Deployment 部署
Deployment 是 Kubernetes 中最常用的资源对象,用于管理无状态应用的部署、更新和扩缩容。理解 Deployment 的工作原理,是掌握 Kubernetes 应用管理的基础。
什么是 Deployment?
Deployment 为 Pod 和 ReplicaSet 提供声明式更新能力,是管理无状态应用的首选方式。你只需要描述期望的状态,Deployment 控制器会以可控的速率将实际状态转变为期望状态。
Deployment 的核心价值
在实际生产环境中,我们面临这些问题:
- 如何保证应用始终运行指定数量的副本?
- 如何安全地更新应用版本,同时保证服务不中断?
- 如何在更新失败时快速回滚?
- 如何根据负载自动扩缩容?
Deployment 正是为了解决这些问题而设计的。
Deployment 与 ReplicaSet、Pod 的关系
Deployment 不直接管理 Pod,而是通过 ReplicaSet 间接管理。这种设计有几个好处:
- 版本管理:每次更新都会创建新的 ReplicaSet,保留历史版本
- 回滚能力:可以通过切换 ReplicaSet 实现快速回滚
- 滚动更新:新旧 ReplicaSet 协同工作,实现平滑过渡
创建 Deployment
基础 Deployment
一个完整的 Deployment 定义包含三个关键部分:元数据(metadata)、规格(spec)和 Pod 模板(template)。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
environment: production
spec:
# Pod 副本数
replicas: 3
# 选择器:定义 Deployment 管理哪些 Pod
# 注意:selector 必须与 template.labels 匹配
selector:
matchLabels:
app: nginx
# Pod 模板:定义要创建的 Pod 的规格
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
关键字段详解
replicas(副本数):指定需要运行的 Pod 数量。Deployment 会确保始终有指定数量的 Pod 在运行。
selector(选择器):定义 Deployment 如何找到它管理的 Pod。.spec.selector.matchLabels 必须与 .spec.template.metadata.labels 匹配,否则 Deployment 无法正确管理 Pod。
template(Pod 模板):定义 Pod 的规格,包括容器镜像、端口、环境变量等。这个模板会被 ReplicaSet 用来创建 Pod。
使用 kubectl 创建
# 使用 YAML 文件创建(推荐)
kubectl apply -f deployment.yaml
# 查看创建结果
kubectl get deployments
# 输出示例
# NAME READY UP-TO-DATE AVAILABLE AGE
# nginx-deployment 3/3 3 3 18s
# 查看字段含义:
# READY - 就绪副本数/期望副本数
# UP-TO-DATE - 已更新到最新模板的副本数
# AVAILABLE - 可供用户访问的副本数
# AGE - 运行时长
# 使用命令快速创建(适合测试)
kubectl create deployment nginx --image=nginx:1.25 --replicas=3
# 生成 YAML 模板(dry-run)
kubectl create deployment nginx --image=nginx --dry-run=client -o yaml > deployment.yaml
Pod-template-hash 标签
创建 Deployment 后,你会发现每个 Pod 都有一个额外的标签 pod-template-hash:
kubectl get pods --show-labels
# 输出示例
# NAME LABELS
# nginx-deployment-75675f5897-abc12 app=nginx,pod-template-hash=75675f5897
# nginx-deployment-75675f5897-def34 app=nginx,pod-template-hash=75675f5897
# nginx-deployment-75675f5897-ghi56 app=nginx,pod-template-hash=75675f5897
这个标签是 Deployment 控制器自动添加的,用于确保同一 Deployment 的不同版本(不同的 ReplicaSet)不会重叠。不要手动修改这个标签,否则可能导致 Deployment 无法正确管理 Pod。
更新策略
Deployment 支持两种更新策略:RollingUpdate(滚动更新)和 Recreate(重建)。选择正确的策略对于应用的可用性至关重要。
RollingUpdate(滚动更新,默认)
滚动更新是默认策略,它逐步替换旧版本的 Pod,确保在更新过程中始终有一定数量的 Pod 可用。
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 允许超过期望副本数最多 1 个(可以是数字或百分比)
maxUnavailable: 0 # 最多允许 0 个 Pod 不可用(可以是数字或百分比)
maxSurge 和 maxUnavailable 详解:
这两个参数决定了滚动更新的节奏,理解它们对于控制更新过程至关重要。
| 参数 | 默认值 | 说明 |
|---|---|---|
| maxSurge | 25% | 更新期间可以比期望副本数多创建的 Pod 数量上限 |
| maxUnavailable | 25% | 更新期间可以不可用的 Pod 数量上限 |
实际计算示例(replicas=4):
默认配置:maxSurge=25%, maxUnavailable=25%
maxSurge = ceil(4 * 0.25) = 1 # 最多可以有 5 个 Pod 运行
maxUnavailable = ceil(4 * 0.25) = 1 # 最少必须有 3 个 Pod 可用
更新过程中 Pod 数量范围:[3, 5]
常见的策略配置组合:
# 组合一:保证零停机(推荐用于关键服务)
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
# 特点:先创建新 Pod,就绪后才删除旧 Pod
# 适用场景:对可用性要求极高的服务
# 组合二:快速更新(资源有限时)
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
# 特点:先删除旧 Pod,再创建新 Pod
# 适用场景:资源紧张,可以容忍短暂不可用
# 组合三:平衡模式(默认)
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
# 特点:在速度和可用性之间平衡
# 适用场景:一般服务
滚动更新工作流程:
Recreate(重建)
Recreate 策略会先终止所有旧 Pod,等待它们完全终止后,再创建新 Pod。
spec:
replicas: 3
strategy:
type: Recreate
特点:
- 更新期间服务完全不可用
- 不需要额外的资源
- 适合不支持多个版本同时运行的应用
适用场景:
- 应用不支持新旧版本同时运行(如数据库 schema 变更)
- 测试/开发环境
- 可以接受短暂不可用的非关键服务
minReadySeconds 参数
minReadySeconds 指定新创建的 Pod 在被认为可用之前必须保持就绪状态的最小秒数:
spec:
replicas: 3
minReadySeconds: 30 # Pod 就绪后等待 30 秒才算可用
这个参数的作用是防止新 Pod 刚启动就因为某些问题立即崩溃,导致滚动更新过快地将流量切换到有问题的 Pod。设置适当的值可以增加更新过程的稳定性。
扩缩容
Deployment 支持手动扩缩容和自动扩缩容(HPA)两种方式。
手动扩缩容
# 扩容到 5 个副本
kubectl scale deployment nginx-deployment --replicas=5
# 缩容到 2 个副本
kubectl scale deployment nginx-deployment --replicas=2
# 基于条件扩容(只有当前副本数为 3 时才扩容)
kubectl scale deployment nginx-deployment --current-replicas=3 --replicas=5
手动扩缩容适用于:
- 预知流量高峰(促销活动、发布等)
- 维护期间调整容量
- 测试环境快速调整
自动扩缩容(HPA)
Horizontal Pod Autoscaler(HPA)根据 CPU、内存等指标自动调整副本数。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2 # 最小副本数
maxReplicas: 10 # 最大副本数
metrics:
# CPU 使用率指标
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU 使用率超过 70% 时扩容
# 内存使用率指标
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80 # 内存使用率超过 80% 时扩容
# 自定义指标(需要安装 Metrics Server)
- type: Pods
pods:
metric:
name: requests-per-second
target:
type: AverageValue
averageValue: 1000 # 每秒请求数
# 创建 HPA
kubectl apply -f hpa.yaml
# 快速创建 HPA(命令行方式)
kubectl autoscale deployment nginx-deployment --min=2 --max=10 --cpu-percent=70
# 查看 HPA 状态
kubectl get hpa
# 输出示例
# NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
# nginx-hpa Deployment/nginx-deployment 50%/70% 2 10 3 5m
# 查看 HPA 详情
kubectl describe hpa nginx-hpa
HPA 工作原理
HPA 计算公式:
期望副本数 = ceil(当前副本数 × (当前指标值 / 目标指标值))
示例:
- 当前副本数:3
- 当前 CPU 使用率:140%
- 目标 CPU 使用率:70%
- 期望副本数 = ceil(3 × 140 / 70) = ceil(6) = 6
HPA 会定期(默认 15 秒)检查指标,当指标超过目标值时扩容,低于目标值时缩容。为了避免频繁波动,HPA 有以下机制:
- 扩容:立即执行,没有冷却时间
- 缩容:有 5 分钟的稳定期,避免指标波动导致频繁缩容
前置条件
使用 HPA 需要安装 Metrics Server:
# 安装 Metrics Server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# 验证安装
kubectl get pods -n kube-system -l k8s-app=metrics-server
# 测试指标获取
kubectl top nodes
kubectl top pods
更新 Deployment
触发更新的条件
只有修改 .spec.template(Pod 模板)时才会触发滚动更新。修改以下内容会触发更新:
- 容器镜像
- Pod 标签
- 环境变量
- 资源限制
- 探针配置
修改其他字段(如 replicas、strategy)不会触发更新,只是修改 Deployment 的配置。
更新镜像
# 方式一:使用 set image 命令
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# 语法:kubectl set image deployment/<deployment-name> <container-name>=<new-image>
# 注意:<container-name> 是 Pod 模板中的容器名称,不是 Pod 名称
# 方式二:编辑 Deployment
kubectl edit deployment/nginx-deployment
# 在编辑器中修改 .spec.template.spec.containers[0].image
# 方式三:使用 patch
kubectl patch deployment nginx-deployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.26"}]}}}}'
# 方式四:修改 YAML 文件后重新 apply
kubectl apply -f deployment.yaml
查看更新状态
# 查看滚动更新状态
kubectl rollout status deployment/nginx-deployment
# 输出示例
# Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
# Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
# Waiting for rollout to finish: 1 old replicas are pending termination...
# deployment "nginx-deployment" successfully rolled out
# 实时观察更新过程
kubectl get pods -w
# 查看 ReplicaSet 状态(了解新旧版本副本数)
kubectl get rs
# 输出示例
# NAME DESIRED CURRENT READY AGE
# nginx-deployment-1564180365 3 3 3 6s # 新版本
# nginx-deployment-2035384211 0 0 0 36s # 旧版本
# 查看 Deployment 详情
kubectl describe deployment nginx-deployment
暂停和恢复更新
有时你需要对 Deployment 进行多次修改,但不希望每次修改都触发一次滚动更新。这时可以先暂停更新,完成所有修改后再恢复。
# 暂停 Deployment 的更新
kubectl rollout pause deployment/nginx-deployment
# 现在可以进行多次修改,不会触发更新
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
kubectl set resources deployment/nginx-deployment -c nginx --limits=cpu=200m,memory=512Mi
kubectl set env deployment/nginx-deployment ENV=production
# 恢复更新(所有修改会一次性应用)
kubectl rollout resume deployment/nginx-deployment
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
暂停更新的典型应用场景:
- 需要同时更新镜像和配置
- 需要进行多项测试环境的修改
- 避免多次触发 CI/CD 流水线
回滚机制
Deployment 的回滚功能是其最重要的特性之一,让你能够在更新出现问题时快速恢复到之前的状态。
查看历史版本
# 查看所有历史版本
kubectl rollout history deployment/nginx-deployment
# 输出示例
# deployment.apps/nginx-deployment
# REVISION CHANGE-CAUSE
# 1 <none>
# 2 <none>
# 3 kubectl set image deployment/nginx-deployment nginx=nginx:1.26 --record=true
# 查看特定版本的详细信息
kubectl rollout history deployment/nginx-deployment --revision=2
# 输出示例
# Pod Template:
# Labels: app=nginx
# pod-template-hash=75675f5897
# Containers:
# nginx:
# Image: nginx:1.25
# Port: 80/TCP
注意:CHANGE-CAUSE 列显示更新原因。要记录更新原因,需要在执行更新时添加 --record=true 参数(但这个参数已弃用,推荐使用注解):
# 推荐方式:使用注解记录更新原因
kubectl annotate deployment nginx-deployment kubernetes.io/change-cause="更新到 nginx 1.26"
执行回滚
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 输出示例
# deployment.apps/nginx-deployment rolled back
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=1
# 查看回滚状态
kubectl rollout status deployment/nginx-deployment
控制历史版本数量
使用 revisionHistoryLimit 控制保留的历史版本数量:
spec:
replicas: 3
revisionHistoryLimit: 10 # 默认值,保留 10 个历史版本
较小的值可以节省 etcd 存储空间,但会限制回滚的选择。对于频繁更新的应用,建议保留足够的版本数。
设置更新超时
使用 progressDeadlineSeconds 设置更新超时时间:
spec:
replicas: 3
progressDeadlineSeconds: 600 # 10 分钟超时
如果更新在指定时间内没有进展,Deployment 会被标记为失败,状态变为 ProgressDeadlineExceeded。这可以防止更新卡住而无人发现。
# 查看是否有超时
kubectl describe deployment nginx-deployment
# 输出示例
# Conditions:
# Type Status Reason
# ---- ------ ------
# Available True MinimumReplicasAvailable
# Progressing False ProgressDeadlineExceeded
# ReplicaFailure True InsufficientReplicas
Deployment 状态详解
了解 Deployment 的状态对于排查问题至关重要。Deployment 有几个关键的状态条件(Conditions)。
状态条件
| 条件类型 | 说明 |
|---|---|
Available | Deployment 的最小可用副本数已满足 |
Progressing | 正在进行滚动更新或扩缩容 |
ReplicaFailure | 创建/删除 Pod 失败 |
# 查看 Deployment 的状态条件
kubectl describe deployment nginx-deployment
# 输出示例
# Conditions:
# Type Status Reason
# ---- ------ ------
# Available True MinimumReplicasAvailable
# Progressing True NewReplicaSetAvailable
常见状态问题
ProgressDeadlineExceeded:更新超时
# 原因:Pod 无法启动(镜像拉取失败、资源不足等)
# 解决:检查 Pod 事件和日志
kubectl describe pod <pod-name>
kubectl logs <pod-name>
ReplicaFailure:副本创建失败
# 原因:资源不足、配额限制、节点不可用
# 解决:检查资源配额和节点状态
kubectl describe resourcequota -n <namespace>
kubectl get nodes
Deployment 生命周期
状态转换说明
- 创建时:Deployment 进入
Progressing状态,创建 ReplicaSet 和 Pod - 所有副本就绪:状态变为
Complete,Available条件为True - 更新触发:重新进入
Progressing状态,开始滚动更新 - 更新超时:如果超过
progressDeadlineSeconds,状态变为Failed - 回滚:进入
Progressing状态,恢复到指定版本
Deployment 配置详解
完整配置示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: production
labels:
app: my-app
version: v1
spec:
replicas: 3
revisionHistoryLimit: 5 # 保留的历史版本数
progressDeadlineSeconds: 600 # 最大等待时间(秒)
selector:
matchLabels:
app: my-app
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: my-app
version: v1
spec:
# 副本亲和性
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: my-app
topologyKey: kubernetes.io/hostname
containers:
- name: app
image: my-app:v1
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
protocol: TCP
# 资源配额
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
# 健康检查
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
# 环境变量
env:
- name: APP_ENV
value: "production"
# 卷挂载
volumeMounts:
- name: config
mountPath: /app/config
# 初始化容器
initContainers:
- name: init-db
image: busybox:1.36
command: ['sh', '-c', 'echo Waiting for DB']
# 亲和性
tolerations:
- key: "dedicated"
value: "app"
effect: NoSchedule
# 存储卷
volumes:
- name: config
configMap:
name: app-config
# 终止GracePeriod
terminationGracePeriodSeconds: 30
管理命令
查看 Deployment
# 查看 Deployment
kubectl get deployment
# 查看详细信息
kubectl describe deployment nginx-deployment
# 查看 Pod
kubectl get pods -l app=nginx
# 查看 ReplicaSet
kubectl get replicaset -l app=nginx
更新策略
# 设置更新策略
kubectl patch deployment nginx-deployment \
-p '{"spec":{"strategy":{"type":"Recreate"}}}'
# 设置镜像并记录
kubectl set image deployment/nginx-deployment \
nginx=nginx:1.26 --record=true
调试
# 查看特定版本的详情
kubectl rollout history deployment/nginx-deployment --revision=2
# 查看实时状态
kubectl rollout status -w deployment/nginx-deployment
# 进入 Pod 调试
kubectl exec -it <pod-name> -- /bin/sh
最佳实践
1. 资源配置
始终为容器设置资源请求和限制,这是 HPA 和调度的前提:
resources:
# 请求值:调度时的最小资源保证
requests:
memory: "128Mi"
cpu: "100m"
# 限制值:容器可使用的最大资源
limits:
memory: "256Mi"
cpu: "500m"
经验法则:
requests设置为正常运行所需的资源limits设置为峰值时可能需要的资源- limits 不应超过 requests 的 2-4 倍
2. 健康检查
配置存活探针和就绪探针,确保流量只路由到健康的 Pod:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30 # 给应用足够的启动时间
periodSeconds: 10
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
探针区别:
livenessProbe失败 → Pod 重启readinessProbe失败 → 从 Service 移除,但 Pod 继续运行
3. 副本数规划
spec:
replicas: 3 # 生产环境至少 3 个副本
为什么至少 3 个:
- 滚动更新时,最多只有 1 个副本不可用(maxUnavailable=25%)
- 单个节点故障不会导致服务完全不可用
- 支持高可用部署
4. 更新策略选择
# 关键服务:零停机更新
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
# 非关键服务:快速更新
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
5. Pod 反亲和性
将 Pod 分散到不同节点,提高可用性:
spec:
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: my-app
topologyKey: kubernetes.io/hostname
6. 优雅终止
配置足够的终止宽限期,让应用有足够时间清理资源:
spec:
template:
spec:
terminationGracePeriodSeconds: 30 # 默认 30 秒
containers:
- name: app
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 10 && nginx -s quit"]
7. 版本标签
使用标签管理版本,便于问题排查:
template:
metadata:
labels:
app: my-app
version: v1.2.3
commit: abc123
8. 历史版本保留
根据更新频率调整历史版本数量:
spec:
revisionHistoryLimit: 10 # 默认值
- 频繁更新:可以适当增加到 15-20
- 很少更新:可以减少到 5
9. 使用标签选择器最佳实践
确保 Deployment 的 selector 和 Pod 模板标签正确配置:
# 正确配置
selector:
matchLabels:
app: my-app # 必须与 template.labels 匹配
template:
metadata:
labels:
app: my-app # 必须与 selector.matchLabels 匹配
注意事项:
- selector 一旦创建就不能修改
- 不要使用可能与其它 Deployment 重叠的标签
Canary 部署模式
Canary(金丝雀)部署是一种渐进式发布策略,先将新版本部署到少量用户,验证无问题后再逐步扩大范围。
原理说明
Canary 部署的核心思想是:同时运行新旧两个版本,通过控制流量比例来逐步迁移用户。
实现方式
方式一:多 Deployment 方式(推荐)
创建两个 Deployment,通过调整副本数控制流量比例:
# stable-deployment.yaml - 稳定版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-stable
spec:
replicas: 9 # 90% 流量
selector:
matchLabels:
app: nginx
version: stable
template:
metadata:
labels:
app: nginx
version: stable
spec:
containers:
- name: nginx
image: nginx:1.25
---
# canary-deployment.yaml - Canary 版本
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-canary
spec:
replicas: 1 # 10% 流量
selector:
matchLabels:
app: nginx
version: canary
template:
metadata:
labels:
app: nginx
version: canary
spec:
containers:
- name: nginx
image: nginx:1.26 # 新版本
---
# service.yaml - Service 同时选择两个版本
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx # 同时匹配 stable 和 canary
ports:
- port: 80
Canary 流程:
# 1. 初始状态:全部运行稳定版本
kubectl scale deployment nginx-stable --replicas=10
kubectl scale deployment nginx-canary --replicas=0
# 2. 开始 Canary:10% 流量到新版本
kubectl scale deployment nginx-canary --replicas=1
# 3. 监控指标,无问题则扩大
kubectl scale deployment nginx-canary --replicas=2 # 20% 流量
kubectl scale deployment nginx-canary --replicas=5 # 50% 流量
# 4. 全量切换:新版本接管全部流量
kubectl set image deployment/nginx-stable nginx=nginx:1.26
kubectl scale deployment nginx-stable --replicas=10
kubectl scale deployment nginx-canary --replicas=0
方式二:使用 Istio 或 Nginx Ingress
通过服务网格或 Ingress 实现更精细的流量控制(基于权重、Header、Cookie 等):
# Istio VirtualService 示例
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx
spec:
hosts:
- nginx
http:
- route:
- destination:
host: nginx-stable
weight: 90
- destination:
host: nginx-canary
weight: 10
监控 Canary 状态
在 Canary 过程中,需要密切监控新版本的健康状况:
# 监控 Pod 状态
kubectl get pods -l app=nginx
# 监控资源使用
kubectl top pods -l version=canary
# 查看日志
kubectl logs -l version=canary -f
# 监控错误率(需要 Prometheus 等监控工具)
回滚 Canary
如果发现问题,快速回滚:
# 方式一:立即将 Canary 缩容到 0
kubectl scale deployment nginx-canary --replicas=0
# 方式二:如果新版本有问题,回滚 stable
kubectl rollout undo deployment/nginx-stable
其他工作负载控制器
除了 Deployment,Kubernetes 还提供了其他工作负载控制器来管理不同类型的应用。
ReplicaSet
ReplicaSet 确保指定数量的 Pod 副本始终运行。Deployment 内部使用 ReplicaSet 来管理 Pod 副本,通常不需要直接创建 ReplicaSet。
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: my-replicaset
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:1.25
Deployment vs ReplicaSet:
| 特性 | Deployment | ReplicaSet |
|---|---|---|
| 滚动更新 | 原生支持 | 不支持 |
| 回滚 | 支持 | 不支持 |
| 历史版本 | 支持 | 不支持 |
| 使用场景 | 推荐 | 仅在特殊需求时 |
StatefulSet
StatefulSet 用于管理有状态应用,如数据库、消息队列等。它为每个 Pod 提供稳定的网络标识和持久存储。
详细教程请参考:StatefulSet 详解
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-headless
replicas: 3
selector:
matchLabels:
app: mysql
template:
# ... Pod 模板
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
DaemonSet
DaemonSet 确保每个节点上都运行一个 Pod 副本,常用于日志收集、监控代理等系统级守护进程。
详细教程请参考:DaemonSet 详解
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: logging-agent
namespace: kube-system
spec:
selector:
matchLabels:
app: logging
template:
# ... Pod 模板
Job 和 CronJob
Job 用于一次性批处理任务,CronJob 用于定时执行任务。
详细教程请参考:Job 与 CronJob
控制器选择指南
| 应用类型 | 推荐控制器 | 特点 |
|---|---|---|
| 无状态 Web 服务 | Deployment | 快速扩缩容、滚动更新 |
| 有状态数据库 | StatefulSet | 稳定标识、持久存储 |
| 系统守护进程 | DaemonSet | 每个节点一个 Pod |
| 批处理任务 | Job | 一次性执行 |
| 定时任务 | CronJob | 周期性执行 |
小结
本章我们深入学习了 Kubernetes Deployment 的核心知识:
- Deployment 概念:声明式管理 Pod,通过 ReplicaSet 间接管理副本
- 创建 Deployment:YAML 配置的关键字段,pod-template-hash 标签的作用
- 更新策略:RollingUpdate 的 maxSurge/maxUnavailable 参数详解,Recreate 的适用场景
- 更新和回滚:触发条件、暂停恢复、历史版本管理、超时设置
- 扩缩容:手动扩缩容,HPA 自动扩缩容的原理和配置
- 状态管理:Deployment 的状态条件,常见问题排查
- Canary 部署:渐进式发布策略的实现方式
- 最佳实践:资源配置、健康检查、反亲和性、优雅终止等
练习
-
基础练习:创建一个包含 3 个副本的 Deployment,观察 ReplicaSet 和 Pod 的关系
-
滚动更新:更新镜像版本,使用
kubectl get pods -w观察滚动更新过程 -
回滚操作:
- 故意更新到一个不存在的镜像
- 观察更新状态
- 执行回滚
-
扩缩容:
- 手动扩容到 5 个副本
- 配置 HPA(需要 Metrics Server)
- 使用
kubectl top pods观察资源使用
-
高级练习:实现一个 Canary 部署:
- 创建 stable 和 canary 两个 Deployment
- 通过调整副本数控制流量比例
- 监控新版本状态
参考资料
- Kubernetes 官方文档 - Deployment
- Kubernetes 官方文档 - Horizontal Pod Autoscaler
- Kubernetes API 参考 - Deployment
准备好继续学习了吗?点击下一章了解 Service 和网络!