Rolling Update
滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新。滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性。
run: httpd 和name: httpd 都可以
下面我们部署三副本应用,初始镜像为 httpd:2.2.31,然后将其更新到 httpd:2.2.32。
[root@master rolling]# vim httpd.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
selector:
matchLabels:
run: httpd
replicas: 3
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:2.2.31
run: httpd 和name: httpd 都可以
通过 kubectl apply
部署。
[root@master rolling]# kubectl apply -f httpd.yml
deployment.apps/httpd created
[root@master rolling]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 3 3 2m40s httpd httpd:2.2.31 run=httpd
[root@master rolling]# kubectl get replicaset -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
httpd-55f56846f 3 3 3 3m21s httpd httpd:2.2.31 pod-template-hash=55f56846f,run=httpd
[root@master rolling]# kubectl get pod
NAME READY STATUS RESTARTS AGE
httpd-55f56846f-7bthw 1/1 Running 0 3m28s
httpd-55f56846f-7wzjs 1/1 Running 0 3m28s
httpd-55f56846f-pjf5q 1/1 Running 0 3m28s
[root@master rolling]#
部署过程如下:
1、创建 Deployment httpd
2、创建 ReplicaSet httpd-551879778
3、创建三个 Pod
4、当前镜像为 httpd:2.2.31
将配置文件中 httpd:2.2.31 替换为 httpd:2.2.32,再次执行 kubectl apply
[root@master rolling]# kubectl apply -f httpd.yml
deployment.apps/httpd configured
[root@master rolling]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 1 3 10m httpd httpd:2.2.32 run=httpd
[root@master rolling]# kubectl get replicaset -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
httpd-55f56846f 2 2 2 10m httpd httpd:2.2.31 pod-template-hash=55f56846f,run=httpd
httpd-846d8d79dd 2 2 1 54s httpd httpd:2.2.32 pod-template-hash=846d8d79dd,run=httpd
[root@master rolling]# kubectl get pod
NAME READY STATUS RESTARTS AGE
httpd-55f56846f-7bthw 1/1 Running 0 10m
httpd-55f56846f-7wzjs 1/1 Running 0 10m
httpd-846d8d79dd-7dlwp 1/1 Running 0 63s
httpd-846d8d79dd-9pcq4 0/1 ContainerCreating 0 23s
[root@master rolling]# kubectl get pod
NAME READY STATUS RESTARTS AGE
httpd-846d8d79dd-7dlwp 1/1 Running 0 4m40s
httpd-846d8d79dd-9pcq4 1/1 Running 0 4m
httpd-846d8d79dd-m4mpj 1/1 Running 0 3m19s
我们发现了如下变化:
1、Deployment httpd 的镜像更新为 httpd:2.2.32
2、新创建了 ReplicaSet httpd-846d8d79dd,镜像为 httpd:2.2.32,并且管理了三个新的 Pod。
3、之前的 ReplicaSet httpd-55f56846f 里面已经没有任何 Pod。
结论是:ReplicaSet httpd-55f56846f8 的三个 httpd:2.2.31 Pod 已经被 ReplicaSet httpd-846d8d79dd 的三个 httpd:2.2.32 Pod 替换了。
具体过程可以通过 kubectl describe deployment httpd
查看。
[root@master rolling]# kubectl describe deployment httpd
Name: httpd
Namespace: default
CreationTimestamp: Tue, 22 Dec 2020 14:04:37 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 2
Selector: run=httpd
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=httpd
Containers:
httpd:
Image: httpd:2.2.32
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: httpd-846d8d79dd (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set httpd-55f56846f to 3
Normal ScalingReplicaSet 6m6s deployment-controller Scaled up replica set httpd-846d8d79dd to 1
Normal ScalingReplicaSet 5m26s deployment-controller Scaled down replica set httpd-55f56846f to 2
Normal ScalingReplicaSet 5m26s deployment-controller Scaled up replica set httpd-846d8d79dd to 2
Normal ScalingReplicaSet 4m45s deployment-controller Scaled down replica set httpd-55f56846f to 1
Normal ScalingReplicaSet 4m45s deployment-controller Scaled up replica set httpd-846d8d79dd to 3
Normal ScalingReplicaSet 4m44s deployment-controller Scaled down replica set httpd-55f56846f to 0
每次只更新替换一个 Pod:
1、ReplicaSet httpd-846d8d79dd 增加一个 Pod,总数为 1。
2、ReplicaSet httpd-55f56846f 减少一个 Pod,总数为 2。
3、ReplicaSet httpd-846d8d79dd 增加一个 Pod,总数为 2。
4、ReplicaSet httpd-55f56846f 减少一个 Pod,总数为 1。
5、ReplicaSet httpd-846d8d79dd 增加一个 Pod,总数为 3。
6、ReplicaSet httpd-55f56846f 减少一个 Pod,总数为 0
每次替换的 Pod 数量是可以定制的。Kubernetes 提供了两个参数 maxSurge
和 maxUnavailable
来精细控制 Pod 的替换数量,结合 Health Check 特性。
回滚
kubectl apply 每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个 revision(版次),这样就可以回滚到某个特定 revision。
默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit 属性增加 revision 数量。
下面实践回滚功能。应用有如下三个配置文件 httpd.v1.yml,httpd.v2.yml 和 httpd.v3.yml,分别对应不同的 httpd 镜像 2.4.16,2.4.17 和 2.4.18:
通过 kubectl apply
部署并更新应用:
[root@master roll_text]# kubectl apply -f httpd.v1.yml --record
deployment.apps/httpd created
[root@master roll_text]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 0/3 1 0 38s httpd httpd:2.4.16 run=httpd
[root@master roll_text]# kubectl apply -f httpd.v2.yml --record
deployment.apps/httpd configured
[root@master roll_text]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 0/3 1 0 38s httpd httpd:2.4.17 run=httpd
[root@master roll_text]# kubectl apply -f httpd.v3.yml --record
deployment.apps/httpd configured
[root@master roll_text]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 0/3 1 0 38s httpd httpd:2.4.18 run=httpd
--record
的作用是将当前命令记录到 revision 记录中,这样我们就可以知道每个 revison 对应的是哪个配置文件。
通过 kubectl rollout history deployment httpd
查看 revison 历史记录。
[root@master roll_text]# kubectl rollout history deployment httpd
deployment.apps/httpd
REVISION CHANGE-CAUSE
1 kubectl apply --filename=httpd.v1.yml --record=true
2 kubectl apply --filename=httpd.v2.yml --record=true
3 kubectl apply --filename=httpd.v3.yml --record=true
CHANGE-CAUSE
就是 --record
的结果。如果要回滚到某个版本,比如 revision 1,
可以执行命令 kubectl rollout undo deployment httpd --to-revision=1
:
[root@master roll_text]# kubectl rollout undo deployment httpd --to-revision=1
deployment.apps/httpd rolled back
[root@master roll_text]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 2/3 2 2 7m22s httpd httpd:2.4.16 run=httpd
此时,revison 历史记录也会发生相应变化。
[root@master roll_text]# kubectl rollout history deployment httpd
deployment.apps/httpd
REVISION CHANGE-CAUSE
2 kubectl apply --filename=httpd.v2.yml --record=true
3 kubectl apply --filename=httpd.v3.yml --record=true
4 kubectl apply --filename=httpd.v1.yml --record=true
revison 1 变成了 revison 4。不过我们可以通过 CHANGE-CAUSE
知道每个 revison 的具体含义。所以一定要在执行 kubectl apply
时加上 --record
参数。