00000229
Deployment是 Kubernetes 中用于管理 无状态应用(Stateless Application) 的控制器(Controller),它声明了 期望的 Pod 副本数 与 Pod 模板,并由控制器自动维持实际状态与期望状态一致。
无状态应用特征:
常见无状态服务:Web 前端、API 服务、Nginx、Tomcat、Spring Boot 微服务等。
Deployment 核心能力:
| 能力 | 说明 | SRE 价值 |
|---|---|---|
声明式更新 |
通过修改 |
变更可重复、可审计 |
滚动更新(RollingUpdate) |
逐步替换旧版本 Pod,保证服务不中断 |
零停机发布 |
回滚(Rollback) |
快速恢复到历史版本 |
变更失败时快速止血 |
扩缩容(Scaling) |
动态调整副本数 |
应对流量波动 |
自愈能力 |
Pod 异常退出时自动重建 |
提升可用性 |
Deployment 工作原理(Mermaid):
graph TD
A[用户创建/更新 Deployment] --> B[Deployment Controller 检测到期望状态变化]
B --> C[创建 ReplicaSet 新版本]
C --> D[新 ReplicaSet 逐步创建新版本 Pod]
D --> E[旧 ReplicaSet 按比例缩减 Pod]
E --> F[直到旧 ReplicaSet 副本数为 0]
F --> G[更新完成 保留历史 ReplicaSet 供回滚]
H[用户触发回滚] --> I[Deployment Controller 选择历史 ReplicaSet]
I --> J[重新扩容旧版本 ReplicaSet 缩容当前版本]
J --> K[回滚完成]
ReplicaSet:Deployment 的子资源,负责维护固定版本的 Pod 副本数。每次更新会创建一个新的 ReplicaSet,旧 ReplicaSet 保留(默认保留 10 个历史版本)。
滚动更新策略:由 strategy.type=RollingUpdate控制,可配置最大不可用 Pod 数和最大 surge Pod 数。
1. 滚动更新策略(RollingUpdate)
在 Deployment.spec.strategy中配置:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25% # 更新过程中最大不可用 Pod 比例(或绝对值)
maxSurge: 25% # 更新过程中最大超出期望副本数的 Pod 比例(或绝对值)
maxUnavailable:保证服务可用性的下限(如 25% 表示至少保留 75% 的 Pod 可用)。maxSurge:允许临时超出期望副本数的 Pod 数量,用于加速更新(如 25% 表示最多可多出 25% 的 Pod)。更新顺序:
maxSurge创建新版本 Pod;maxUnavailable控制删除速率);2. 回滚机制
Kubernetes 自动保存 Deployment 的 Revision History(修订历史),可通过以下方式回滚:
kubectl rollout undo deployment/<name>(回滚到上一版)kubectl rollout undo deployment/<name> --to-revision=<rev>kubectl rollout pause/resume deployment/<name>(分批验证更新)每次回滚会重新扩容旧版本 ReplicaSet,缩容当前版本 ReplicaSet。
YAML 配置(nginx-deploy-v1.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: prod
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy: # 升级策略
# 指定升级的类型,"Recreate" or "RollingUpdate"
# Recreate:
# 代表的是删除所有旧的Pod,再去创建新的Pod,不推荐使用。
# RollingUpdate:
# 代表滚动更新,会更新一部分Pod,逐步替换旧的Pod,默认就是这种类型。
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 更新时最多 1 个 Pod 不可用
maxSurge: 1 # 更新时最多多出 1 个 Pod
template:
metadata:
labels:
app: nginx
version: "v1.0"
spec:
containers:
- name: nginx
image: harbor.wyasw.com/test/nginx:v1
ports:
- containerPort: 80
# 指定镜像的拉取策略,有效值为: Always, Never, IfNotPresent
# Never:
# 如果本地有镜像则尝试启动。
# 如果本地没有镜像则不会去远程仓库拉取镜像。
# IfNotPresent:
# 如果本地有镜像则尝试启动。
# 如果本地没有镜像则去远程仓库拉取镜像。
# Always:
# 如果本地有镜像,则会将本地的镜像和远程仓库的摘要信息进行对比,若一致则直接使用本地缓存镜像,若不一致则重新拉取。
# 如果本地没有镜像,则直接从远程仓库拉取镜像。
#
# 默认策略会根据镜像的标签来定:
# 如果你的tag是"latest",则默认策略为"Always";
# 若你的tag是非"latest",则默认策略为"IfNotPresent"
imagePullPolicy: Always
部署:
kubectl create namespace prod kubectl apply -f nginx-deploy-v1.yaml # 查询 Deployment nginx-deploy在 prod命名空间的滚动更新状态 kubectl rollout status deployment/nginx-deploy -n prod # kubectl get pods -n prod -o wide # curl podIP # 显示 v1
编辑 Deployment(或使用新 YAML)
kubectl set image deployment/nginx-deploy nginx=harbor.wyasw.com/test/nginx:v2 -n prod
# 或
kubectl patch deployment nginx-deploy -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"harbor.wyasw.com/test/nginx:v2"}]}}}}'
立即(运行更新命令后立即执行)查看更新状态
kubectl rollout status deployment/nginx-deploy -n prod # 输出示例: # Waiting for deployment "nginx-deploy" rollout to finish: 2 of 3 updated replicas are available... # deployment "nginx-deploy" successfully rolled out # kubectl get pods -n prod -o wide # curl podIP # 显示 v2
查看修订历史
kubectl rollout history deployment/nginx-deploy -n prod # 输出示例: # REVISION CHANGE-CAUSE # 1 <none> # 2 <none>
# 回滚到上一版本 kubectl rollout undo deployment/nginx-deploy -n prod # 回滚到指定版本(如 revision 1) kubectl rollout undo deployment/nginx-deploy -n prod --to-revision=1
用于灰度验证:
# 暂停更新 kubectl rollout pause deployment/nginx-deploy -n prod # 进行一次小批量更新(例如修改一个环境变量) kubectl set env deployment/nginx-deploy TEST_ENV=true -n prod # 验证部分 Pod 状态 kubectl get pods -l app=nginx -n prod -o wide # 确认无误后继续更新 kubectl rollout resume deployment/nginx-deploy -n prod