ToolkitX
知识库工具箱

部署策略

滚动更新、蓝绿部署、金丝雀发布

25min·高级

01. Deployment——Pod 的管理者

Deployment 是 K8s 最常用的控制器——它管理 ReplicaSet,ReplicaSet 管理 Pod。你定义期望状态(几个副本、什么镜像),Deployment 保证实际状态跟期望一致。 Deployment 的核心功能: 1. 副本管理——保证指定数量的 Pod 一直跑着。少了就补,多了就杀。 2. 滚动更新——改变镜像版本时,一个一个替换 Pod,服务不中断。 3. 回滚——升级出了问题,一键回到上一个版本。 4. 扩缩容——改 replicas 数字,秒级生效。 创建 Deployment 最常用 kubectl create deployment(命令行快捷方式)和 kubectl apply -f deployment.yaml(YAML 声明式,推荐)。
yaml
# 命令行快捷创建
kubectl create deployment my-app --image=nginx --replicas=3

# YAML 方式
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: app
        image: nginx:1.25
        ports:
        - containerPort: 80

02. 滚动更新——怎么不停机升级

滚动更新是 Deployment 的杀手级功能。你改一下 image 版本号然后 apply,Deployment 会创建一个新的 ReplicaSet,按配置的策略逐步用新 Pod 替换旧 Pod。 控制滚动更新的两个关键参数: maxSurge——更新期间最多可以多出几个 Pod(超出 replicas 数量)。默认 25%。比如 replicas=4,最多可以临时跑到 5 个。 maxUnavailable——更新期间最多几个 Pod 可以不可用。默认 25%。比如 replicas=4,最多 1 个 Pod 可以不接流量。 更新策略:RollingUpdate(一个个换,默认)和 Recreate(先把所有旧的删了再建新的,有停机时间)。除非真的不能同时跑新旧版本(如数据库 schema 不兼容),不然都用 RollingUpdate。
bash
# 更新镜像
kubectl set image deployment/my-app app=nginx:1.26

# 或者在 YAML 里改 image 然后重新 apply
kubectl apply -f deployment.yaml

# 查看更新进度
kubectl rollout status deployment/my-app

# 查看更新历史
kubectl rollout history deployment/my-app

# 调整滚动更新策略
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
maxUnavailable: 0 表示更新时不允许任何 Pod 不可用,但需要临时多出一个 Pod(maxSurge 至少为 1)。这是最保守的更新策略。

03. 回滚——出错了怎么退回去

升级后发现问题怎么办?Deployment 保存了更新历史(默认保留 10 个版本),一条命令就能回滚。 kubectl rollout undo deployment/my-app——回到上一个版本。 kubectl rollout undo deployment/my-app --to-revision=3——回到指定的第 3 版。 kubectl rollout history deployment/my-app——看所有历史版本。 每次对 Deployment 的 template(即 Pod 的定义)的修改都会创建一个新 Revision。改 replicas 数不算新 Revision。 回滚也是通过滚动更新来实现的——Deployment 会创建新的 ReplicaSet,逐步替换当前 Pod。
bash
# 查看更新历史
kubectl rollout history deployment/my-app

# 查看某个版本的具体信息
kubectl rollout history deployment/my-app --revision=3

# 回滚到上一个版本
kubectl rollout undo deployment/my-app

# 回滚到指定版本
kubectl rollout undo deployment/my-app --to-revision=2

# 暂停和恢复更新
kubectl rollout pause deployment/my-app   # 暂停
kubectl rollout resume deployment/my-app  # 恢复
在持续部署(CD)里,部署后发现监控指标异常可以自动执行 rollout undo——这是 GitOps 的标配操作。

04. 扩缩容与自动伸缩(HPA)

手动扩缩容:kubectl scale deployment my-app --replicas=5。秒级生效,K8s 立刻启动或终止 Pod。 水平自动伸缩(HPA)——根据 CPU 使用率或自定义指标自动调整副本数。HPA 定期检查指标,如果 Pod 的平均 CPU 超过你设定的阈值,自动增加副本。反之减少。 HPA 需要三个条件:Deployment 必须设了 resources.requests(HPA 要知道什么是 100%);集群安装了 metrics-server(收集 CPU/内存指标);你创建了 HPA 资源。 除了 CPU 和内存,HPA 还支持自定义指标(如请求 QPS、队列长度)。需要安装 Prometheus Adapter。
yaml
# 手动扩容
kubectl scale deployment my-app --replicas=5

# 创建 HPA
kubectl autoscale deployment my-app --min=2 --max=10 --cpu-percent=70

# HPA YAML
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
HPA 的冷却时间有默认值——扩容后等 3 分钟再考虑缩容,避免抖动。这些参数可以配但一般默认值够用。

05. 金丝雀发布与蓝绿部署

除了标准滚动更新,还有更复杂的发布策略: 蓝绿部署——准备两套完整的环境(蓝=旧版,绿=新版)。新版部署好后,一次性把所有流量从蓝切到绿。优点:瞬间切换,有问题立刻切回去。缺点:双倍资源。 金丝雀发布——先把新版放给一小部分用户(比如 10% 流量),观察没问题再逐步放大到 100%。用 Service 的 Label Selector 配合多个 Deployment 实现。 K8s 原生的 Deployment 不直接支持这些策略,但可以借助: - 多个 Deployment + 共享的 Service(通过 Label 控制流量比例) - Service Mesh(Istio、Linkerd)做更精细的流量控制 - Argo Rollouts(专门做渐进式发布的 K8s 控制器) - Flagger(配合 Service Mesh 做金丝雀发布)
bash
# 金丝雀发布思路(用 Label 分流)
# 主 Deployment: label version: stable
# 金丝雀 Deployment: label version: canary(只有 1 个副本)
# Service selector 同时匹配 stable 和 canary
# 大多数流量到 stable,少部分到 canary
生产环境直接上 Istio 或 Argo Rollouts 做金丝雀发布,比手动调 Label 靠谱得多。K8s 原生对高级发布策略支持有限。

知识测验

1/5正确 0

Deployment 的默认更新策略是什么?

下一节

存储管理

下一节