Kubernetes解析-主节点如何控制集群
kubernetes俗称k8s,相信很多人都听说过,管理容器的或者管理集群的。这样的概念过于宽泛,今天先说明一个点:主节点如何控制集群。k8s是如何做到在主节点上执行的命令可以在集群其他节点同步执行,使用者看来彷佛在同一台主机上运行的呢?
nodes
在了解集群之前,首先要了解节点(node)。所谓node可以理解为组成集群的一台设备,不仅仅局限于物理机。我们在集群中所运行的服务,本质都是运行在node上的一组容器。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane,master 24s v1.20.2
至于为什么k8s可以在主节点上控制其他设备上运行的容器,这就要说起kubelet了
kubelet
kubelet是node的重要组成之一,负责该node上容器控制。所有的运行中容器信息都以文件的形式存储在manifests目录下,这个目录可以通过kubelet --config
设定具体位置,kubelet会监控这个目录下所有文件,当文件消失就会停止对应容器。这样所创建的容器称为静态容器
$ ll
total 28
drwxr-xr-x 2 root root 4096 Mar 25 14:58 ./
drwxr-xr-x 4 root root 4096 Mar 25 14:43 ../
-rw------- 1 root root 2259 Mar 25 14:43 etcd.yaml
-rw------- 1 root root 4014 Mar 25 14:43 kube-apiserver.yaml
-rw------- 1 root root 3339 Mar 25 14:43 kube-controller-manager.yaml
-rw------- 1 root root 1385 Mar 25 14:43 kube-scheduler.yaml
-rw-r--r-- 1 root root 478 Mar 25 14:43 nginx.yaml
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-minikube 2/2 Running 0 45s
$ pwd
/etc/kubernetes/manifests
不过kubelet内核中还运行着一个http服务器,默认监听port 10255,通过接受请求完成容器启停。在kubelet启动时,会向控制平面上的api sever注册kubelet --api-servers=ip:8080
,从而实现了主节点对node上容器的控制。此外kubelet提供了查询接口,供api server查询node上信息
$ curl --stderr /dev/null http://localhost:10255/pods | jq . | head
{
"kind": "PodList",
"apiVersion": "v1",
"metadata": {},
"items": [
{
"metadata": {
"name": "nginx-kx",
"namespace": "default",
"selfLink": "/api/v1/pods/namespaces/nginx-kx/default",
不过kubelet仅控制由k8s所创建的容器,其他容器不在kubelet控制范围内。比如我们在node上通过docker run image是不会在主节点上查询到的。
api server
创建容器通常会使用yaml文件来确定容器配置,从使用者的角度来说,只是执行kubectl apply -f xx.ymal
,如果启动成功,就会查询到对应容器信息。从内部来说,这个yaml会先转为json,通过请求的方式发送给api server,再由api server和node上kubelet通信,最终完成容器启动。
$ curl \
--stderr /dev/null \
--request POST http://localhost:8080/api/v1/namespaces/default/pods \
--data @nginx.json | jq 'del(.spec.containers, .spec.volumes)'
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/nginx",
"uid": "28aa5a55-5194-11e5-b364-68f7288bdc45",
"resourceVersion": "1365",
"creationTimestamp": "2015-09-02T17:00:48Z"
},
"spec": {
"restartPolicy": "Always",
"dnsPolicy": "ClusterFirst",
"nodeName": "awesome-node"
},
"status": {
"phase": "Pending"
}
etcd
etcd是个分布式k-v数据库,在k8s中为各组件提供状态存储。像api server,kubelet等组件都是无状态的,它们所有的状态信息都以键值对的形式存储在etcd中,并且各个组件之间的通信也是通过etcd,其中只有api server负责向etcd中写入新状态,其他组件负责监听。
实际上,k8s的集群管理本质上仍然是服务注册的玩法,api server是注册中心,只不过现在注册的不是服务,而是一个逻辑主机。原来提供一个可用的服务,现在提供一个container running environment,并且外加一个主节点agent--kubelet来控制容器的生命周期。
参考资料:
[2]: Kubernetes from the ground up: the API server
[3]: Kubernetes Documentation/Concepts/Cluster Architecture/Nodes
[4]: 创建静态 Pod