编排其实很简单:“谈谈控制器模型”
定义一个Deployment的例子
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
这个Deployment的编排定义的很简单,保证了携带app=nginx标签的Pod的副本数永远等于2,这就意味着这个集群中,携带了app=nginx的标签大于2的时候就会又旧的Pod被删除,反之,就会有Pod被创建;
Kubernetes中都遵循了一种通用的编排模式 ,叫做控制循环(control loop),Go语言代码来描述这个控制循环;
for {
实际状态 := 获取集群中对象X的实际状态(Actual State)
期望状态 := 获取集群中对象X的期望状态(Desired State)
if 实际状态 == 期望状态{
什么都不做
} else {
执行编排动作,将实际状态调整为期望状态
}
}
实际状态一般来源于Kubernets集群本身,比如Kubelet通过心跳汇报容器的状态和节点状态,这些都是实际状态;
期望状态一般来源于用户提交的YAML文件,比如Deployment对象中的Replicas字段的值,都保存在ETCD当中;
Deployment的控制器模型实现
Deployment控制器从ETCD中获取携带了"app=nginx"标签的Pod,进行统计,这就是实际状态
Deployment对象的Replicas字段的值就是期望状态;
Deployment的控制器就要对这两个状态进行比较,决定是否创建或删除Pod;
Deployment这样的控制器,实际上就是由上半部分的控制器定义(包括期望状态)和下半部分的被控制对象的模板组成。