Kubernetes Deployment Overview
tags: Deployment
文章目录
Kubernetes Deployment Overview
1. 简介
2. 创建 Deployment
2.1 编排yaml
2.2 定义描述
2.3 运行与查看
2.4 Pod-template-hash label
3. 更新 Deployment
3.1 Rollover(多个 rollout 并行)
Label selector 更新
4. 回滚 Deployment
4.1 检查 Deployment 上线历史
4.2 回滚到之前的修订版本
5. 缩放 Deployment
5.1 比例缩放
6. 暂停、恢复 Deployment
7. Deployment 状态
7.1 进行中的 Deployment(Progressing)
7.2 完成的 Deployment(Complete)
7.3 失败的 Deployment(Failed)
8. 编排 Deployment
8.1 Pod template
8.2 Replicas
8.3 spec.selector
8.4 策略
8.5 进度期限秒数
8.6 最短就绪时间
8.7 Rollback To
8.8 Revision
8.9 修订历史限制
8.10 paused(暂停的)Kubernetes Deployment【1】管理与编排入门
Kubernetes Deployment【2】原理深入
Kubernetes Deployment【3】管理高级技巧
Kubernetes Deployment【4】参数大全
Kubernetes Deployment【5】部署策略
Kubernetes Deployment【6】client-go 开发
Deployment 结构示意图
deployment排查拓扑图
1. 简介
一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。
你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
2. 创建 Deployment
下面是 Deployment 示例。其中创建了一个 ReplicaSet,负责启动三个 nginx Pods:
2.1 编排yaml
apiVersion: 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.14.2 ports: - containerPort: 80
2.2 定义描述
创建名为 nginx-deployment(由 .metadata.name 字段标明)的 Deployment。
该 Deployment 创建三个(由 replicas 字段标明)Pod 副本。
selector 字段定义 Deployment 如何查找要管理的 Pods。 在这里,你选择在 Pod 模板中定义的标签(app: nginx)。 不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。
spec.selector.matchLabels 字段是 {key,value} 键值对映射。 在 matchLabels 映射中的每个 {key,value} 映射等效于 matchExpressions 中的一个元素, 即其 key 字段是 “key”,operator 为 “In”,values 数组仅包含 “value”。 在 matchLabels 和 matchExpressions 中给出的所有条件都必须满足才能匹配。
template 字段包含以下子字段:
Pod 被使用 labels 字段打上 app: nginx 标签。
Pod 模板规约(即 .template.spec 字段)指示 Pods 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub镜像。
创建一个容器并使用 name 字段将其命名为 nginx。
2.3 运行与查看
$ kubectl apply -f nginx-deployment.yaml $ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 0 0 0 1s
说明: 你可以设置 --record 标志将所执行的命令写入资源注解 kubernetes.io/change-cause 中。这对于以后的检查是有用的。例如,要查看针对每个 Deployment 修订版本所执行过的命令。
在检查集群中的 Deployment 时,所显示的字段有:
NAME 列出了集群中 Deployment 的名称。
READY 显示应用程序的可用的 副本 数。显示的模式是“就绪个数/期望个数”。
UP-TO-DATE 显示为了达到期望状态已经更新的副本数。
AVAILABLE 显示应用可供用户使用的副本数。
AGE 显示应用程序运行的时间。
请注意期望副本数是根据 .spec.replicas 字段设置 3。
查看 Deployment 上线状态
$ kubectl rollout status deployment/nginx-deployment Waiting for rollout to finish: 2 out of 3 new replicas have been updated... deployment "nginx-deployment" successfully rolled out
几秒钟后再次运行
#注意 Deployment 已创建全部三个副本,并且所有副本都是最新的(它们包含最新的 Pod 模板) 并且可用 $ kubectl get deployments AME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 18s
查看 Deployment 创建的 ReplicaSet(rs)
$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-75675f5897 3 3 3 18s
ReplicaSet 输出中包含以下字段:
NAME 列出名字空间中 ReplicaSet 的名称;
DESIRED 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
CURRENT 显示当前运行状态中的副本个数;
READY 显示应用中有多少副本可以为用户提供服务;
AGE 显示应用已经运行的时间长度。
注意 ReplicaSet 的名称始终被格式化为[Deployment名称]-[随机字符串]。 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。
Deployment 控制器将 pod-template-hash 标签添加到 Deployment 所创建或收留的 每个 ReplicaSet 。此标签可确保 Deployment 的子 ReplicaSets 不重叠。 标签是通过对 ReplicaSet 的 PodTemplate 进行哈希处理。 所生成的哈希值被添加到 ReplicaSet 选择算符、Pod 模板标签,并存在于在 ReplicaSet 可能拥有的任何现有 Pod 中。
要查看每个 Pod 自动生成的标签,运行
$ kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453 $ k expose deployment nginx-deployment 80 $ k get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 51d nginx-deployment ClusterIP 10.101.106.248 <none> 80/TCP 8s $ curl 10.101.106.248:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
2.4 Pod-template-hash label
注意:这个 label 不是用户指定的!
注意上面示例输出中的 pod label 里的 pod-template-hash label。当 Deployment 创建或者接管 ReplicaSet 时,Deployment controller 会自动为 Pod 添加 pod-template-hash label。这样做的目的是防止 Deployment 的子 ReplicaSet 的 pod 名字重复。通过将 ReplicaSet 的 PodTemplate 进行哈希散列,使用生成的哈希值作为 label 的值,并添加到 ReplicaSet selector 里、 pod template label 和 ReplicaSet 管理中的 Pod 上。
3. 更新 Deployment
说明: 仅当 Deployment Pod 模板(即 .spec.template)发生改变时,例如模板的标签或容器镜像被更新, 才会触发Deployment 上线。 其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。
按照以下步骤更新 Deployment:
先来更新 nginx Pod 以使用 nginx:1.16.1 镜像,而不是 nginx:1.14.2 镜像。
$ kubectl --record deployment.apps/nginx-deployment set image \ deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 deployment.apps/nginx-deployment image updated 或者 $ kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1 --record deployment.apps/nginx-deployment image updated
或者,可以 edit Deployment
并将 .spec.template.spec.containers[0].image
从 nginx:1.14.2
更改至 nginx:1.16.1
。
$ kubectl edit deployment.v1.apps/nginx-deployment deployment.apps/nginx-deployment edited
要查看上线状态,运行:
$ kubectl rollout status deployment/nginx-deployment Waiting for rollout to finish: 2 out of 3 new replicas have been updated... or deployment "nginx-deployment" successfully rolled out $ kubectl get deployments NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 36s $ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 6s nginx-deployment-2035384211 0 0 0 36s $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-khku8 1/1 Running 0 14s nginx-deployment-1564180365-nacti 1/1 Running 0 14s nginx-deployment-1564180365-z9gth 1/1 Running 0 14s $ kubectl describe deployments Name: nginx-deployment Namespace: default CreationTimestamp: Thu, 30 Nov 2017 10:56:25 +0000 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=2 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.16.1 Port: 80/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: nginx-deployment-1564180365 (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 2m deployment-controller Scaled up replica set nginx-deployment-2035384211 to 3 Normal ScalingReplicaSet 24s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 1 Normal ScalingReplicaSet 22s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 2 Normal ScalingReplicaSet 22s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 2 Normal ScalingReplicaSet 19s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 1 Normal ScalingReplicaSet 19s deployment-controller Scaled up replica set nginx-deployment-1564180365 to 3 Normal ScalingReplicaSet 14s deployment-controller Scaled down replica set nginx-deployment-2035384211 to 0
下次要更新这些 Pods 时,只需再次更新 Deployment Pod 模板即可。
Deployment 可确保在更新时仅关闭一定数量的 Pod。默认情况下,它确保至少所需 Pods 75% 处于运行状态(最大不可用比例为 25%)。
Deployment 还确保仅所创建 Pod 数量只可能比期望 Pods 数高一点点。 默认情况下,它可确保启动的 Pod 个数比期望个数最多多出 25%(最大峰值 25%)。
例如,如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除了一些旧的 Pods, 并创建了新的 Pods。它不会杀死老 Pods,直到有足够的数量新的 Pods 已经出现。 在足够数量的旧 Pods 被杀死前并没有创建新 Pods。它确保至少 2 个 Pod 可用,同时 最多总共 4 个 Pod 可用。
可以看到,当第一次创建 Deployment 时,它创建了一个 ReplicaSet(nginx-deployment-2035384211) 并将其直接扩容至 3 个副本。更新 Deployment 时,它创建了一个新的 ReplicaSet (nginx-deployment-1564180365),并将其扩容为 1,然后将旧 ReplicaSet 缩容到 2, 以便至少有 2 个 Pod 可用且最多创建 4 个 Pod。 然后,它使用相同的滚动更新策略继续对新的 ReplicaSet 扩容并对旧的 ReplicaSet 缩容。 最后,你将有 3 个可用的副本在新的 ReplicaSet 中,旧 ReplicaSet 将缩容到 0。
3.1 Rollover(多个 rollout 并行)
每当 Deployment controller 观测到有新的 deployment 被创建时,如果没有已存在的 ReplicaSet 来创建期望个数的 Pod 的话,就会创建出一个新的 ReplicaSet 来做这件事。已存在的 ReplicaSet 控制 label 与 .spec.selector 匹配但是 template 跟 .spec.template 不匹配的 Pod 缩容。最终,新的 ReplicaSet 将会扩容出 .spec.replicas 指定数目的 Pod,旧的 ReplicaSet 会缩容到 0。
如果您更新了一个的已存在并正在进行中的 Deployment,每次更新 Deployment 都会创建一个新的 ReplicaSet 并扩容它,同时回滚之前扩容的 ReplicaSet —— 将它添加到旧的 ReplicaSet 列表中,开始缩容。
例如,假如您创建了一个有 5 个 niginx:1.7.9 replica 的 Deployment,但是当还只有 3 个 nginx:1.7.9 的 replica 创建出来的时候您就开始更新含有 5 个 nginx:1.9.1 replica 的 Deployment。在这种情况下,Deployment 会立即杀掉已创建的 3 个 nginx:1.7.9 的 Pod,并开始创建 nginx:1.9.1 的 Pod。它不会等到所有的 5 个 nginx:1.7.9 的 Pod 都创建完成后才开始改变航道。
Label selector 更新
我们通常不鼓励更新 label selector,我们建议事先规划好您的 selector。
任何情况下,只要您想要执行 label selector 的更新,请一定要谨慎并确认您已经预料到所有可能因此导致的后果。
增添 selector 需要同时在 Deployment 的 spec 中更新新的 label,否则将返回校验错误。此更改是不可覆盖的,这意味着新的 selector 不会选择使用旧 selector 创建的 ReplicaSet 和 Pod,从而导致所有旧版本的 ReplicaSet 都被丢弃,并创建新的 ReplicaSet。
更新 selector,即更改 selector key 的当前值,将导致跟增添 selector 同样的后果。
删除 selector,即删除 Deployment selector 中的已有的 key,不需要对 Pod template label 做任何更改,现有的 ReplicaSet 也不会成为孤儿,但是请注意,删除的 label 仍然存在于现有的 Pod 和 ReplicaSet 中。
4. 回滚 Deployment
有时,你可能想要回滚 Deployment;例如,当 Deployment 不稳定时(例如进入反复崩溃状态)。 默认情况下,Deployment 的所有上线记录都保留在系统中,以便可以随时回滚 (你可以通过修改修订历史记录限制来更改这一约束)。
Deployment 被触发上线时,系统就会创建 Deployment 的新的修订版本。 这意味着仅当 Deployment 的 Pod 模板(.spec.template)发生更改时,才会创建新修订版本 – 例如,模板的标签或容器镜像发生变化。 其他更新,如 Deployment 的扩缩容操作不会创建 Deployment 修订版本。 这是为了方便同时执行手动缩放或自动缩放。 换言之,当你回滚到较早的修订版本时,只有 Deployment 的 Pod 模板部分会被回滚。
假设你在更新 Deployment 时犯了一个拼写错误,将镜像名称命名设置为 nginx:1.161 而不是 nginx:1.16.1:
$ kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.161 --record=true deployment.apps/nginx-deployment image updated
此上线进程会出现停滞。你可以通过检查上线状态来验证:
$ kubectl rollout status deployment/nginx-deployment Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
你可以看到旧的副本有两个(nginx-deployment-1564180365
和 nginx-deployment-2035384211
), 新的副本有 1 个(nginx-deployment-3066724191
):
$ kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-1564180365 3 3 3 25s nginx-deployment-2035384211 0 0 0 36s nginx-deployment-3066724191 1 1 0 6s
查看所创建的 Pod,你会注意到新 ReplicaSet 所创建的 1 个 Pod 卡顿在镜像拉取循环中
$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-1564180365-70iae 1/1 Running 0 25s nginx-deployment-1564180365-jbqqo 1/1 Running 0 25s nginx-deployment-1564180365-hysrc 1/1 Running 0 25s nginx-deployment-3066724191-08mng 0/1 ImagePullBackOff 0 6s $ kubectl describe deployment Name: nginx-deployment Namespace: default CreationTimestamp: Tue, 15 Mar 2016 14:48:04 -0700 Labels: app=nginx Selector: app=nginx Replicas: 3 desired | 1 updated | 4 total | 3 available | 1 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=nginx Containers: nginx: Image: nginx:1.91 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True ReplicaSetUpdated OldReplicaSets: nginx-deployment-1564180365 (3/3 replicas created) NewReplicaSet: nginx-deployment-3066724191 (1/1 replicas created) Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-2035384211 to 3 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 1 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 2 22s 22s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 2 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 1 21s 21s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-1564180365 to 3 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled down replica set nginx-deployment-2035384211 to 0 13s 13s 1 {deployment-controller } Normal ScalingReplicaSet Scaled up replica set nginx-deployment-3066724191 to 1
说明: Deployment 控制器自动停止有问题的上线过程,并停止对新的 ReplicaSet 扩容。 这行为取决于所指定的rollingUpdate
参数(具体为 maxUnavailable
)。 默认情况下,Kubernetes 将此值设置为 25%。
4.1 检查 Deployment 上线历史
首先,检查 Deployment 修订历史:
kubectl rollout history deployment.v1.apps/nginx-deployment deployments "nginx-deployment" REVISION CHANGE-CAUSE 1 kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml --record=true 2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.9.1 --record=true 3 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.91 --record=true
CHANGE-CAUSE 的内容是从 Deployment 的 kubernetes.io/change-cause 注解复制过来的。 复制动作发生在修订版本创建时。你可以通过以下方式设置 CHANGE-CAUSE 消息:
使用 kubectl annotate deployment.v1.apps/nginx-deployment kubernetes.io/change-cause="image updated to 1.9.1" 为 Deployment添加注解。
追加 --record 命令行标志以保存正在更改资源的 kubectl 命令。
手动编辑资源的清单。
要查看修订历史的详细信息,运行:
$ kubectl rollout history deployment.v1.apps/nginx-deployment --revision=2 deployments "nginx-deployment" revision 2 Labels: app=nginx pod-template-hash=1159050644 Annotations: kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1 --record=true Containers: nginx: Image: nginx:1.16.1 Port: 80/TCP QoS Tier: cpu: BestEffort memory: BestEffort Environment Variables: <none> No volumes.
4.2 回滚到之前的修订版本
按照下面给出的步骤将 Deployment 从当前版本回滚到以前的版本(即版本 2)。
假定现在你已决定撤消当前上线并回滚到以前的修订版本:
$ kubectl rollout undo deployment.v1.apps/nginx-deployment deployment.apps/nginx-deployment
或者,你也可以通过使用 --to-revision
来回滚到特定修订版本:
$ kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2 deployment.apps/nginx-deployment
现在,Deployment 正在回滚到以前的稳定版本。正如你所看到的,Deployment 控制器生成了 回滚到修订版本 2 的 DeploymentRollback
事件。
检查回滚是否成功以及 Deployment 是否正在运行,运行:
$ kubectl get deployment nginx-deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE nginx-deployment 3 3 3 3 30m $ kubectl describe deployment nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Sun, 02 Sep 2018 18:17:55 -0500 Labels: app=nginx Annotations: deployment.kubernetes.io/revision=4 kubernetes.io/change-cause=kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.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.16.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-c4747d96c (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 12m deployment-controller Scaled up replica set nginx-deployment-75675f5897 to 3 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 1 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 2 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 2 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 1 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-c4747d96c to 3 Normal ScalingReplicaSet 11m deployment-controller Scaled down replica set nginx-deployment-75675f5897 to 0 Normal ScalingReplicaSet 11m deployment-controller Scaled up replica set nginx-deployment-595696685f to 1 Normal DeploymentRollback 15s deployment-controller Rolled back deployment "nginx-deployment" to revision 2 Normal ScalingReplicaSet 15s deployment-controller Scaled down replica set nginx-deployment-595696685f to 0