书籍来源:cloudman《每天5分钟玩转Kubernetes》
一边学习一边整理老师的课程内容及试验笔记,并与大家分享,侵权即删,谢谢支持!
Kubernetes Cluster由Master和Node组成,节点上运行着若干Kubernetes服务。
Master是Kubernetes Cluster的大脑,运行着的Daemon服务包括kube-apiserver、kube-scheduler、kube-controller-manager、etcd和Pod网络(例如flannel)
API Server提供HTTP/HTTPS RESTful API,即Kubernetes API。API Server是Kubernetes Cluster的前端接口,各种客户端工具(CLI或 UI)以及Kubernetes其他组件可以通过它管理Cluster的各种资源。
Scheduler负责决定将Pod放在哪个Node上运行。Scheduler在调度时会充分考虑Cluster的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。
Controller Manager负责管理Cluster各种资源,保证资源处于预期的状态。Controller Manager由多种controller组成,包括replication controller、endpoints controller、namespace controller、serviceaccounts controller等。
不同的controller管理不同的资源。例如,replication controller管理Deployment、StatefulSet、DaemonSet的生命周期,namespace controller管理Namespace资源。
etcd负责保存Kubernetes Cluster的配置信息和各种资源的状态信息。当数据发生变化时,etcd会快速地通知Kubernetes相关组件。
Pod要能够相互通信,Kubernetes Cluster必须部署Pod网络,flannel是其中一个可选方案。
以上是Master上运行的组件,下面我们接着讨论Node。
Node是Pod运行的地方,Kubernetes支持Docker、rkt等容器Runtime。Node上运行的Kubernetes组件有kubelet、kube-proxy和Pod网络(例如flannel),
kubelet是Node的agent,当Scheduler确定在某个Node上运行Pod后,会将Pod的具体配置信息(image、volume等)发送给该节点的kubelet,kubelet根据这些信息创建和运行容器,并向Master报告运行状态。
service在逻辑上代表了后端的多个Pod,外界通过service访问Pod。service接收到的请求是如何转发到Pod的呢?这就是kube-proxy要完成的工作。
每个Node都会运行kube-proxy服务,它负责将访问service的TCP/UPD数据流转发到后端的容器。如果有多个副本,kube-proxy会实现负载均衡。
Pod要能够相互通信,Kubernetes Cluster必须部署Pod网络,flannel是其中一个可选方案。
结合实验环境,我们得到了如下的架构图。
你可能会问:为什么k8s-master上也有kubelet和kube-proxy呢?
这是因为Master上也可以运行应用,即Master同时也是一个Node。
几乎所有的Kubernetes组件本身也运行在Pod里,执行如下命令,结果如图所示。
kubectl get pod --all-namespaces -o wide
Kubernetes的系统组件都被放到kube-system namespace中。这里有一个kube-dns组件(上图中为coredns),它为Cluster提供DNS服务,我们后面会讨论到。kube-dns是在执行kubeadm init时(第5步)作为附加组件安装 的。
kubelet是唯一没有以容器形式运行的Kubernetes组件,它在CentOS中通过Systemd服务运行,如图所示。
为了帮助大家更好地理解Kubernetes架构,我们部署一个应用来演示各个组件之间是如何协作的。
执行下列命令,结果如图所示。
[root@k8s-master ~]# vi deployment-nginx.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: dev
spec:
replicas: 3
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx:1.17.1
name: nginx
ports:
- containerPort: 80
protocol: TCP
kubectl apply -f deployment-nginx.yaml
等待一段时间,应用部署完成,如图所示。
Kubernetes部署了deployment,有3个副本Pod,分别运 行在k8s-node1和k8s-node2。
详细讨论整个部署过程,如图所示。
① kubectl发送部署请求到API Server。
② API Server通知Controller Manager创建一个deployment资源。
③ Scheduler执行调度任务,将3个副本Pod分发到k8s-node1和 k8s-node2。
④ k8s-node1和k8s-node2上的kubectl在各自的节点上创建并运行 Pod。
补充两点:
(1)应用的配置和当前状态信息保存在etcd中,执行kubectl get pod时API Server会从etcd中读取这些数据。
(2)flannel会为每个Pod都分配IP。因为没有创建service,所以目前kube-proxy还没参与进来。
本章我们学习了Kubernetes的架构,讨论了Master和Node是哪个运行的组件和服务,并通过一个部署案例加深了对架构的理解。