参考课程:Kubernetes 全站架构师
Deployment
Kubernetes 提供了一种更加简单的更新 RC 和 Pod 的机制,叫做 Deployment。通过在 Deployment 中描述期望的集群状态,Deployment Controller 会将现在的集群状态在一个可控的速度下逐步更新成期望的集群状态。Deployment 过程如下图所示:
Deployment 的主要职责同样是为了保证 Pod 的数量和健康,而绝大多数的功能与 Replication Controller 完全一样,因此可以被看作新一代的 Replication Controller。但是,它又具备了 Replication Controller 不具备的新特性:
事件和状态查看:可以查看升级的详细进度和状态;
回滚:当升级 Pod 镜像或者相关参数的时候发现问题,可以使用回滚操作回滚到上一个稳定的版本或者指定的版本;
版本记录:每一次对 Deployment 的操作都能够保存下来,给与后续可能的回滚使用;
暂停和启动:对于每一次升级,都能够随时暂停和启动;
多种升级方案:
- Recreate: 删除所有已存在的 Pod,重新创建新的;
- RollingUpdate: 滚动升级,即逐步替换的策略。滚动升级时支持更多的附件参数,例如设置最大不可用 Pod 数量,最小升级间隔时间等。
相比于 RC,Deployment 直接使用 kubectl edit deployment/deploymentName
或者 kubectl set
方法就可以直接升级(原理是 Pod 的 Template 发生变化,例如,更新 Label,更新镜像版本等操作会触发 Deployment 的滚动升级)。
创建 Deployment
首先,我们定义一个 nginx-deploy-v1.yaml 文件,副本数为 3,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80示例解析
- 第4行,metadata.name: Deployment 的名称
- 第8行,spec.replicas: 创建 Pod 的副本数
- 第9行,spec.selector: 定义 Deployment 如何找到要管理的 Pod,与 template 下的 labels 对应
- template 字段包含以下字段:
- metadata.labels.app: 使用 label 标记 Pod
- spec.containers.name: 表示 Pod 运行一个名字为 nginx 的容器
- spec.containers.image: 运行此 Pod 使用的镜像
- Ports: 容器用于发送和接收流量的端口。
使用
kubectl create
创建 Deployment1
2# kubectl create -f nginx-deploy-v1.yaml
deployment.apps/nginx-deployment created使用 kubectl get 或者 kubectl describe 查看此 Deployment
1
2
3kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 56s此时,我们查看 Deployment rollout 的状态
1
2# kubectl rollout status deployment nginx-deployment
deployment "nginx-deployment" successfully rolled out查看此 Deployment 创建的 ReplicaSet
1
2
3# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5d59d67564 3 3 3 15m查看此 Deployment 创建的 Pod
1 | # kubectl get pods --show-labels |
更新 Deployment
一般应用程序升级或者迭代时,会通过 Deployment 对 Pod 进行滚动更新。
假如更新 Nginx Pod 的 image 使用 nginx:1.9.1
1
2# kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record
deployment.apps/nginx-deployment image updated也可以使用 edit 直接编辑 Deployment,效果相同
1
kubectl edit deployment nginx-deployment
使用 kubectl rollout status 查看更新状态
1
2
3
4
5
6# kubectl rollout status deployment nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out查看 ReplicaSet 状态
1
2
3
4# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5d59d67564 0 0 0 32m
nginx-deployment-69c44dfb78 3 3 3 5m3s通过 describe 查看 deployment 的详细信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43# kubectl describe deployments nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sat, 03 Apr 2021 21:14:15 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 4
kubernetes.io/change-cause: kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
Selector: app=nginx
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: app=nginx
Containers:
nginx:
Image: nginx:1.9.1
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: nginx-deployment-69c44dfb78 (3/3 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 33m deployment-controller Scaled up replica set nginx-deployment-5d59d67564 to 3
Normal ScalingReplicaSet 6m deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 1
Normal ScalingReplicaSet 5m16s deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 2
Normal ScalingReplicaSet 4m31s deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 3
Normal ScalingReplicaSet 2m25s deployment-controller Scaled up replica set nginx-deployment-5d59d67564 to 1
Normal ScalingReplicaSet 2m24s deployment-controller Scaled up replica set nginx-deployment-5d59d67564 to 2
Normal ScalingReplicaSet 2m24s deployment-controller Scaled down replica set nginx-deployment-69c44dfb78 to 2
Normal ScalingReplicaSet 2m11s (x2 over 5m16s) deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 2
Normal ScalingReplicaSet 2m10s (x2 over 4m31s) deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 1
Normal ScalingReplicaSet 2m10s (x6 over 2m23s) deployment-controller (combined from similar events): Scaled up replica set nginx-deployment-69c44dfb78 to 3
Normal ScalingReplicaSet 102s (x2 over 4m3s) deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 0
从 describe 中可以看出,第一次创建时,它创建了一个名为 nginx-deployment-5d59d67564 的 ReplicaSet,并直接将其扩展为 3 个副本。更新部署时,它创建了一个新的 ReplicaSet,命名为 nginx-deployment-69c44dfb78,并将其副本数扩展为 1,然后将旧的的 ReplicaSet 缩小为 2,这样至少可以有 2 个 Pod 可用,最多创建了 4 个 Pod。以此类推,使用相同的滚动更新策略向上和向下扩展新旧 ReplicaSet,最终新的 ReplicaSet 可以拥有 3 个副本,并将旧的 ReplicaSet 缩小为 0.
回滚 Deployment
当心版本不稳定时,可以对其进行回滚操作,默认情况下,所有 Deployment 的 rollout
历史记录都保留在系统中,可以随时回滚。
假设我们又进行了几次更新
1
2
3
4
5# kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record
deployment.apps/nginx-deployment image updated
# kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record
deployment.apps/nginx-deployment image updated使用
kubectl rollout history
查看部署历史1
2
3
4
5
6
7# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
3 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
4 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
5 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record=true
6 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record=true查看 deployment 某次更新的详细信息,使用
--revision
指定版本号1
2
3
4
5
6
7
8
9
10
11
12
13
14# kubectl rollout history deployment nginx-deployment --revision=5
deployment.apps/nginx-deployment with revision #5
Pod Template:
Labels: app=nginx
pod-template-hash=666f99dd56
Annotations: kubernetes.io/change-cause: kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record=true
Containers:
nginx:
Image: dotbalo/canary:v1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>使用
kubectl rollout undo
回滚到上一个版本1
2# kubectl rollout undo deployment nginx-deployment
deployment.apps/nginx-deployment rolled back再次查看历史记录,发现 REVISION 7 回到了 canary:v1
1
2
3
4
5
6
7# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
3 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
4 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
6 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record=true
7 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record=true使用
--to-revision
参数回滚到指定版本1
2# kubectl rollout undo deployment nginx-deployment --to-revision=3
deployment.apps/nginx-deployment rolled back
扩容/缩容 Deployment
当公司访问量变大,三个 Pod 已经无法支撑业务时,可以对其进行扩展。
使用
kubectl scale
动态调整 Pod 的副本数,比如增加 Pod 为 5 个1
2# kubectl scale deployment nginx-deployment --replicas=5
deployment.apps/nginx-deployment scaled查看 Pod,此时 Pod 已经变成了 5 个
1
2
3
4
5
6
7# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-5d59d67564-99l2x 1/1 Running 0 3m20s app=nginx,pod-template-hash=5d59d67564
nginx-deployment-5d59d67564-fl5q7 1/1 Running 0 71s app=nginx,pod-template-hash=5d59d67564
nginx-deployment-5d59d67564-js2xn 1/1 Running 0 3m24s app=nginx,pod-template-hash=5d59d67564
nginx-deployment-5d59d67564-sbfxw 1/1 Running 0 71s app=nginx,pod-template-hash=5d59d67564
nginx-deployment-5d59d67564-vsl95 1/1 Running 0 3m22s app=nginx,pod-template-hash=5d59d67564
暂停和恢复 Deployment 更新
Deployment 支持暂停更新,用于对 Deployment 进行多次修改操作。
使用
kubectl rollout pause
暂停 Deployment 更新1
2# kubectl rollout pause deployment nginx-deployment
deployment.apps/nginx-deployment paused对 Deployment 进行相关更新操作,比如更新镜像,然后对其资源进行限制
1
2
3
4
5# kubectl set image deploy nginx-deployment nginx=nginx:1.14.2
deployment.apps/nginx-deployment image updated
# kubectl set resources deploy nginx-deployment -c=nginx --limits=cpu=200m,memory=254Mi
deployment.apps/nginx-deployment resource requirements updated通过
rollout history
可以看到没有新的更新1
2
3
4
5
6
7# kubectl rollout history deployment nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
4 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
6 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v2 --record=true
7 kubectl set image deployment nginx-deployment nginx=dotbalo/canary:v1 --record=true
8 kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true使用
kubectl rollout resume
恢复 Deployment 的更新1
2# kubectl rollout resume deployment nginx-deployment
deployment.apps/nginx-deployment resumed可以看到恢复更新的 Deployment 创建了一个新的 RS(复制集)
1
2
3
4
5
6
7# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5b99ddccc6 5 5 5 54s
nginx-deployment-5d59d67564 0 0 0 59m
nginx-deployment-666f99dd56 0 0 0 19m
nginx-deployment-69c44dfb78 0 0 0 31m
nginx-deployment-79d4d8c7d5 0 0 0 18m可以看到 Deployment 的 image 镜像已经变成了 nginx:1.14.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47# kubectl describe deployments.apps nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Sat, 03 Apr 2021 21:14:15 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 9
kubernetes.io/change-cause: kubectl set image deploy nginx-deployment nginx=nginx:1.9.1 --record=true
Selector: app=nginx
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.14.2
Port: 80/TCP
Host Port: 0/TCP
Limits:
cpu: 200m
memory: 254Mi
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-deployment-5b99ddccc6 (5/5 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 32m deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 1
Normal ScalingReplicaSet 32m deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 2
Normal ScalingReplicaSet 31m deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 3
Normal ScalingReplicaSet 29m deployment-controller Scaled up replica set nginx-deployment-5d59d67564 to 1
Normal ScalingReplicaSet 29m deployment-controller Scaled up replica set nginx-deployment-5d59d67564 to 2
Normal ScalingReplicaSet 29m (x2 over 32m) deployment-controller Scaled up replica set nginx-deployment-69c44dfb78 to 2
Normal ScalingReplicaSet 29m (x2 over 31m) deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 1
Normal ScalingReplicaSet 28m (x2 over 30m) deployment-controller Scaled down replica set nginx-deployment-5d59d67564 to 0
Normal ScalingReplicaSet 18m (x2 over 29m) deployment-controller Scaled down replica set nginx-deployment-69c44dfb78 to 2
Normal ScalingReplicaSet 18m deployment-controller Scaled down replica set nginx-deployment-69c44dfb78 to 1
Normal ScalingReplicaSet 18m deployment-controller Scaled down replica set nginx-deployment-69c44dfb78 to 0
Normal ScalingReplicaSet 2m13s (x25 over 29m) deployment-controller (combined from similar events): Scaled down replica set nginx-deployment-5d59d67564 to 4
更新 Deployment 的注意事项
清理策略
在默认情况下,revision
保留 10 个旧的 ReplicaSet,其余的将在后台进行垃圾回收,可以在 .spec.revisionHistoryLimit
设置保留 ReplicaSet 的个数。当设置为 0 时,不保留历史记录。
更新策略
- .spec.strategy.type == Recreat,表示重建,先删掉旧的 Pod,再创建新的 Pod;
- .spec.strategy.type == RollingUpdate,表示滚动更新,可以指定 maxUnavailable 和 maxSurge 来控制更新过程;
- .spec.strategy.rollingUpdate.maxUnavailable,指定在回滚更新时最大不可用的 Pod 数量,可选字段,默认为 25%,可以设置数字或百分比,如果 maxSurge 为 0,则该值不能位 0.
- .spec.strategy.rollingUpdate.maxSurge,可以超过期望值的最大 Pod 数,可选字段,默认为 25%,可以设置为数字或者百分比,如果 maxUnavailable 为 0,则该值不能为 0