K8S脉络整理(005)-Kubernetes架构
Kubernetes Cluster 由 Master 和 Node 组成,节点上运行着若干 Kubernetes 服务。
Master 节点
Master 是 Kubernetes Cluster 的大脑,运行着如下 Daemon 服务:
- kube-apiserver
- API Server(kube-apiserver)API Server 提供 HTTP/HTTPS RESTful API,即 Kubernetes API。
API Server 是 Kubernetes Cluster 的前端接口,各种客户端工具(CLI 或 UI)以及 Kubernetes 其他组件可以通过它管理 Cluster 的各种资源。
- API Server(kube-apiserver)API Server 提供 HTTP/HTTPS RESTful API,即 Kubernetes API。
- kube-scheduler
- Scheduler(kube-scheduler)Scheduler 负责决定将 Pod 放在哪个 Node 上运行。
Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。
- Scheduler(kube-scheduler)Scheduler 负责决定将 Pod 放在哪个 Node 上运行。
- kube-controller-manager
-
Controller Manager(kube-controller-manager)Controller Manager 负责管理 Cluster 各种资源,保证资源处于预期的状态。
Controller Manager 由多种 controller 组成,包括 replication controller、endpoints controller、namespace controller、serviceaccounts controller 等。
不同的 controller 管理不同的资源。
例如 :
replication controller 管理 Deployment、StatefulSet、DaemonSet 的生命周期;
namespace controller 管理 Namespace 资源。
-
- etcd
-
etcd 负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。
当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。
-
- Pod 网络(例如 flannel、calico)
- Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。
Node 节点
Node 是 Pod 运行的地方,Kubernetes 支持 Docker、rkt 等容器 Runtime。
Node上运行的 Kubernetes 组件有 kubelet、kube-proxy 和 Pod 网络(例如 flannel)。
kubelet
kubelet 是 Node 的 agent.
当 Scheduler 确定在某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image、volume 等)发送给该节点的 kubelet,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。
kube-proxy
service 在逻辑上代表了后端的多个 Pod,外界通过 service 访问 Pod。
service 接收到的请求是如何转发到 Pod 的呢?这就是 kube-proxy 要完成的工作。
每个 Node 都会运行 kube-proxy 服务,它负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。
如果有多个副本,kube-proxy 会实现负载均衡。
Pod 网络
Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。
完整的架构图
结合实验环境,我们得到了如下的架构图:
你可能会问:为什么 k8s-master 上也有 kubelet 和 kube-proxy 呢?
这是因为 Master 上也可以运行应用,即 Master 同时也是一个 Node。
几乎所有的 Kubernetes 组件本身也运行在 Pod 里,执行如下命令:
kubectl get pod --all-namespaces -o wide ##查看所有pod并查看ip及所在node
root@master:~/kubespray# kubectl get pod --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
default kubernetes-bootcamp-5d7f968ccb-c57nw 1/1 Running 0 3h 10.233.75.7 node2
default kubernetes-bootcamp-5d7f968ccb-lv24f 1/1 Running 0 3h 10.233.71.7 node3
kube-system calico-node-4gm72 1/1 Running 52 33d 172.28.2.212 node2
kube-system calico-node-8fkfk 1/1 Running 0 33d 172.28.2.210 master
kube-system calico-node-fqdwj 1/1 Running 53 33d 172.28.2.213 node3
kube-system calico-node-lpdtx 1/1 Running 47 33d 172.28.2.211 node1
kube-system calico-node-nq8l2 1/1 Running 42 33d 172.28.2.214 node4
kube-system kube-apiserver-master 1/1 Running 0 33d 172.28.2.210 master
kube-system kube-apiserver-node4 1/1 Running 224 18d 172.28.2.214 node4
kube-system kube-controller-manager-master 1/1 Running 0 33d 172.28.2.210 master
kube-system kube-controller-manager-node4 1/1 Running 5 18d 172.28.2.214 node4
kube-system kube-dns-79d99cdcd5-6vvrw 3/3 Running 0 18d 10.233.102.131 node1
kube-system kube-dns-79d99cdcd5-rkpf2 3/3 Running 0 18d 10.233.71.5 node3
kube-system kube-proxy-master 1/1 Running 0 33d 172.28.2.210 master
kube-system kube-proxy-node1 1/1 Running 0 32d 172.28.2.211 node1
kube-system kube-proxy-node2 1/1 Running 0 18d 172.28.2.212 node2
kube-system kube-proxy-node3 1/1 Running 0 32d 172.28.2.213 node3
kube-system kube-proxy-node4 1/1 Running 0 18d 172.28.2.214 node4
kube-system kube-scheduler-master 1/1 Running 0 33d 172.28.2.210 master
kube-system kube-scheduler-node4 1/1 Running 3 18d 172.28.2.214 node4
kube-system kubedns-autoscaler-5564b5585f-7z62x 1/1 Running 0 18d 10.233.71.4 node3
kube-system kubernetes-dashboard-6bbb86ffc4-zmmc2 1/1 Running 0 18d 10.233.75.5 node2
kube-system nginx-proxy-node1 1/1 Running 0 32d 172.28.2.211 node1
kube-system nginx-proxy-node2 1/1 Running 0 18d 172.28.2.212 node2
kube-system nginx-proxy-node3 1/1 Running 0 32d 172.28.2.213 node3
Kubernetes 的系统组件都被放到 kube-system
namespace 中。
这里有一个 kube-dns
组件,它为 Cluster 提供 DNS 服务,我们后面会讨论。
kube-dns
是在执行 kubeadm init
时(第 ⑤ 步)作为附加组件安装的。
kubelet 是唯一没有以容器形式运行的 Kubernetes 组件,它在 Ubuntu 中通过 Systemd 运行。
service kubelet status ● kubelet.service - Kubernetes Kubelet Server Loaded: loaded (/etc/systemd/system/kubelet.service; enabled; vendor preset: enabled) Active: active (running) since 四 2018-02-01 19:02:58 CST; 1 months 3 days ago Docs: https://github.com/GoogleCloudPlatform/kubernetes Main PID: 9652 (kubelet) Tasks: 18 Memory: 58.9M CPU: 22h 18min 30.647s CGroup: /system.slice/kubelet.service └─9652 /usr/local/bin/kubelet --logtostderr=true --v=2 --address=172.28.2.210 --node-ip=172.28.2.210 --hostname-override=master --allow-privileged=true --p
部署演示
为了帮助大家更好地理解 Kubernetes 架构,我们部署一个应用来演示各个组件之间是如何协作的。
执行命令
kubectl run httpd-app --image=httpd --replicas=2
root@master:~/kubespray# kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE httpd-app 2 2 2 2 34m kubernetes-bootcamp 2 2 2 2 5h root@master:~/kubespray# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE httpd-app-5fbccd7c6c-c8qq7 1/1 Running 0 35m 10.233.71.8 node3 httpd-app-5fbccd7c6c-jstpm 1/1 Running 0 35m 10.233.75.8 node2 kubernetes-bootcamp-5d7f968ccb-c57nw 1/1 Running 0 4h 10.233.75.7 node2 kubernetes-bootcamp-5d7f968ccb-lv24f 1/1 Running 0 4h 10.233.71.7 node3
等待一段时间,应用部署完成。
Kubernetes 部署了 deployment httpd-app
,有两个副本 Pod,分别运行在 k8s-node1
和 k8s-node2
。
详细讨论整个部署过程。
① kubectl 发送部署请求到 API Server。
② API Server 通知 Controller Manager 创建一个 deployment 资源。
③ Scheduler 执行调度任务,将两个副本 Pod 分发到 k8s-node1 和 k8s-node2。
④ k8s-node1 和 k8s-node2 上的 kubelet 在各自的节点上创建并运行 Pod。
补充两点:
-
应用的配置和当前状态信息保存在 etcd 中,执行
kubectl get pod
时 API Server 会从 etcd 中读取这些数据。 -
flannel 会为每个 Pod 都分配 IP。因为没有创建 service,目前 kube-proxy 还没参与进来。