Deployment与控制器模型
Deployment可以帮我们做什么
- 定义一组Pod期望数量,Controller会维持Pod数量与期望数量一致
- 配置Pod的发布方式,controller会按照给定的策略更新Pod,保证更新过程中不可用Pod维持在限定数量范围内
- 如果发布有问题支持回滚
实例
apiVersion: v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
控制器模型
在Kubernetes架构中,有一个叫做kube-controller-manager的组件。这个组件,是一系列控制器的集合。
其中每一个控制器,都以独有的方式负责某种编排功能。而Deployment正是这些控制器中的一种。它们都遵循Kubernetes中一个通用的编排模式,即:控制循环
用一段go语言伪代码,描述这个控制循环
for {
实际状态 := 获取集群中对象X的实际状态
期望状态 := 获取集群中对象X的期望状态
if 实际状态 == 期望状态 {
什么都不做
}else{
执行编排动作,将实际状态调整为期望状态
}
}
在具体实现中,实际状态往往来自于Kubernetes集群本身。比如Kubelet通过心跳汇报的容器状态和节点状态,或者监控系统中保存的应用监控数据,或者控制器主动收集的它感兴趣的信息,这些都是常见的实际状态的来源;期望状态一般来自用户提交的YAML文件,这些信息都保存在Etcd中
对于Deployment,它的控制器简单实现如下:
- Deployment Controller从Etcd中获取到所有携带 “app:nginx”标签的Pod,然后统计它们的数量,这就是实际状态
- Deployment对象的replicas的值就是期望状态
- Deployment Controller将两个状态做比较,然后根据比较结果,确定是创建Pod,还是删除已有Pod
Deployment的滚动更新
Deployment滚动更新的实现,依赖的是Kubernetes中的ReplicaSet
Deployment控制器实际操纵的,就是Replicas对象,而不是Pod对象。对于Deployment、ReplicaSet、Pod它们的关系如下图:
image.pngReplicaSet负责通过“控制器模式”,保证系统中Pod的个数永远等于指定的个数。这也正是Deployment只允许容器的restartPolicy=Always的主要原因:只有容器能保证自己始终是running状态的前提下,ReplicaSet调整Pod的个数才有意义。
Deployment同样通过控制器模式,操作ReplicaSet的个数和属性,进而实现“水平扩展/收缩”和“滚动更新”两个编排动作
对于“水平扩展/收缩”的实现,Deployment Controller只需要修改replicas的值即可。
用户执行这个操作的指令如下:
kubectl scale deployment nginx-deployment --replicas=4
滚动更新的过程
首先,创建上述Pod
[root@host1 deployment]# kubectl create -f nginx-deployment.yaml --record #record参数可以记录每次操作所执行的命令,方便日后查看
deployment.apps/nginx-deployment created
[root@host1 deployment]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 21s
[root@host1 deployment]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-76bf4969df 3 3 3 62s
[root@host1 deployment]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-76bf4969df-jq4tj 1/1 Running 0 70s
nginx-deployment-76bf4969df-jsln9 1/1 Running 0 70s
nginx-deployment-76bf4969df-nbl8j 1/1 Running 0 70s
test-projected-volume 1/1 Running 0 19h
[root@host1 deployment]# kubectl rollout status deployment/nginx-deployment #通过该指令可以实时查看对象的状态变化
deployment "nginx-deployment" successfully rolled out
[root@host1 deployment]# kubectl edit deployment/nginx-deployment #修改etcd中的API对象
deployment.extensions/nginx-deployment edited
[root@host1 deployment]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
[root@host1 deployment]# kubectl describe deployment/nginx-deployment
....
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 22m deployment-controller Scaled up replica set nginx-deployment-76bf4969df to 3
Normal ScalingReplicaSet 17m deployment-controller Scaled up replica set nginx-deployment-779fcd779f to 1
Normal ScalingReplicaSet 16m deployment-controller Scaled down replica set nginx-deployment-76bf4969df to 2
Normal ScalingReplicaSet 16m deployment-controller Scaled up replica set nginx-deployment-779fcd779f to 2
Normal ScalingReplicaSet 15m deployment-controller Scaled down replica set nginx-deployment-76bf4969df to 1
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set nginx-deployment-779fcd779f to 3
Normal ScalingReplicaSet 15m deployment-controller Scaled down replica set nginx-deployment-76bf4969df to 0
首先,当你修改了Deployment中的Pod定义之后,Deployment Controller会使用这个修改后的Pod模板,创建一个新的ReplicaSet,这个ReplicaSet的初始Pod副本数是:0
然后在17m的时候,Deployment Controller开始将这个新的ReplicaSet所控制的Pod副本数从0变为1,即水平扩展出与i个副本
接着,在16m的时候,Deployment Controller将旧的ReplicaSet所控制的旧Pod副本数减少一个
....
如此交替,就弯沉了一组Pod版本更新过程。
[root@host1 deployment]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-76bf4969df 0 0 0 26m
nginx-deployment-779fcd779f 3 3 3 21m
Deployment还会确保,在任何时间窗口内,只有指定比例的Pod处于离线状态,同时确保,在任何时间窗口内,只有指定比例的新Pod被创建出来,这两个值都可以配置,默认是25%
这个策略,是Deployment对象的一个字段,叫做RollingUpdateStrategy,如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
...
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
maxSurge指定的是除了DESIRED数量之外,在一次滚动中,Deployment控制器还可以创建多少个新Pod;
maxUnavailable指的是,在一次滚动中,Deployment控制器可以删除多少个旧Pod
回滚
首先我们使用kubeclt rollout history命令,查看每次Deployment变更对应的版本
然后使用kubeclt rollout undo deployment/[deployment-name] --to-revision=[版本号]
参考:阿里云大学云原生技术公开课 极客时间深入剖析Kubernetes
网友评论