Kubernetes从零开始
本文最后更新于:2021年5月27日 晚上
本篇blog记录本人学习Kubernetes的全过程,参考资料为官方教程 和 *YouTube教程*。
Kubernetes是什么
本节我们介绍Kubernetes中的若干基本概念,包括control plane, node和could controller manager。
Kubernetes是用来管理container的,container和虚拟机(VM)功能类似,但是更加轻量。
Similar to a VM, a container has its own filesystem, share of CPU, memory, process space, and more. As they are decoupled from the underlying infrastructure, they are portable across clouds and OS distributions.
各个部署方式的示意图如下:
可以看到,VM有自己的OS,一个虚拟的完整系统,而container是在OS的上层部署的。
一些基本概念:
- Node:一个节点,每个node可以是一台真实的计算机,也可以是一个虚拟机(Virtual machine)。
- Cluster:若干node的集合,一个cluster可以只有一个node。
- Pods:Cluster中运行的若干container的集合。
- Control plane:Control plane用于管理node和Pods。
Control plane是什么
Control plane用来做一些全局的决策,并对系统中发生的事件进行响应。理论上control plane可以部署在任何一台机器上,但习惯上所有control plane都会集中部署在一台机器上。
Control plane由以下几个部分组成:
- kube-apiserver:API server是Kubernetes的前端,它提供API与cluster交互,是control plane的主要部件。
- etcd:Kubernetes的后端,提供key-value store来存储cluster数据。
- kube-scheduler:给Pod分配node。
- kube-controller-manager:用于运行各种controller(后面会讲什么是controller),比如用于通知node挂掉了的controller。
- cloud-controller-manager:用于管理跟cloud相关的部分。
Controller是什么
上面提到我们可以用kube-controller-manager管理controller,这里介绍一下controller是什么。
在自动化领域,control loop是一个不终止的负反馈调节过程,它控制着系统state的变化。举个例子,某间房屋需要维持特定的温度(desired state),可以让一个controller通过不断开关温度调节设备让房屋的当前温度(current state),从而不断靠近目标温度(desired state)。
Kubernetes中的controller同样会将cluster中的一些state维持在desired state附近。Controller可以通过API server控制,也可以直接控制。
Node是什么
一个node既可以是一台真正的计算机,也可以是virtual machine。每个node中包含以下组件:
- kubelet:确保所有container在Pod中成功运行。
- kube-proxy:node上的网络代理。
- Container runtime: 管理运行中的container,支持Docker, containerd, CRI-O等
Node的注册
我们有两种添加node的方法:
- 使用kubelet向API server进行self-registration
- 手动添加
Node被创建后,kube-apiserver会检查metadata.name
是否匹配。name是该node的标识符,它必须是个DNS Subdomain,且必须唯一。之后,系统会不断检查该node是否成功运行了相关服务。当所有的相关服务都成功运行,该node才会被允许在Pod上运行。
Self-registration:kubelet中--register-node
的默认值为true(推荐用默认值),这代表kubelet会尝试向向control plane进行self-register。
Self-registration的相关选项有--kubeconfig、
--cloud-provider
、--register-node
、--register-with-taints
、--node-ip
和--node-labels
。
手动添加:我们可以使用 kubectl这个命令行工具手动创建node,此时--register-node
的值为false.
Node的status
使用以下命令查看node的status,包括node的Address、Condition(Ready/DiskPressure…)、Capacity and Allocatable(可用资源情况——CPU、内存、Pod数量)和Info(一些通用信息)
1 |
|
Node controller
Node controller属于control plane中controller的一种,它有三个作用:
- 如果启用了CIDR分配,负责分配CIDR block。
- 如果用了cloud,保证Node controller里记录的node在cloud上都是可用的。如果不可用,则将其从记录里删除。
- 监控node的健康。
Heartbeats
Node需要不断发送hearbeat报告自己是否存活。有两种heartbeat——NodeStatus以及Lease对象,它们都由kubelet管理。其中,NodeStatus默认每5分钟更新一次,Lease默认每10秒更新一次。
Reliability,Node capacity,Node topology、Graceful node shutdown
略
Cloud Controller Manager是什么
Kubernetes致力于将管理cloud相关的功能与管理cluster本身的功能解耦。其中,与cloud相关的控制逻辑在control plance中的cloud-controller-manager(c-c-m)里实现。c-c-m以插件的形式存在,并与cloud提供者的API交互。
c-c-m包括以下controller:
- Node controller:在cloud中创建node,记录could相关信息,获取node的hostname和network address,获取node的健康状态。
- Route controller:配置路由,使node间可以通信。
- Service controller:Service在若干Pods上运行,它将Pods对外暴露为network service。Cloud上会提供load balancing、network packet filtering之类的功能。我们使用service controller和could上这些功能的API交互。
基础操作入门
创建一个cluster
Cluster中包含两种资源,control plane和node。其中,
- Control plane用来管理cluster中的所有活动,我们使用Control plane中的API server与node进行交互。
- 每个Node是一台虚拟机或真实计算机。每个node中都有一个Kubelet,用来管理node,以及和control plane交互。Node中也需要支持container相关操作的工具,如containerd和Docker。
示意图如下:
现在我们用Minikube来入门Kubernetes。Minikube比真正的Kubernetes简单,它会在本地创建只包含一个node的cluster。
使用以下命令启动minikube
1 |
|
我们使用kubectl来和Kubernetes交互,使用以下命令查看cluster信息
1 |
|
使用以下命令查看node信息
1 |
|
部署一个App
为了部署containerized application,我们需要配置Deployment controller。它告诉系统如何创建和更新app的实例,并且不断监视app所在的node的状态。当node不可用时,Deployment controller会在›可用的node中再次创建App的instance。
我们仍然使用Kubectl创建Deployment。kubectl是一个命令行工具,它的基本
语法是:
1 |
|
其中,action是要执行的操作,如reate和describe;而resource指定了要操作的资源,如node和container。我们可以在每条kubectl命令后添加--help
(如kubectl get nodes --help
),来学习这条命令的参数。
使用以下命令创建Deployment:
1 |
|
上图中,我们将新建的Deployment命名为kubernetes-bootcamap,并且指定了一个已有的app image。在执行这条命令时,Kubernetes做了以下几件事:
- 找到可用的node
- 在node中部署app
- 进行了一些设置,使得当该node不再可用时,可以寻找新的可用node
使用以下命令查看已有的Deployment:
1 |
|
Pod默认情况下只能对同一个cluster内的其他pods可见。
kubectl可以创建一个proxy,用来在cluster中通讯。为此,我们需要新开一个terminal,并键入以下命令:
1 |
|
另外,我们可以使用ctrl + c
结束当前proxy的运行。
当这个proxy在运行时,我们可以在当前host(当前的terminal)使用它暴露出的API,来和kubernetes通信。例如,下面展示了如何使用curl
命令查看其版本:
1 |
|
API server会自动为每个pod创建一个endpoint,这个endpoint可以被proxy访问到。如果不想使用代理(Proxy),我们可以使用Service来提供服务。
写到这里,笔者感觉官方教程不太符合初学者学习路线,但对了解基本概念挺有帮助,下面我们跳转到另一个教程,教程链接是:
https://www.youtube.com/watch?v=X48VuDVv0do
Overview
Container很轻量,为小型的服务(Microservice)提供了方便, 当今的一个服务背后,可能需要数百上千个container共同支持。Kubernetes就是用来支持和管理这些container运行的。Kubernetes提供了high availability(不宕机)、scalability(扩展性)和disaster recovery(备份和恢复数据)。
现在我们来简要了解Kubernetes的组成部分:
Kubernetes(k8s)的组成部件众多,一一介绍对新手不友好。下面我们通过一个运行js服务的例子来了解其中一些主要部件。
Pod
Pod是k8s中所操作的最小单位,是对container的一个封装。通常情况下,每个pod中只有一个app(理论上可以有多个)。每个pod有自己的IP,各个Pod间。但很不方便的是,当这个pod崩溃被重新创建时,该ip会发生变化。Pod崩溃的原因有很多,我们可以认为pod会经常“死亡->重建”。
Service
为了解决IP变化的问题,我们需要使用Service。Service拥有固定不变的ip,并且可以和pod绑定。
Pod和Service的生命周期不一样,所以即使pod奔溃了,与它绑定的Service还是可用的,这样,我们就能获得一个不变的IP了。
我们并不想将所有的service暴露给外部的资源。在这个例子中,我们想要把包含js服务的service(my-app)暴露给用户,但不想把底层包含数据库(DB)的后端service暴露给外部资源。为此,我们在创建Service的时候就需要指定它是internal的还是external的。
Ingress
上图中external service的urlhttp://my-app-service-ip:port
用起来不方便。例如,它可能是http://124.89.101.2:8080
。在对外提供服务时,我们需要提供https://my-app.com
这样的url。为此,我们需要用到Ingress。在这种情况下,Ingress被用来接收外部请求,然后再将其转发给Service。
ConfigMap and Secret
如前文所说,pod之间通过service进行通信。在这个例子中,my-app
通过和mongo-db-service
这个服务通信,实现与数据库的交互。
但是,数据库url的配置一般要用一个属性文件或者一些外部的环境变量。这些相关文件通常会内嵌在这个app的image文件当中。
本网站仅作为个人观点的交流平台,博客中讨论内容及引用书籍都有标注。如疑版权问题,请在评论区留言~
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处~