一文读懂Deployment以及实践攻略
Deployment是用于管理一组 Pod从而运行应用程序的工作负载,通常是无状态的工作负载。Deployment 就像是一位“项目经理”,负责规划和监督整个应用的运行。它定义了应用如何部署、多少副本运行、更新的方式等重要策略。通过使用 Deployment,用户可以轻松管理应用的滚动更新、扩展副本数量、回滚到之前的版本,确保应用在任何时候都能正常工作。
一文读懂Deployment以及实践攻略
❤️ 摘要:本文详细介绍了Kubernetes中Deployment的概念及其实践攻略。Deployment是一种用于管理一组Pod的工作负载,主要负责应用的部署、更新及回滚等操作。文章首先解释了Deployment的基本概念,包括其如何管理Pod、与ReplicaSet的关系以及生命周期状态。接着,通过一系列实践案例,展示了如何创建、更新、回滚及扩展Deployment。此外,还介绍了如何暂停和恢复Deployment的rollout流程。通过这些详细的步骤和示例,读者可以更好地理解和掌握Deployment的使用方法。
目录
- 1 概念
- 2 Deployment的实践
- 3 参考文献
1 概念
1.1 什么是Deployment
Deployment是用于管理一组 Pod从而运行应用程序的工作负载,通常是无状态的工作负载。
Deployment 就像是一位“项目经理”,负责规划和监督整个应用的运行。它定义了应用如何部署、多少副本运行、更新的方式等重要策略。通过使用 Deployment,用户可以轻松管理应用的滚动更新、扩展副本数量、回滚到之前的版本,确保应用在任何时候都能正常工作。
1.2 Deployment 如何管理 Pod?
上一篇导航: 《一文读懂Pod以及实践攻略》
前文所述,Pod 是 Kubernetes 中最小的计算单元,承载着应用的容器。Deployment 就像是一个“指挥官”,它可以告诉 Kubernetes 需要启动多少个 Pod;在运行时持续监控这些Pod,在更新时实现不影响用户体验完成更新或者Pod扩容和缩容。
举个例子,如果一个网站需要始终保持 3 个 Pod 在运行,Deployment 就会确保无论发生什么情况(比如某个 Pod 崩溃或更新),都会有 3 个副本保持在线,像是“纪律严明的运维团队”,确保始终有人在岗位上。
Deployment 还可以控制应用的滚动更新。当我们需要更新应用时,Deployment 会“有条不紊”地逐一更新 Pod,而不是一下子重启所有,避免服务中断,就像在流水线上逐步替换零件一样高效安全。
❔ 说明: Deployment 处于 master 节点上,通过发布 Deployment,master 节点会选择合适的 worker 节点创建 Container(即图中的正方体),Container 会被包含在 Pod (即蓝色圆圈)里。
1.3 Deployment 与 ReplicaSet 的关系
在pod的管理中, Deployment是明面的管理者,但是ReplicaSet才是管理 Pod 副本的真正“执行者”,负责根据指令启动或终止特定数量的 Pod。可以把 ReplicaSet 想象成是 Deployment 手下的“组长”,而Pod就是实际干活的人。当 Deployment 下达指令时,ReplicaSet 会具体执行这些命令,比如生成指定数量的 Pod 副本。
Deployment 实际上管理着多个 ReplicaSet。每次 Deployment 更新时,都会生成一个新的 ReplicaSet,并逐步将流量从旧的 ReplicaSet 切换到新的ReplicaSet,这样确保在更新过程中不会出现应用中断的情况。而旧的 ReplicaSet 也可以在回滚时被重新启用。
⚠️ 不要尝试绕过Deployment,直接操作现有的Replica, 这样可能导致Deployment无法有效管理Pod。
1.4 Deployment的生命周期状态
Deployment在其生命周期中会进入不同状态, 状态清单如下:
状态 | 可能情况 |
---|---|
progressing | 1) Deployment 创建一个新的 ReplicaSet。 2) Deployment 正在扩展其最新的 ReplicaSet。 3) Deployment 正在缩减其旧的 ReplicaSet。 4) 新 Pod 准备就绪或可用(至少准备MinReadySeconds )。 |
complete | 1)与部署关联的所有副本均已更新至您指定的最新版本,这意味着您请求的所有更新均已完成。 2)与部署关联的所有副本均可用。 3)部署的旧副本没有正在运行。 |
fail to progress | 1)配额不足 2) 就绪探针故障 3) 镜像拉取错误 4) 权限不足 5) 限制范围 6)应用程序运行时配置错误 |
2 Deployment的实践
假设我们需要在 Kubernetes 集群中部署一个简单的 Web 应用(如 nginx
),要求它有 3 个副本,实践在应用部署、更新、回滚和扩展的过程。
2.1 创建Deployment
编辑nginx-deployment.yaml,定义一个 ReplicaSet 来启动三个nginx
Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
# 定义Deployment的名字
name: nginx-deployment
labels:
app: nginx
spec:
# 定义副本数
replicas: 3
# 选择器指定label与pod模板的label匹配
selector:
matchLabels:
app: nginx
template:
metadata:
# 与选择器指定label匹配
labels:
app: nginx
spec:
containers:
# pod名字,可自定义
- name: nginx
# 镜像源, 这里设置私有镜像源
image: harbor.zx/hcie/nginx:1.26.1
# pod暴露端口号
ports:
- containerPort: 80
name: http
protocol: TCP
运行以下命令部署
kubectl apply -f nginx-deployment.yaml
检查 Deployment 是否已创建
[root@k8s-master1 hcie]# kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 104m
❔ 说明: 当您检查集群中的部署时,会显示以下字段:
字段 | 说明 |
---|---|
NAME | 列出命名空间中部署的名称。 |
READY | 显示有多少个应用程序副本可供用户使用。它遵循准备/期望的模式。 |
UP-TO-DATE | 显示已更新以达到所需状态的副本数量。 |
AVAILABLE | 显示有多少个应用程序副本可供您的用户使用。 |
AGE | 显示应用程序已运行的时间量。 |
2.1.1 Deployment的pod如何命名?
ReplicaSet 的名称始终采用[DEPLOYMENT-NAME]-[HASH]
格式,该名称将成为创建的 Pod 的前缀。HASH
字符串与 ReplicaSet 上的pod-template-hash
标签相同。
可以执行以下命令查看到pod-template-hash
标签。
1)查看Replicaset的label
[root@k8s-master1 hcie]# kubectl get rs --show-labels
NAME DESIRED CURRENT READY AGE LABELS
nginx-deployment- 64db67d8bc 3 3 3 114m app=nginx, pod-template-hash=64db67d8bc
2) 查看pod的label
[root@k8s-master1 hcie]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment- 64db67d8bc -h6vsv 1/1 Running 0 113m app=nginx, pod-template-hash=64db67d8bc
nginx-deployment-64db67d8bc-lf57x 1/1 Running 0 113m app=nginx,pod-template-hash=64db67d8bc
nginx-deployment-64db67d8bc-ljh85 1/1 Running 0 113m app=nginx,pod-template-hash=64db67d8bc
- 可以看到replicaset的label会被关联的pod继承;
- 同时也是replicaset通过label关联pod
[root@k8s-master1 hcie]# kubectl get rs -oyaml
...
selector:
matchLabels:
app: nginx
pod-template-hash: 64db67d8bc
⚠️ 注意:不要让多个控制器(如 Deployment、StatefulSet)使用相同的标签(labels)和选择器(selectors)来管理 Pod。Kubernetes 不会自动阻止这种重叠,但如果多个控制器同时选择并尝试管理同一组 Pod,可能会导致意外行为或冲突。
⚠️ 警告:不要尝试修改selector和pod-template现有的标签,否则导致ReplicaSet无法管理关联的pod。
2.2 更新Deployment
❔ 说明: 当且仅当 Deployment 的 Pod 模板(即
.spec.template
)发生更改(例如,模板的标签或容器映像更新)时,才会触发 Deployment 的滚动更新。
执行以下命令,更新 nginx Pod 的映像使用nginx:1.27.1
代替 nginx:1.26.1
kubectl set image deployment/nginx-deployment nginx=harbor.zx/hcie/nginx:1.27.1
- 其中,
deployment/nginx-deployment
表示部署,nginx
表示将进行更新的容器,nginx:1.27.1
表示新映像及其标签。 - 或者执行
edit
命令并修改.spec.template.spec.containers[0].image
从nginx:1.26.1
到nginx:1.27.1
kubectl edit deployment/nginx-deployment
执行以下命令,查看部署状态:
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: 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
部署成功后,您可以通过kubectl get deployments
查看 Deployment信息
[root@k8s-master1 hcie]# kubectl get deployments nginx-deployment -owide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3/3 3 3 141m nginx harbor.zx/hcie/nginx:1.27.1 app=nginx
执行kubectl get rs
可以看到 Deployment 通过创建新的 ReplicaSet 并将其扩展到 3 个副本,以及将旧的 ReplicaSet 缩减到 0 个副本来更新 Pod。
[root@k8s-master1 hcie]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-546946b498 3 3 3 3m10s
nginx-deployment-5dd79cf485 0 0 0 10m
❔ 说明: 输出字段说明
字段 | 说明 | 定义 |
---|---|---|
NAME | ReplicaSet的名称 | 上面已说明,字段组成是[DEPLOYMENT-NAME]-[HASH] |
DESIRED | 期望的 Pod 数量 | 该字段显示的是 ReplicaSet 中希望维持的 Pod 副本数量。这个值是根据 ReplicaSet 的 spec.replicas 来设置的,代表应用正常运行时需要的 Pod 数量。 |
CURRENT | 当前的 Pod 数量 | 该字段显示的是当前由 ReplicaSet 管理的 Pod 的实际数量。这个值可能小于或等于 DESIRED,具体取决于是否正在进行扩容、缩容或滚动更新。 |
READY | 准备好的 Pod 数量。 | 该字段显示的是处于 Ready 状态并且可以接受流量的 Pod 数量。Pod 只有在所有的健康检查(如 readiness probe)通过之后才会被认为是 “Ready”。 |
AGE | ReplicaSet 存在的时间。 | 该字段表示该 ReplicaSet 自创建以来的持续时间,单位通常为秒s 、分钟m 、小时h 或天d 。 |
❓ 思考: Deployment的更新过程怎么执行的? 如何从旧的pod过渡到新的pod?
- 通常,滚动更新(Rolling Update)是 Deployment 的默认更新策略,它允许在更新过程中逐步替换旧的 Pod,而不是直接销毁所有旧 Pod,从而保证应用始终有足够的可用实例来处理请求。
- 例如:当 Deployment 控制器观察到新的 Deployment 时,会创建一个 ReplicaSet 来启动所需的 Pod。如果更新了Deployment,那么控制标签与
.spec.selector
匹配但模板内容与.spec.template
不匹配的 ReplicaSet会将所属的Pod缩放为 0,而新的 ReplicaSet 所属的pod被扩展为.spec.replicas
的数量。 - 更新的关键参数有两个:
maxUnavailable
和maxSurge
,它们控制了在更新过程中 Pod 的替换策略。参数说明如下:
字段 | 说明 | 可能值 | 作用 |
---|---|---|---|
maxUnavailable | maxUnavailable 指定在更新过程中,最多有多少个 不可用的 Pod。换句话说,它控制了在更新过程中允许离线的 Pod 数量。 | 1)该值可以是绝对数字,也可以是百分比。 2) 例如,maxUnavailable: 1 表示在更新过程中,最多可以有 1 个 Pod 处于不可用状态(即正在被删除或替换)。 3)如果设置为百分比,如 maxUnavailable: 25% ,则表示最多有 25% 的 Pod 可以在更新过程中不可用。 | maxUnavailable 决定了集群在更新期间的可用性。如果这个值设置得太高,可能会在更新时造成较大的服务中断;设置得较低,更新速度则会减慢。 |
maxSurge | maxSurge 指定在更新过程中,允许临时多创建的 额外 Pod 数量。这些额外 Pod 会在旧 Pod 被删除之前创建,确保有足够的新 Pod 在更新时提前准备好。 | 1)该值也可以是绝对数字或者百分比。 2)例如,maxSurge: 2 表示更新过程中最多可以有 2 个额外的新 Pod 被创建。 3)如果设置为百分比,如 maxSurge: 50% ,则表示更新过程中最多可以比所需的 Pod 副本数多创建 50% 的 Pod。 | maxSurge 控制了更新的速度和容量。通过增加额外的 Pod 副本,maxSurge 可以加快更新进程,确保新的 Pod 在旧的 Pod 被终止之前已经就绪,从而减少服务的影响。 |
RollingUpdateStrategy默认策略
执行以下命令,查看Deployment的详细信息:
kubectl describe deployments nginx-deployment
输出如下:
Name: nginx-deployment
Namespace: default
CreationTimestamp: Thu, 05 Sep 2024 19:53:56 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 3
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
❔ 说明:
- 默认情况下,它确保至少有 75% 的所需 Pod 数量处于运行状态(最多 25% 不可用)。
- 默认情况下,它确保最多 125% 的所需 Pod 数量处于启动状态(最大激增 25%)。
- 如果你仔细观察上面的 Deployment更新过程,你会发现它首先创建了一个新的 Pod,然后删除了一个旧的 Pod,再创建了另一个新的 Pod。在出现足够数量的新 Pod 之前,它不会杀死旧 Pod;并且在杀死足够数量的旧 Pod 之前,它不会创建新 Pod。它确保至少有 3 个 Pod 可用,并且总共最多有 4 个 Pod 可用。
Terminating Pods 不被计入 availableReplicas
❓ 思考: 观察Deployment的更新过程时,会发现有时候pod的数量会大于所设置的replicas + maxSurge值。
当一个 Pod 被标记为 “终止”(Terminating)时,它可能还没有完全停止运行,比如还在处理请求或在等待资源释放。这些处于 “终止” 状态的 Pod 不会被计入 availableReplicas
,即 Kubernetes 不会把这些正在终止的 Pod 视为可用的副本。
所以Pod 数量多于replicas + maxSurge的原因:
- 旧 Pod 的延迟终止:当新 Pod 启动并开始处理流量时,旧的 Pod 可能还处于 “终止” 状态。这些终止中的 Pod 仍然在运行,虽然不计入
availableReplicas
,但仍占用资源。 - 新旧 Pod 共存:由于
maxSurge
的作用,Kubernetes 允许额外创建的新 Pod 在旧 Pod 被完全终止之前就已经开始工作。这可能会有比replicas + maxSurge
更多 的 Pod 同时存在。
2.2.3 验证RollingUpdateStrategy策略
修改nginx-deployment.yaml的RollingUpdateStrategy策略
apiVersion: apps/v1
kind: Deployment
metadata:
# 定义Deployment的名字
name: nginx-deployment
labels:
app: nginx
spec:
# 定义副本数
replicas: 5
# 新增策略描述
strategy:
type: RollingUpdate
rollingUpdate:
# 最大不可用 Pod 数量
maxUnavailable: 1
# 最大新增 Pod 数量
maxSurge: 1
# 选择器指定label与pod模板的label匹配
selector:
matchLabels:
app: nginx
template:
metadata:
# 与选择器指定label匹配
labels:
app: nginx
spec:
containers:
# pod名字,可自定义
- name: nginx
# 镜像源, 这里设置私有镜像源
image: harbor.zx/hcie/nginx:1.26.1
# pod暴露端口号
ports:
- containerPort: 80
name: http
protocol: TCP
查看deployment的状态
[root@k8s-master1 ~]# kubectl get deploy nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 5/5 5 5 96s
- 可以看到5个pod都运行了。
执行以下命令,更新 nginx Pod 的映像使用nginx:1.27.1
代替 nginx:1.26.1
kubectl set image deployment/nginx-deployment nginx=harbor.zx/hcie/nginx:1.27.1
执行以下命令观察rs更新的情况。
# 查看ReplicaSet执行情况
kubectl get rs -l app=nginx -w
直到pod数量达到5个, 暂停日志输出,并将日志保存到文件。
查看ReplicaSet执行日志,可以看到nginx-deployment-64db67d8bc
是旧的RS,nginx-deployment-546946b498
是新的RS。
# 这是新的RS
[root@k8s-master1 ~]# grep -e "nginx-deployment-546946b498" -e "NAME" rs-display.txt
NAME DESIRED CURRENT READY AGE
nginx-deployment-546946b498 0 0 0 78m
nginx-deployment-546946b498 0 0 0 78m
nginx-deployment-546946b498 1 0 0 78m
nginx-deployment-546946b498 1 0 0 78m
nginx-deployment-546946b498 1 1 0 78m
nginx-deployment-546946b498 2 1 0 78m
nginx-deployment-546946b498 2 1 0 78m
nginx-deployment-546946b498 2 2 0 78m
nginx-deployment-546946b498 2 2 1 78m
nginx-deployment-546946b498 2 2 2 78m
nginx-deployment-546946b498 3 2 2 78m
nginx-deployment-546946b498 3 2 2 78m
nginx-deployment-546946b498 3 3 2 78m
nginx-deployment-546946b498 4 3 2 78m
nginx-deployment-546946b498 4 3 2 78m
nginx-deployment-546946b498 4 4 2 78m
nginx-deployment-546946b498 4 4 3 78m
nginx-deployment-546946b498 5 4 3 78m
nginx-deployment-546946b498 5 4 3 78m
nginx-deployment-546946b498 5 5 3 78m
nginx-deployment-546946b498 5 5 4 78m
nginx-deployment-546946b498 5 5 5 78m
# 这是旧的RS
[root@k8s-master1 ~]grep -e "nginx-deployment-64db67d8bc" -e "NAME" rs-display.txt
NAME DESIRED CURRENT READY AGE
nginx-deployment-64db67d8bc 5 5 5 87m
nginx-deployment-64db67d8bc 4 5 5 87m
nginx-deployment-64db67d8bc 4 5 5 87m
nginx-deployment-64db67d8bc 4 4 4 87m
nginx-deployment-64db67d8bc 3 4 4 87m
nginx-deployment-64db67d8bc 3 4 4 87m
nginx-deployment-64db67d8bc 3 3 3 87m
nginx-deployment-64db67d8bc 2 3 3 87m
nginx-deployment-64db67d8bc 2 3 3 87m
nginx-deployment-64db67d8bc 2 2 2 87m
nginx-deployment-64db67d8bc 1 2 2 87m
nginx-deployment-64db67d8bc 1 2 2 87m
nginx-deployment-64db67d8bc 1 1 1 87m
nginx-deployment-64db67d8bc 0 1 1 87m
nginx-deployment-64db67d8bc 0 1 1 87m
nginx-deployment-64db67d8bc 0 0 0 87m
❔ 说明:
- 日志输出与策略描述一致,新的RS与旧的RS并行执行;
- 新RS的DESIRED数值按
MaxSurge
递增,旧RS的DESIRED数值按maxUnavailable
递减 - 当DESIRED等于CURRENT,RS才会继续向下执行递增(递减)。
2.2.4 多次更新并行时
❓ 思考: 如果在执行了Deployment的第一次更新操作后,立刻执行第二次更新操作,K8S会怎么处理呢?
如果你更新了正在进行更新任务的 Deployment,那么Deployment 会根据最新更新的模板内容来创建一个新的 ReplicaSet 并开始扩展,并将之前的ReplicaSet标志成旧的 ReplicaSet 并开始缩减。
例如,假设您创建一个 Deployment 来创建 5 个nginx:1.26.1
副本,但随后更新该 Deployment 来创建 5 个nginx:1.27.1
副本,而此时只创建了 3 个nginx:1.26.1
副本。在这种情况下,Deployment 会立即开始终止其创建的 3 个nginx:1.26.1
Pod,并开始创建nginx:1.27.1
Pod。它不会等待nginx:1.26.1
的 5 个副本创建后才改变方向。
2.2.5 验证多次更新并行时
还是沿用nginx-deployment,我们先将镜像更新为nginx:1.26.1
,然后将镜像更新为nginx:stable
kubectl set image deployment/nginx-deployment nginx=harbor.zx/hcie/nginx:1.26.1
kubectl set image deployment/nginx-deployment nginx=harbor.zx/hcie/nginx:stable
在这过程,一直观察rs的状态
# 查看ReplicaSet执行情况
kubectl get rs -l app=nginx -w
直到pod数量达到5个, 暂停日志输出。
查看ReplicaSet执行日志,可以看到nginx-deployment-64db67d8bc
是原RS,nginx-deployment-546946b498
是第一次更新的RS,nginx-deployment-56968dfdd4
是第二次更新的RS。
[root@k8s-master1 ~]# kubectl get rs -l app=nginx -w
NAME DESIRED CURRENT READY AGE
nginx-deployment-546946b498 0 0 0 110m
nginx-deployment-5dd79cf485 0 0 0 112m
nginx-deployment-64db67d8bc 5 5 5 119m
#第一次更新的RS
nginx-deployment-546946b498 0 0 0 110m
nginx-deployment-546946b498 1 0 0 110m
nginx-deployment-64db67d8bc 4 5 5 119m
nginx-deployment-546946b498 1 0 0 110m
# 原RS进行删除
nginx-deployment-64db67d8bc 4 5 5 119m
nginx-deployment-546946b498 1 1 0 110m
nginx-deployment-546946b498 2 1 0 110m
nginx-deployment-64db67d8bc 4 4 4 119m
nginx-deployment-546946b498 2 1 0 110m
nginx-deployment-546946b498 2 2 0 110m
#第二次更新的RS
nginx-deployment-56968dfdd4 0 0 0 0s
nginx-deployment-56968dfdd4 0 0 0 0s
# 第一次更新的RS,DESIRED直接置为零,开始删第一次更新的Pod
nginx-deployment-546946b498 0 2 0 110m
nginx-deployment-546946b498 0 2 1 110m
#第二次更新的RS继续创建,直到到达Replica指定数量
nginx-deployment-56968dfdd4 2 0 0 0s
nginx-deployment-546946b498 0 2 1 110m
...
# 原RS删除直到pod为0
nginx-deployment-64db67d8bc 0 0 0 120m
nginx-deployment-56968dfdd4 5 5 5 50s
❔ 说明:
- 当Deployment监听到更新指令时,新RS开始增加,旧RS开始删除
- 当Deployment监听到第二次更新指令时, 立刻创建第二个新RS, 第一个新RS立刻删除;
- 最终第二个新RS达到DESIRED数量, 第一个新RS和旧RS被删除。
2.3 回滚Deployment
2.3.1 模拟更新Deployment出错
例如,当 新部署的Deployment 不稳定时,例如应用出现循环崩溃,您可能想要回滚历史版本。默认情况下,所有更新历史记录都保留在系统中,以便您可以随时回滚(您可以通过修改修订历史记录限制来更改它)。
假设您在更新部署时,将映像名称拼写错误,设置为nginx:1.261
:
kubectl set image deployment/nginx-deployment nginx=nginx:1.261
查询rollout状态,会发现会被卡住:
[root@k8s-master1 ~]# kubectl rollout status deployment/nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 5 new replicas have been updated...
而RS的状态同样是卡住:
[root@k8s-master1 hcie]# kubectl get rs -l app=nginx
NAME DESIRED CURRENT READY AGE
nginx-deployment-546946b498 0 0 0 130m
nginx-deployment-56968dfdd4 4 4 4 19m
nginx-deployment-5dd79cf485 0 0 0 132m
nginx-deployment-64db67d8bc 0 0 0 139m
nginx-deployment-f64455fb9 2 2 0 17s
查看pods状态,可以直观看到是镜像拉取出错
[root@k8s-master1 ~]# kubectl get pods -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-deployment-56968dfdd4-6wpmt 1/1 Running 0 21m
nginx-deployment-56968dfdd4-k48mt 1/1 Running 0 22m
nginx-deployment-56968dfdd4-k9zq8 1/1 Running 0 22m
nginx-deployment-56968dfdd4-s7jpp 1/1 Running 0 22m
nginx-deployment-f64455fb9-7p6hw 0/1 ImagePullBackOff 0 2m56s
nginx-deployment-f64455fb9-h9d5h 0/1 ImagePullBackOff 0 2m57s
2.3.2 检查Deployment的Rollout历史记录
首先,检查此 Deployment 的修订(revisions),执行以下命令:
[root@k8s-master1 hcie]# kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
8 <none>
9 <none>
10 <none>
11 <none>
❔ 说明:
- 当触发deployment的rollout时,会创建deployment的修订版。这意味着当且仅当 Deployment 的 Pod 模板 (
.spec.template
) 发生更改时才会创建新修订版本,例如,如果您更新模板的标签或容器映像。 - 原创建修订的方法,
--record=true
参数已经标记deprecated, 所以建议使用注释的方法; CHANGE-CAUSE
在创建时从deployment的注释kubernetes.io/change-cause
复制到其修订版本。您可以通过以下方式指定CHANGE-CAUSE
消息:
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to 1.26.1"
- 或者直接修改deployment的注释
kubectl edit deployment/nginx-deployment
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "11"
# 更新时新增注释
kubernetes.io/change-cause: 1.26.1
然后,要查看上一个修订的详细信息,执行以下命令:
kubectl rollout history deployment/nginx-deployment --revision=10
输出如下:
deployment.apps/nginx-deployment with revision #10
Pod Template:
Labels: app=nginx
pod-template-hash=56968dfdd4
Containers:
nginx:
Image: harbor.zx/hcie/nginx:stable
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
2.3.3 回滚到以前的修订
按照下面给出的步骤将 Deployment 从当前版本回滚到之前的版本,即版本 10。
现在可以撤消当前的rollout操作:
kubectl rollout undo deployment/nginx-deployment
输出如下:
deployment.apps/nginx-deployment rolled back
或者,直接指定历史版本回滚:
kubectl rollout undo deployment/nginx-deployment --to-revision=9
查看deployment状态
[root@k8s-master1 hcie]# kubectl describe deployments.apps nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Mon, 09 Sep 2024 20:19:13 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 14
Selector: app=nginx
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: harbor.zx/hcie/nginx:1.27.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
2.4 扩展Deployment
如果要临时对deployment进行扩展, 可以使用以下命令:
kubectl scale deployment/nginx-deployment --replicas=10
输出如下:
deployment.apps/nginx-deployment scaled
同样, 如果希望对deployment进行缩减,也可以执行该命令
kubectl scale deployment/nginx-deployment --replicas=3
❔ 说明: 后续文章会对K8S的HPA弹性扩展进行深入剖析,敬请期待。
2.5 暂停和恢复deployment的rollout
❔ 说明: 这个方法在实际场景比较少用到, 这里仅做功能介绍。
当您计划更新deployment时,您可能会做一项或多项更新操作,并希望暂停该deployment的rollout流程,当您准备好应用这些更改时,再恢复deployment的rollout流程。这种方法允许您在暂停和恢复之间应用多个修复,而不会触发不必要的rollout流程。
例如: 你可能需要对deployment更新镜像或者其他操作,如配置资源。
通过运行以下命令暂停:
kubectl rollout pause deployment/nginx-deployment
输出如下:
deployment.apps/nginx-deployment paused
然后更新 deployment 的镜像:
kubectl set image deployment/nginx-deployment nginx=nginx:1.26.1
输出如下:
deployment.apps/nginx-deployment image updated
请注意,没有开始新的部署:
kubectl rollout history deployment/nginx-deployment
输出如下:
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
8 <none>
12 <none>
13 1.26.1
14 <none> -- 当前版本,没有创建新版本
还可以根据需要进行任意多次更新,例如,更新将使用的资源:
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=100m,memory=512Mi
输出如下:
deployment.apps/nginx-deployment resource requirements updated
❔ 说明: 暂停部署之前的Pod将继续提供服务,只要暂停了deployment,对deployment的新更新操作就不会产生任何影响。
最后,恢复deployment并观察新的 ReplicaSet 是否出现了所有新更新:
kubectl rollout resume deployment/nginx-deployment
输出如下:
deployment.apps/nginx-deployment resumed
观察RS状态是否完成更新
[root@k8s-master1 hcie]# kubectl get rs -w
NAME DESIRED CURRENT READY AGE
nfs-subdir-external-provisioner-7784486c98 1 1 1 5d5h
nginx-deployment-546946b498 4 4 4 169m
...
nginx-deployment-546946b498 0 0 0 169m
nginx-deployment-556dbcb546 5 5 5 27s
查看详细信息
[root@k8s-master1 hcie]# kubectl describe deploy nginx-deployment
Name: nginx-deployment
Namespace: default
CreationTimestamp: Mon, 09 Sep 2024 20:19:13 +0800
Labels: app=nginx
Annotations: deployment.kubernetes.io/revision: 15
Selector: app=nginx
Replicas: 5 desired | 5 updated | 5 total | 5 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.26.1
Port: 80/TCP
Host Port: 0/TCP
Limits:
cpu: 100m
memory: 512Mi
❔ 说明:
- 镜像和资源限制都更新了
⚠️ 注意:如果deployment被暂停,在被恢复之前您无法对deployment进行回滚操作。
3 参考文献
[2]https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)