为了服务升级过程中提供可持续的不中断的服务,K8S提供了Rolling Update机制,它可以使得服务近乎无缝地平滑升级,即在不停止对外服务的前提下完成应用的更新。滚动更新采用渐进的方式逐步替换旧版本Pod,如果更新不如预期,那么也可以通过回滚操作恢复到更新前的状态。
下面我们部署三副本应用,初始镜像为httpd:2.2.31,然后将其更新到httpd:2.2.32。
vi httpd.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
replicas: 3
selector:
matchLabels:
run: httpd
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:2.2.31
ports:
- containerPort: 80
通过kubectl apply部署
[root@k8s-master ~]# vi httpd.yaml
[root@k8s-master ~]# kubectl apply -f httpd.yaml
deployment.apps/httpd configured
[root@k8s-master ~]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 2 3 3d httpd httpd:2.2.31 run=httpd
将配置⽂件中的httpd:2.2.31替换为httpd:2.2.32,再次执行kubectl apply
[root@k8s-master ~]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 3 3 3d httpd httpd:2.2.32 run=httpd
[root@k8s-master ~]# kubectl get replicaset -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
httpd-6847bf7784 0 0 0 3m19s httpd httpd:2.2.31 pod-template-hash=6847bf7784,run=httpd
httpd-6c864b4669 3 3 3 59s httpd httpd:2.2.32 pod-template-hash=6c864b4669,run=httpd
Deployment httpd的镜像更新为httpd:2.2.32。
[root@k8s-master ~]# kubectl describe deployment httpd
Name: httpd
Namespace: default
CreationTimestamp: Sat, 27 Jan 2024 18:00:17 +0800
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 3
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-6c864b4669 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 3m41s deployment-controller Scaled up replica set httpd-6847bf7784 to 1
Normal ScalingReplicaSet 3m13s deployment-controller Scaled down replica set httpd-ff8d77b9b to 2
Normal ScalingReplicaSet 3m13s deployment-controller Scaled up replica set httpd-6847bf7784 to 2
Normal ScalingReplicaSet 2m42s deployment-controller Scaled down replica set httpd-ff8d77b9b to 1
Normal ScalingReplicaSet 2m42s deployment-controller Scaled up replica set httpd-6847bf7784 to 3
Normal ScalingReplicaSet 2m25s deployment-controller Scaled down replica set httpd-ff8d77b9b to 0
Normal ScalingReplicaSet 81s deployment-controller Scaled up replica set httpd-6c864b4669 to 1
Normal ScalingReplicaSet 48s deployment-controller Scaled down replica set httpd-6847bf7784 to 2
Normal ScalingReplicaSet 48s deployment-controller Scaled up replica set httpd-6c864b4669 to 2
Normal ScalingReplicaSet 27s (x3 over 30s) deployment-controller (combined from similar events): Scaled down replica set httpd-6847bf7784 to 0
kubectlapply每次更新应用时,Kubernetes都会记录下当前的配置,保存为⼀个revision(版次),这样就可以回滚到某个特定revision。
下⾯实践回滚功能。应用有三个配置⽂件,即httpd.v1.yml、 httpd.v2.yml和httpd.v3.yml,分别对应不同的httpd镜像2.4.16、2.4.17和2.4.18。
vi httpd.v1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
selector:
matchLabels:
run: httpd
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:2.4.16
ports:
- containerPort: 80
vi httpd.v2.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
selector:
matchLabels:
run: httpd
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:2.4.17
ports:
- containerPort: 80
vi httpd.v3.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpd
spec:
revisionHistoryLimit: 10
replicas: 3
selector:
matchLabels:
run: httpd
template:
metadata:
labels:
run: httpd
spec:
containers:
- name: httpd
image: httpd:2.4.18
ports:
- containerPort: 80
通过kubectl apply部署并更新应用。
[root@k8s-master ~]# kubectl apply -f httpd.v1.yml --record
deployment.apps/httpd configured
[root@k8s-master ~]# kubectl apply -f httpd.v2.yml --record
deployment.apps/httpd configured
[root@k8s-master ~]# kubectl apply -f httpd.v3.yml --record
deployment.apps/httpd configured
[root@k8s-master ~]# kubectl get deployment httpd -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
httpd 3/3 2 3 3d1h httpd httpd:2.4.18 run=httpd
–record的作用是将当前命令记录到revision记录中,这样我们就可以知道每个revison对应的是哪个配置文件了。
[root@k8s-master ~]# kubectl rollout history deployment httpd
deployment.apps/httpd
REVISION CHANGE-CAUSE
7 kubectl apply --filename=httpd.v1.yml --record=true
8 kubectl apply --filename=httpd.v2.yml --record=true
9 kubectl apply --filename=httpd.v3.yml --record=true
如果要回滚到某个版本,比如revision 7,可以执行命令kubectl rollout undo deployment httpd --to-revision=7
[root@k8s-master ~]# kubectl rollout undo deployment httpd --to-revision=7
deployment.apps/httpd rolled back
[root@k8s-master ~]# kubectl rollout history deployment httpd
deployment.apps/httpd
REVISION CHANGE-CAUSE
8 kubectl apply --filename=httpd.v2.yml --record=true
9 kubectl apply --filename=httpd.v3.yml --record=true
10 kubectl apply --filename=httpd.v1.yml --record=true
httpd.v1.yml 的revison 7变成了revison 10。不过我们可以通过CHANGE-CAUSE知
道每个revison的具体含义,所以⼀定要在执行kubectl apply时加–record参数。