ReplicaSet 与 Deployment:应用编排核心

深入理解 ReplicaSet 的副本管理机制,Deployment 的滚动更新策略,以及金丝雀发布、蓝绿部署等高级发布方式。

概述

Deployment 是 Kubernetes 中最常用的 workload 资源,它基于 ReplicaSet 实现应用的声明式管理。本文将深入探讨:

学习目标

  • 理解 ReplicaSet 的副本管理机制与 Selector 语法
  • 掌握 Deployment 的滚动更新策略与参数调优
  • 学会查看和管理 Deployment 历史版本
  • 了解金丝雀发布、蓝绿部署等高级发布模式
  • 掌握多环境配置与配置继承

ReplicaSet:副本控制器

ReplicaSet 工作原理

┌─────────────────────────────────────────────────────────────────┐
│                   ReplicaSet 控制器工作流程                      │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   用户定义 ReplicaSet(期望状态)                                │
│          │                                                      │
│          ▼                                                      │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                   Control Plane                          │   │
│   │                                                         │   │
│   │   ┌─────────────────────────────────────────────┐       │   │
│   │   │           ReplicaSet Controller              │       │   │
│   │   │                                             │       │   │
│   │   │   1. 读取 RS 的 selector                     │       │   │
│   │   │   2. 统计匹配标签的 Pod 数量                  │       │   │
│   │   │   3. 与期望副本数比较                         │       │   │
│   │   │   4. 差距 > 0 → 创建 Pod                      │       │   │
│   │   │   5. 差距 < 0 → 删除 Pod                      │       │   │
│   │   └─────────────────────────────────────────────┘       │   │
│   └─────────────────────────────────────────────────────────┘   │
│          │                                                      │
│          ▼                                                      │
│   ETCD 存储期望状态 + 实际状态                                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

ReplicaSet 定义

# replicaset-example.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # 期望副本数
  replicas: 3

  # 选择器:匹配拥有这些标签的 Pod
  selector:
    matchLabels:
      tier: frontend

  # Pod 模板
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: redis:3.2.11
        ports:
        - containerPort: 6379

Selector 语法详解

# matchLabels:精确匹配(AND 关系)
selector:
  matchLabels:
    tier: frontend
    app: myapp
  # 必须同时满足 tier=frontend AND app=myapp

# matchExpressions:表达式匹配
selector:
  matchExpressions:
  - key: tier
    operator: In
    values:
    - frontend
    - backend
  # tier 必须是 In 列表中的值

  - key: environment
    operator: NotIn
    values:
    - dev
  # environment 不能是 dev

  - key: memory
    operator: Exists
  # 必须存在 memory 标签

  - key: gpu
    operator: DoesNotExist
  # 不能存在 gpu 标签

# 组合使用
selector:
  matchLabels:
    app: myapp
  matchExpressions:
  - key: tier
    operator: In
    values:
    - frontend
    - backend

Deployment:声明式应用管理

Deployment vs ReplicaSet

┌─────────────────────────────────────────────────────────────────┐
│                  Deployment 与 ReplicaSet 关系                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                     Deployment                          │   │
│   │                                                          │   │
│   │   ┌─────────────────────────────────────────────────┐   │   │
│   │   │         管理 ReplicaSet 的版本                   │   │   │
│   │   │                                                  │   │   │
│   │   │  Deployment-1.0  →  ReplicaSet-v1.0 (3 replicas)  │   │   │
│   │   │       ↓                                            │   │   │
│   │   │       │ (滚动更新)                                 │   │   │
│   │   │       ↓                                            │   │   │
│   │   │  Deployment-2.0  →  ReplicaSet-v2.0 (3 replicas)  │   │   │
│   │   │                                                  │   │   │
│   │   │  Deployment 历史版本(支持回滚)                    │   │   │
│   │   └─────────────────────────────────────────────────┘   │   │
│   │                                                          │   │
│   └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│   Deployment 提供的高级能力:                                     │
│   ✓ 滚动更新(Rolling Update)                                   │
│   ✓ 版本回滚(Rollback)                                        │
│   ✓ 暂停/恢复(Pause/Resume)                                   │
│   ✓ 状态扩缩容(Scale)                                         │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Deployment 基本定义

# deployment-example.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  # 期望副本数
  replicas: 3

  # Pod 选择器
  selector:
    matchLabels:
      app: nginx

  # 滚动更新策略
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1          # 最多超出期望副本数
      maxUnavailable: 0    # 不可用 Pod 最多数

  # Pod 模板
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

滚动更新策略

滚动更新原理

┌─────────────────────────────────────────────────────────────────┐
│                    滚动更新流程                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  初始状态:v1 版本 (3 Pods)                                     │
│                                                                 │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                        │
│  │ nginx   │  │ nginx   │  │ nginx   │                        │
│  │  v1.0   │  │  v1.0   │  │  v1.0   │                        │
│  └─────────┘  └─────────┘  └─────────┘                        │
│                                                                 │
│  更新过程:maxSurge=1, maxUnavailable=0                         │
│                                                                 │
│  步骤1:创建 1 个 v2.0 Pod                                      │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐           │
│  │ nginx   │  │ nginx   │  │ nginx   │  │ nginx   │           │
│  │  v1.0   │  │  v1.0   │  │  v1.0   │  │  v2.0   │ ← 新增    │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘           │
│                                                                 │
│  步骤2:新 Pod Ready 后,删除 1 个 v1.0 Pod                     │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐           │
│  │ nginx   │  │ nginx   │  │ nginx   │  │ nginx   │           │
│  │  v2.0   │  │  v2.0   │  │  v2.0   │  │  v1.0   │ ← 删除    │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘           │
│                                                                 │
│  ... 重复直到全部替换                                           │
│                                                                 │
│  最终状态:v2.0 版本 (3 Pods)                                   │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐                        │
│  │ nginx   │  │ nginx   │  │ nginx   │                        │
│  │  v2.0   │  │  v2.0   │  │  v2.0   │                        │
│  └─────────┘  └─────────┘  └─────────┘                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

策略参数详解

# RollingUpdate 参数配置

strategy:
  type: RollingUpdate

  # maxSurge: 滚动过程中最多超出 desired 的 Pod 数量
  # 可以是绝对数(如 1)或百分比(如 25%)
  rollingUpdate:
    maxSurge: 1              # 默认 25%
    # 推荐:生产环境使用较小值(如 25%)
    # 推荐:开发环境可以使用较大值(如 50%)

    # maxUnavailable: 滚动过程中最多不可用的 Pod 数量
    # 设置为 0 意味着不能有 Pod 不可用,保证服务连续性
    maxUnavailable: 0         # 默认 25%
    # 设置为 0 时,需要足够的资源支持 maxSurge

不同场景的策略选择

# 场景1:服务可用性优先(无停机)
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0
  # 特点:始终保持 100% 副本数,资源需求大

# 场景2:速度优先
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 50%
    maxUnavailable: 50%
  # 特点:快速完成,但有短暂服务降级

# 场景3:资源受限环境
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 1
  # 特点:平衡资源与速度

# 场景4:数据库升级(需要特殊处理)
# 注意:数据库直接滚动更新通常不可行,需要先更新只读副本

Deployment 管理命令

基本操作

# 创建 Deployment
kubectl apply -f deployment.yaml

# 查看 Deployment 状态
kubectl get deployment nginx-deployment

# 查看详细状态
kubectl describe deployment nginx-deployment

# 查看关联的 ReplicaSet
kubectl get rs -l app=nginx

# 查看 Pod
kubectl get pods -l app=nginx

扩缩容

# 命令行扩缩容(临时修改)
kubectl scale deployment nginx-deployment --replicas=5

# 自动扩缩容(HPA)
kubectl autoscale deployment nginx-deployment \
  --min=2 \
  --max=10 \
  --cpu-percent=80

# 滚动扩缩容(不影响服务)
# HPA 会逐步调整,避免服务中断

滚动更新

# 更新镜像
kubectl set image deployment/nginx-deployment \
  nginx=nginx:1.22

# 查看滚动状态
kubectl rollout status deployment/nginx-deployment

# 暂停滚动(可以在暂停期间做其他操作)
kubectl rollout pause deployment/nginx-deployment

# 恢复滚动
kubectl rollout resume deployment/nginx-deployment

回滚

# 查看历史版本
kubectl rollout history deployment/nginx-deployment

# 输出示例:
# deployments "nginx-deployment"
# REVISION  CHANGE-CAUSE
# 1         kubectl apply --filename=deployment.yaml
# 2         kubectl set image deployment/nginx-deployment nginx=nginx:1.21
# 3         kubectl set image deployment/nginx-deployment nginx=nginx:1.22

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

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=1

# 查看回滚状态
kubectl rollout status deployment/nginx-deployment

查看回滚详情

# 查看某个版本的详细信息
kubectl rollout history deployment/nginx-deployment --revision=2

# 输出示例:
# Deployment revision: 2
# Labels:    app=nginx
# Annotations: kubernetes.io/change-cause=kubectl set image ...
# Replicas:   3 desired | 3 updated | 1 available | 0 unavailable
# Pods Status:  2 running | 0 waiting | 0 stopped | 0 queued

版本管理机制

Revision 历史

┌─────────────────────────────────────────────────────────────────┐
│                    Deployment 版本历史                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Deployment 创建 (v1.0)                                         │
│         │                                                       │
│         ▼                                                       │
│  Revision 1: ReplicaSet-xxx-1                                   │
│         │                                                       │
│         │  更新镜像 (v1.1)                                       │
│         ▼                                                       │
│  Revision 2: ReplicaSet-xxx-2                                   │
│         │                                                       │
│         │  更新镜像 (v1.2)                                       │
│         ▼                                                       │
│  Revision 3: ReplicaSet-xxx-3 ← 当前                            │
│         │                                                       │
│         │  回滚到 Revision 1                                     │
│         ▼                                                       │
│  Revision 4: ReplicaSet-xxx-1 (复用原 RS)                        │
│         │                                                       │
│         ▼                                                       │
│  Revision 5: ReplicaSet-xxx-4                                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Revision 清理策略

# deployment-revision-history.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  # 保留的历史版本数量
  revisionHistoryLimit: 10  # 默认 10

  # 设置为 0 会禁用历史记录,无法回滚
  # 设置为 1 只保留最近版本

  # 清理说明:
  # - 每个历史版本对应一个 ReplicaSet
  # - 过多的历史版本会占用资源
  # - 生产环境建议保留 5-10 个版本

版本记录注解

# K8s 自动记录 change-cause
# 也可以手动指定
metadata:
  annotations:
    kubernetes.io/change-cause: |
      2024-05-19: Update nginx from 1.21 to 1.22
      Reason: Security patch CVE-2024-xxxx

# 使用 --record 记录命令
kubectl apply -f deployment.yaml --record
kubectl set image deployment/nginx nginx=nginx:1.22 --record

金丝雀发布

金丝雀发布原理

┌─────────────────────────────────────────────────────────────────┐
│                    金丝雀发布流程                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                    流量分发                              │   │
│   │                                                          │   │
│   │                    ┌─────────┐                          │   │
│   │                    │ Ingress │                          │   │
│   │                    └────┬────┘                          │   │
│   │                         │                               │   │
│   │              ┌──────────┴──────────┐                    │   │
│   │              │                     │                    │   │
│   │         90%  │                  10%  │                   │   │
│   │              ▼                     ▼                    │   │
│   │      ┌─────────────┐       ┌─────────────┐             │   │
│   │      │ Stable      │       │ Canary      │             │   │
│   │      │ v1.0 (9 Pod) │       │ v2.0 (1 Pod) │             │   │
│   │      │ 稳定版本     │       │ 金丝雀版本   │             │   │
│   │      └─────────────┘       └─────────────┘             │   │
│   │                                                          │   │
│   └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│   策略:先让少量用户使用新版本,观察无问题后逐步扩大             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

金丝雀发布实现方式

# 方式1:基于 ReplicaSet 的金丝雀(简单)
---
# 稳定版本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-stable
spec:
  replicas: 9
  selector:
    matchLabels:
      app: myapp
      version: stable
  template:
    metadata:
      labels:
        app: myapp
        version: stable
    spec:
      containers:
      - name: app
        image: myapp:v1.0

---
# 金丝雀版本
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
      version: canary
  template:
    metadata:
      labels:
        app: myapp
        version: canary
    spec:
      containers:
      - name: app
        image: myapp:v2.0
# 方式2:基于 Service 的金丝雀(精确控制)
---
# 金丝雀 Service(只选金丝雀版本)
apiVersion: v1
kind: Service
metadata:
  name: app-canary
spec:
  selector:
    version: canary
  ports:
  - port: 80

---
# 稳定 Service(选稳定版本 + 金丝雀)
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  # 通过多个 label 选择
  selector:
    app: myapp
  # 这会匹配 stable 和 canary 两个版本
  ports:
  - port: 80
# 方式3:基于 Ingress 的流量权重(金丝雀 + 灰度)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"
    # 或者使用 header/cookie 匹配
    # nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    # nginx.ingress.kubernetes.io/canary-by-header-value: "always"
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-canary
            port:
              number: 80

金丝雀发布最佳实践

# 金丝雀发布流程
# 1. 创建金丝雀 Deployment(少量副本)
kubectl apply -f canary-deployment.yaml

# 2. 验证金丝雀 Pod 正常运行
kubectl get pods -l version=canary

# 3. 监控金丝雀版本指标
# - 错误率
# - 延迟
# - 成功率

# 4. 逐步增加金丝雀副本
kubectl scale deployment app-canary --replicas=2

# 5. 观察指标无异常后,停止旧版本
kubectl delete deployment app-stable

# 6. 将金丝雀升级为稳定版本
kubectl patch deployment app-canary \
  -p '{"spec":{"template":{"metadata":{"labels":{"version":"stable"}}}}}'
kubectl rename deployment app-canary app

蓝绿部署

蓝绿部署原理

┌─────────────────────────────────────────────────────────────────┐
│                    蓝绿部署流程                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  阶段1:初始状态(蓝环境)                                       │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                        │   │
│  │   ┌───────────────────┐     ┌───────────────────┐      │   │
│  │   │      Blue         │     │      Green        │      │   │
│  │   │    (v1.0)         │     │    (v2.0 准备中)   │      │   │
│  │   │                   │     │                   │      │   │
│  │   │  Service → Blue  │     │   待激活           │      │   │
│  │   │  (活跃)          │     │                   │      │   │
│  │   └───────────────────┘     └───────────────────┘      │   │
│  │                                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  阶段2:部署新版本到绿色环境                                     │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                        │   │
│  │   ┌───────────────────┐     ┌───────────────────┐      │   │
│  │   │      Blue         │     │      Green        │      │   │
│  │   │    (v1.0)         │     │    (v2.0)         │      │   │
│  │   │                   │     │                   │      │   │
│  │   │  Service → Blue  │     │   独立测试        │      │   │
│  │   └───────────────────┘     └───────────────────┘      │   │
│  │                                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  阶段3:切换流量到绿色环境                                      │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │                                                        │   │
│  │   ┌───────────────────┐     ┌───────────────────┐      │   │
│  │   │      Blue         │     │      Green        │      │   │
│  │   │    (v1.0)         │     │    (v2.0)         │      │   │
│  │   │                   │     │                   │      │   │
│  │   │  待删除           │     │  Service → Green  │      │   │
│  │   │                   │     │  (活跃)          │      │   │
│  │   └───────────────────┘     └───────────────────┘      │   │
│  │                                                        │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  优点:瞬时切换,回滚简单                                      │
│  缺点:资源占用大                                              │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

蓝绿部署实现

# blue-green-deployment.yaml
---
# 蓝色环境(当前活跃)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
  labels:
    app: myapp
    color: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      color: blue
  template:
    metadata:
      labels:
        app: myapp
        color: blue
    spec:
      containers:
      - name: app
        image: myapp:v1.0

---
# 绿色环境(新版本)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-green
  labels:
    app: myapp
    color: green
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      color: green
  template:
    metadata:
      labels:
        app: myapp
        color: green
    spec:
      containers:
      - name: app
        image: myapp:v2.0

---
# 切换 Service 到绿色
apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: myapp
    color: green  # 切换 color 即可
  ports:
  - port: 80

蓝绿切换脚本

#!/bin/bash
# blue-green-switch.sh

# 当前颜色
CURRENT_COLOR="blue"
# 目标颜色
TARGET_COLOR="green"

# 1. 验证绿色环境
kubectl rollout status deployment/app-${TARGET_COLOR}
if [ $? -ne 0 ]; then
    echo "绿色环境部署失败"
    exit 1
fi

# 2. 执行切换
kubectl patch service app-service \
  -p "{\"spec\":{\"selector\":{\"app\":\"myapp\",\"color\":\"${TARGET_COLOR}\"}}}"

# 3. 验证切换
sleep 5
NEW_COLOR=$(kubectl get service app-service -o jsonpath='{.spec.selector.color}')
if [ "$NEW_COLOR" = "$TARGET_COLOR" ]; then
    echo "切换成功:${TARGET_COLOR}"
else
    echo "切换失败"
    exit 1
fi

# 4. 等待稳定后清理旧版本
sleep 60
kubectl delete deployment app-${CURRENT_COLOR}

echo "蓝绿部署完成"

多环境配置

环境变量隔离

# production-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-prod
spec:
  replicas: 5
  selector:
    matchLabels:
      app: myapp
      environment: production
  template:
    metadata:
      labels:
        app: myapp
        environment: production
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: ENV
          value: "production"
        - name: LOG_LEVEL
          value: "warn"
        - name: DB_HOST
          value: "prod-db.internal"
        - name: REDIS_HOST
          value: "prod-redis.internal"

---
# staging-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-staging
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp
      environment: staging
  template:
    metadata:
      labels:
        app: myapp
        environment: staging
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: ENV
          value: "staging"
        - name: LOG_LEVEL
          value: "debug"
        - name: DB_HOST
          value: "staging-db.internal"
        - name: REDIS_HOST
          value: "staging-redis.internal"

使用 ConfigMap 统一配置

# base-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_HOST: "db.internal"
  REDIS_HOST: "redis.internal"
  MAX_CONNECTIONS: "100"

---
# deployment-staging.yaml
spec:
  containers:
  - name: app
    env:
    - name: MAX_CONNECTIONS
      valueFrom:
        configMapKeyRef:
          name: app-config
          key: MAX_CONNECTIONS
    # 覆盖特定配置
    - name: DATABASE_HOST
      value: "staging-db.internal"

标签管理

# 推荐的标签方案
metadata:
  labels:
    app: myapp                    # 应用名称
    tier: frontend                # 层级(frontend/backend/db)
    environment: production       # 环境(prod/staging/dev)
    version: v1.2.3              # 版本号
    team: platform                # 负责团队
    managed-by: kubectl           # 管理方式

# 使用场景
kubectl get pods -l "app=myapp,environment=prod"
kubectl get deployment -l "team=platform"

常见问题与避坑指南

Q1:滚动更新卡住了?

# 排查步骤
kubectl get pods
# 查看是否有 Pod 一直处于 Terminating

# 原因分析
# 1. Pod 优雅终止时间过长
kubectl describe pod <name> | grep -A10 "Termination"
# 解决:增加 terminationGracePeriodSeconds

# 2. 镜像拉取失败
kubectl describe pod <name> | grep "ImagePull"
# 解决:检查镜像地址和凭证

# 3. 资源不足
kubectl describe node
# 解决:清理资源或增加节点

# 强制恢复
kubectl rollout undo deployment/<name>

Q2:如何避免滚动更新时的服务中断?

# 关键配置
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0    # 关键:不允许 Pod 不可用
      maxSurge: 1          # 允许临时超出副本数

  template:
    spec:
      containers:
      - name: app
        readinessProbe:    # 关键:配置就绪探针
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

Q3:Deployment 和 StatefulSet 该怎么选?

┌─────────────────────────────────────────────────────────────────┐
│                  Workload 类型选择指南                           │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Deployment                              StatefulSet            │
│  ├─────────────────────────────────┼────────────────────────┤   │
│  │ 无状态应用                       │ 有状态应用              │   │
│  │ 副本无序                            │ 副本有序(命名固定)    │   │
│  │ 可互换                             │ 有持久身份              │   │
│  │ 随意扩缩                            │ 需要稳定网络标识        │   │
│  │                                  │ 需要持久存储            │   │
│  ├─────────────────────────────────┼────────────────────────┤   │
│  │ 适用场景:                        │ 适用场景:              │   │
│  │ - Web 服务                       │ - 数据库               │   │
│  │ - API 服务                       │ - 消息队列             │   │
│  │ - 后台任务                       │ - Kafka/MongoDB        │   │
│  │ - 微服务                          │ - 有序部署/扩展         │   │
│  └─────────────────────────────────┴────────────────────────┘   │
│                                                                 │
│  DaemonSet:每个节点一个 Pod(日志收集、监控)                   │
│  Job/CronJob:批处理任务                                        │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Q4:如何优雅回滚?

# 检查当前状态
kubectl rollout status deployment/myapp

# 查看历史
kubectl rollout history deployment/myapp

# 确认回滚目标
kubectl rollout history deployment/myapp --revision=3

# 执行回滚
kubectl rollout undo deployment/myapp --to-revision=3

# 监控回滚
kubectl rollout status deployment/myapp

# 验证
kubectl get pods -l app=myapp
kubectl logs deployment/myapp-xxx -f

总结

┌─────────────────────────────────────────────────────────────────┐
│                    核心要点回顾                                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ReplicaSet                                                   │
│  ├── 副本控制器,保证 Pod 数量                                 │
│  ├── selector 匹配 Pod                                        │
│  └── 通常不单独使用,由 Deployment 管理                        │
│                                                                 │
│  Deployment                                                   │
│  ├── 声明式管理应用                                           │
│  ├── 管理多个 RS 版本历史                                     │
│  ├── 支持滚动更新、回滚、暂停                                 │
│  └── 多环境配置灵活                                           │
│                                                                 │
│  滚动更新策略                                                 │
│  ├── maxSurge:超出副本数                                     │
│  ├── maxUnavailable:不可用副本数                             │
│  └── 合理配置保证服务连续性                                   │
│                                                                 │
│  发布模式                                                     │
│  ├── 金丝雀:小流量验证新版本                                 │
│  ├── 蓝绿:双环境快速切换                                     │
│  └── A/B 测试:按用户特征分流                                 │
│                                                                 │
│  多环境管理                                                   │
│  ├── 标签隔离环境                                             │
│  ├── ConfigMap 统一配置                                       │
│  └── 环境变量覆盖                                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

思考题

  1. maxUnavailable 设置为 0 且 maxSurge 设置为 1,与设置 maxUnavailable=1 有何区别?
  2. 为什么 Deployment 管理多个 ReplicaSet 而不是直接更新同一个 ReplicaSet?
  3. 金丝雀发布中,如何设计合理的指标来评估新版本是否可用?

引用与参考

  1. Deployments
  2. ReplicaSet
  3. Rolling Back a Deployment
  4. Kubernetes Deployment Strategies

下篇预告

下一篇文章我们将探讨 Service 与网络模型,包括:

  • ClusterIP / NodePort / LoadBalancer / Ingress
  • Service 发现机制
  • 网络策略与隔离
  • Ingress 控制器配置

敬请期待!