一、Deployment 简介

1.1 什么是 Deployment

Deployment 是 Kubernetes 提供的一种声明式控制器,用于管理 Pod 的部署和更新。它基于 ReplicaSet 实现,提供了应用版本的定义、回滚机制以及滚动更新策略。

plaintext

┌─────────────────────────────────────────────────────────────────────┐
│                         Deployment                                   │
│  ┌───────────────────┐     ┌───────────────────┐                     │
│  │    Deployment     │────▶│    ReplicaSet     │                    │
│  │  (声明式定义)      │     │  (副本管理)        │                    │
│  └───────────────────┘     └─────────┬─────────┘                     │
│                                      │                               │
│                          ┌───────────┼───────────┐                   │
│                          ▼           ▼           ▼                   │
│                      ┌───────┐   ┌───────┐   ┌───────┐               │
│                      │  Pod  │   │  Pod  │   │  Pod  │               │
│                      └───────┘   └───────┘   └───────┘               │
└─────────────────────────────────────────────────────────────────────┘

1.2 Deployment 的核心作用

功能说明
副本管理确保指定数量的 Pod 副本持续运行
滚动更新自动化执行应用的零宕机更新
版本回滚支持回退到历史的稳定版本
弹性伸缩手动或自动调整副本数量
声明式配置声明期望状态,控制器自动调谐

1.3 与其他控制器的对比

Kubernetes 提供了多种工作负载控制器,它们各有适用场景:

plaintext

┌──────────────────────────────────────────────────────────────────────┐
│                        Kubernetes Workload Controllers                │
├──────────────────────────────────────────────────────────────────────┤
│                                                                       │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐             │
│   │  Deployment │    │    ReplicaSet    │    StatefulSet    │       │
│   ├─────────────┤    ├─────────────┤    ├─────────────┤             │
│   │ • 无状态应用  │    │ • 底层副本管理 │    │ • 有状态应用  │             │
│   │ • Web 服务   │    │ • 很少直接使用 │    │ • 数据库      │             │
│   │ • API 服务   │    │ • Deployment   │    │ • 消息队列    │             │
│   │             │    │   的底层实现    │    │ • 持久化存储  │             │
│   └─────────────┘    └─────────────┘    └─────────────┘             │
│          │                  │                     │                  │
│          ▼                  ▼                     ▼                  │
│   ┌─────────────┐    ┌─────────────┐    ┌─────────────┐             │
│   │  DaemonSet  │    │    Job      │    │  CronJob    │             │
│   ├─────────────┤    ├─────────────┤    ├─────────────┤             │
│   │ • 守护进程    │    │ • 一次性任务  │    │ • 定时任务    │             │
│   │ • 日志收集   │    │ • 数据迁移   │    │ • 备份任务    │             │
│   │ • 监控代理   │    │ • 批处理作业  │    │ • 报表生成    │             │
│   └─────────────┘    └─────────────┘    └─────────────┘             │
│                                                                       │
└──────────────────────────────────────────────────────────────────────┘

核心区别:

控制器Pod 标识启动顺序存储典型场景
Deployment无序、随机并行共享/无持久化Web 服务、API
ReplicaSet无序、随机并行共享/无持久化很少直接使用
StatefulSet固定标识有序独立持久化MySQL、Kafka
DaemonSet固定节点每节点一个本地/无持久化日志、监控
Job无标识并行/有序无数据迁移、批处理

二、核心概念详解

2.1 Pod 模板(Pod Template)

Pod 模板是 Deployment 的核心组成部分,定义了 Pod 的规格:

yaml

spec:
  template:
    metadata:
      labels:
        app: my-app
        version: v1
    spec:
      containers:
      - name: my-container
        image: nginx:1.25
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: "256Mi"
            cpu: "500m"
          requests:
            memory: "128Mi"
            cpu: "100m"
        livenessProbe:
          httpGet:
            path: /healthz
            port: 80
          initialDelaySeconds: 3
          periodSeconds: 10

重要:Deployment 下的 Pod 模板与 Pod 本身的 metadata 独立。Deployment 会为 ReplicaSet 生成标签以实现关联。

2.2 副本数(Replicas)

副本数定义了期望运行的 Pod 数量:

yaml

spec:
  replicas: 3    # 期望 3 个 Pod 副本

副本数的语义:

plaintext

                    ┌─────────────────────────────────────┐
                    │         Deployment (replicas: 3)      │
                    │                                        │
desired replicas ───▶│   [Pod-1]  [Pod-2]  [Pod-3]          │◀─── ready: 3
                    │                                        │
                    └─────────────────────────────────────┘
                                │
                                ▼
                    ┌─────────────────────────────────────┐
                    │           控制器调谐逻辑              │
                    │                                        │
                    │  期望数 (3) vs 实际数 (2)             │
                    │        ↓                              │
                    │  差距 = 1,创建新 Pod                 │
                    └─────────────────────────────────────┘

2.3 选择器(Selector)

Selector 是 Deployment 连接 ReplicaSet 和 Pod 的桥梁:

yaml

spec:
  selector:
    matchLabels:
      app: my-app

工作原理:

plaintext

┌─────────────────────────────────────────────────────────────────────┐
│                        Selector 匹配关系                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                       │
│  Deployment.spec.selector        →    ReplicaSet.spec.selector      │
│  ┌─────────────────────┐              ┌─────────────────────┐        │
│  │  matchLabels:       │              │  matchLabels:       │        │
│  │    app: my-app      │────────────▶│    app: my-app      │        │
│  └─────────────────────┘              └──────────┬──────────┘      │
│                                                    │                  │
│                                                    ▼                  │
│                                        Pod.spec.metadata.labels      │
│                                        ┌─────────────────────┐       │
│                                        │  labels:            │       │
│                                        │    app: my-app      │       │
│                                        │    version: v1      │       │
│                                        └─────────────────────┘       │
│                                                                       │
│  ⚠️  注意:Pod 标签必须包含 selector 匹配的所有标签                    │
│     Pod 可以有额外的标签,但 selector 必须完全匹配                      │
└─────────────────────────────────────────────────────────────────────┘

⚠️ 注意事项:

  • Selector 是不可变的,创建后不能修改(除非使用 matchExpressions 且在特定版本支持)
  • Pod 模板中的标签必须匹配 Selector
  • 避免与同命名空间下其他 Deployment 的标签重叠

2.4 策略类型(strategy)

Deployment 支持两种更新策略:

2.4.1 RollingUpdate(滚动更新)

yaml

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1           # 最大超过副本数
      maxUnavailable: 0     # 最大不可用副本数

参数详解:

参数类型说明示例值
maxSurgeint/percentage更新过程中最多超出期望副本数1 或 25%
maxUnavailableint/percentage更新过程中最多不可用副本数0 或 25%

滚动更新示意图:

plaintext

初始状态: 3 个 Pod (v1)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Step 1: 启动 1 个新 Pod (v2)
      maxSurge=1
      ┌─────────────────────────────────────────────────────────────┐
      │  [Pod-v1] [Pod-v1] [Pod-v1]  →  [Pod-v2]                   │
      │                                     ↑                       │
      │                                     新启动                  │
      └─────────────────────────────────────────────────────────────┘

Step 2: 终止 1 个旧 Pod (v1)
      maxUnavailable=0, 所以先增后减
      ┌─────────────────────────────────────────────────────────────┐
      │  [Pod-v1] [Pod-v1] [Pod-v2]                                │
      │       ↓                                                   │
      │    终止 1 个                                               │
      └─────────────────────────────────────────────────────────────┘

Step 3-4: 重复 Step 1-2
      ┌─────────────────────────────────────────────────────────────┐
      │  [Pod-v1] [Pod-v2] [Pod-v2]  →  [Pod-v1] [Pod-v2] [Pod-v2]  │
      │       ↓                    替换        ↓                   │
      │    终止旧                    完成      终止旧                │
      └─────────────────────────────────────────────────────────────┘

最终状态: 3 个 Pod (v2)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

2.4.2 Recreate(重建)

yaml

spec:
  strategy:
    type: Recreate

重建策略示意图:

plaintext

┌─────────────────────────────────────────────────────────────────────┐
│                      Recreate 策略执行流程                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   时间线 ──────────────────────────────────────────────────────▶    │
│                                                                      │
│   阶段1: 终止所有旧 Pod                                              │
│   ┌──────────────────────────────────────────────────────────────┐  │
│   │  [Pod-v1] [Pod-v1] [Pod-v1]  ──X──X──X──▶  (空)               │  │
│   │      ✗       ✗       ✗                                          │  │
│   └──────────────────────────────────────────────────────────────┘  │
│                              │                                       │
│                              │ (等待所有 Pod 真正终止)                │
│                              ▼                                       │
│   阶段2: 创建所有新 Pod                                              │
│   ┌──────────────────────────────────────────────────────────────┐  │
│   │  (空)  ──▶  [Pod-v2] [Pod-v2] [Pod-v2]                       │  │
│   │                     + + +                                    │  │
│   └──────────────────────────────────────────────────────────────┘  │
│                                                                      │
│   ⚠️ 注意: 存在服务中断窗口                                          │
└─────────────────────────────────────────────────────────────────────┘

策略选择建议:

策略适用场景优点缺点
RollingUpdate大多数生产环境零宕机、平滑过渡更新时间长、资源占用高
Recreate无法容忍旧新版本共存简单、资源占用低有服务中断窗口

三、工作原理深度剖析

3.1 控制器架构

Deployment 控制器是 Kubernetes 控制平面的一部分:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                          Kubernetes Control Plane                            │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│    ┌────────────────────────────────────────────────────────────────────┐   │
│    │                        API Server (6443)                           │   │
│    │  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐           │   │
│    │  │ REST API │  │  Auth N  │  │  Validat │  │  Mutate  │           │   │
│    │  └──────────┘  └──────────┘  └──────────┘  └──────────┘           │   │
│    └────────────────────────────────────────────────────────────────────┘   │
│                                    │                                         │
│                                    │ Watch/List                             │
│                                    ▼                                         │
│    ┌────────────────────────────────────────────────────────────────────┐   │
│    │                        etcd (数据存储)                              │   │
│    │  ┌──────────┐  ┌──────────┐  ┌──────────┐                         │   │
│    │  │Deployments│  │ReplicaSets│  │   Pods   │                         │   │
│    │  └──────────┘  └──────────┘  └──────────┘                         │   │
│    └────────────────────────────────────────────────────────────────────┘   │
│                                    ▲                                         │
│                                    │                                         │
│    ┌────────────────────────────────────────────────────────────────────┐   │
│    │                     Controller Manager                             │   │
│    │  ┌────────────────────┐  ┌────────────────────┐                   │   │
│    │  │ Deployment Controller│  │ ReplicaSet Controller│                 │   │
│    │  │  • 创建/更新 ReplicaSet│  │  • 管理 Pod 副本    │                   │   │
│    │  │  • 管理版本历史      │  │  • 处理 Pod 故障    │                   │   │
│    │  └────────────────────┘  └────────────────────┘                   │   │
│    │  ┌────────────────────┐  ┌────────────────────┐                   │   │
│    │  │    Node Controller │  │  Resource Controller│                  │   │
│    │  │  • 节点健康检测     │  │  • HPA 扩缩容       │                   │   │
│    │  └────────────────────┘  └────────────────────┘                   │   │
│    └────────────────────────────────────────────────────────────────────┘   │
│                                    │                                         │
└────────────────────────────────────│────────────────────────────────────────┘
                                     │
                                     │ 调度与通信
        ┌────────────────────────────┼────────────────────────────┐
        ▼                            ▼                            ▼
┌───────────────┐          ┌───────────────┐          ┌───────────────┐
│   Node 1      │          │   Node 2      │          │   Node 3      │
│ ┌───────────┐ │          │ ┌───────────┐ │          │ ┌───────────┐ │
│ │  kubelet  │ │          │ │  kubelet  │ │          │ │  kubelet  │ │
│ │    ↓      │ │          │ │    ↓      │ │          │ │    ↓      │ │
│ │  Pod 运行 │ │          │ │  Pod 运行 │ │          │ │  Pod 运行 │ │
│ └───────────┘ │          │ └───────────┘ │          │ └───────────┘ │
└───────────────┘          └───────────────┘          └───────────────┘

3.2 创建流程

Deployment 创建时的资源生成链:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                        Deployment 创建流程                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  用户操作                                                                    │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │  kubectl apply -f deployment.yaml                                   │    │
│  │  或: kubectl create deployment my-app --image=nginx:latest           │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                         API Server                                    │    │
│  │  1. 认证 & 授权                                                       │    │
│  │  2. 验证 YAML 合法性                                                  │    │
│  │  3. 写入 etcd (Deployment 对象)                                       │    │
│  │  4. 返回 success 给客户端                                             │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    │ Deployment Controller 监听到新对象      │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                    Deployment Controller                              │    │
│  │                                                                        │    │
│  │  1. 创建 ReplicaSet (初始版本 revision=1)                            │    │
│  │  ┌──────────────────────────────────────────────────────────────┐     │    │
│  │  │  ReplicaSet Spec:                                             │     │    │
│  │  │    replicas: 3                                                │     │    │
│  │  │    selector: {app: my-app}                                   │     │    │
│  │  │    template: {Pod 模板内容}                                   │     │    │
│  │  └──────────────────────────────────────────────────────────────┘     │    │
│  │                                                                        │    │
│  │  2. 记录版本历史 (deployment.kubernetes.io/revision-history)          │    │
│  │  3. 设置注解 (deployment.kubernetes.io/revision: "1")                 │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    │ ReplicaSet Controller 监听到新对象      │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                      ReplicaSet Controller                            │    │
│  │                                                                        │    │
│  │  计算: desired(3) - current(0) = 需要创建 3 个 Pod                     │    │
│  │                                                                        │    │
│  │  调用 Scheduler                                                      │    │
│  │  ┌──────────────────────────────────────────────────────────────┐     │    │
│  │  │  调度决策:                                                     │     │    │
│  │  │    Pod-1 → Node-1 (资源充足)                                  │     │    │
│  │  │    Pod-2 → Node-2 (资源充足)                                  │     │    │
│  │  │    Pod-3 → Node-3 (资源充足)                                  │     │    │
│  │  └──────────────────────────────────────────────────────────────┘     │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    │ kubelet 在各节点上创建 Pod              │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                           kubelet                                     │    │
│  │                                                                        │    │
│  │  1. 从容器运行时拉取镜像                                              │    │
│  │  2. 创建容器 (Pause 容器 + 业务容器)                                   │    │
│  │  3. 配置网络 (CNI 插件)                                               │    │
│  │  4. 启动并监控容器                                                     │    │
│  │  5. 汇报状态给 API Server                                             │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│                           Pod Running ✓                                     │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

3.3 更新流程(滚动更新机制)

Deployment 更新时的滚动升级流程:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                        滚动更新详细流程                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  假设: replicas=3, maxSurge=1, maxUnavailable=0                              │
│  初始: 3 个 v1 Pod                                                          │
│  更新: 镜像从 nginx:1.21 → nginx:1.25                                       │
│                                                                              │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                       Deployment 更新                                 │    │
│  │                                                                        │    │
│  │  触发方式:                                                            │    │
│  │    • kubectl apply -f deployment.yaml                               │    │
│  │    • kubectl set image deployment/my-app nginx=nginx:1.25          │    │
│  │    • kubectl edit deployment my-app                                 │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                  Deployment Controller 处理                            │    │
│  │                                                                        │    │
│  │  1. 创建新的 ReplicaSet (revision=2)                                  │    │
│  │     - 副本数: maxSurge (1)                                            │    │
│  │                                                                        │    │
│  │  2. 更新旧 ReplicaSet (revision=1)                                    │    │
│  │     - 副本数: 逐步减少                                                  │    │
│  │                                                                        │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
└────────────────────────────────────│────────────────────────────────────────┘
                                     │
                                     ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                           滚动更新进度可视化                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  状态    │  Node-1       │  Node-2       │  Node-3       │ 说明             │
│  ────────┼───────────────┼───────────────┼───────────────┼────────────────  │
│          │               │               │               │                  │
│  初始    │  [Pod-v1]     │  [Pod-v1]     │  [Pod-v1]     │ 3 个 v1 Pod      │
│          │               │               │               │                  │
│  Step 1  │  [Pod-v1]     │  [Pod-v1]     │  [Pod-v1]     │ 新 RS 启动 1 个  │
│          │               │               │  [Pod-v2]  NEW│ v2 Pod (maxSurge)│
│          │               │               │               │                  │
│  Step 2  │  [Pod-v1]     │  [Pod-v1]     │  [Pod-v2]     │ 终止 1 个 v1     │
│          │      ✗        │               │               │ (maxUnavailable=0)│
│          │               │               │               │                  │
│  Step 3  │  [Pod-v1]     │  [Pod-v2] NEW │  [Pod-v2]     │ 新 RS 再启动 1 个│
│          │               │               │               │                  │
│  Step 4  │  [Pod-v1]     │  [Pod-v2]     │  [Pod-v2]     │ 再终止 1 个 v1   │
│          │      ✗        │               │               │                  │
│  Step 5  │  [Pod-v2] NEW │  [Pod-v2]     │  [Pod-v2]     │ 最后 1 个 v2     │
│          │               │               │               │                  │
│  Step 6  │  [Pod-v2]     │  [Pod-v2]     │  [Pod-v2]     │ 最后 1 个 v1 终止 │
│          │               │      ✗        │               │                  │
│          │               │               │               │                  │
│  完成    │  [Pod-v2]     │  [Pod-v2]     │  [Pod-v2]     │ 全 v2 ✓           │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

3.4 回滚机制

Deployment 自动保存历史版本,支持快速回退:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                           回滚机制原理                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  回滚命令:                                                                  │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │  # 回滚到上一个版本                                                   │    │
│  │  kubectl rollout undo deployment/my-app                              │    │
│  │                                                                        │    │
│  │  # 回滚到指定版本                                                     │    │
│  │  kubectl rollout undo deployment/my-app --to-revision=2             │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                    版本历史管理                                        │    │
│  │                                                                        │    │
│  │  Deployment 注解中的版本信息:                                          │    │
│  │  ┌──────────────────────────────────────────────────────────────┐     │    │
│  │  │  kubernetes.io/change-cause: "Update image nginx to 1.25"  │     │    │
│  │  │  deployment.kubernetes.io/revision: "3"                     │     │    │
│  │  └──────────────────────────────────────────────────────────────┘     │    │
│  │                                                                        │    │
│  │  保留的 ReplicaSet 历史 (通过 revisionHistoryLimit 控制):             │    │
│  │  ┌─────────────┐ ┌─────────────┐ ┌─────────────┐                     │    │
│  │  │  RS (v1)    │ │  RS (v2)    │ │  RS (v3)    │  ← 当前活跃         │    │
│  │  │  revision=1 │ │  revision=2 │ │  revision=3 │                     │    │
│  │  │  replicas=0 │ │  replicas=0 │ │  replicas=3 │                     │    │
│  │  └─────────────┘ └─────────────┘ └─────────────┘                     │    │
│  │                                                                        │    │
│  │  revisionHistoryLimit=10 (默认保留 10 个历史版本)                     │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │                    回滚执行过程                                        │    │
│  │                                                                        │    │
│  │  1. 将目标 ReplicaSet 的副本数调整为期望值                             │    │
│  │  2. 将当前 ReplicaSet 的副本数调整为 0                                 │    │
│  │  3. 更新 Deployment 的 revision 注解                                  │    │
│  │  4. 生成新的 rollout 历史记录                                         │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

四、YAML 配置详解

4.1 完整配置示例

yaml

apiVersion: apps/v1                    # API 版本
kind: Deployment                       # 资源类型
metadata:
  name: my-nginx                        # Deployment 名称
  namespace: default                    # 所属命名空间
  labels:                               # Deployment 标签
    app: my-nginx
    tier: frontend
  annotations:                          # 注解
    description: "Nginx web server deployment"
    kubernetes.io/change-cause: "Initialize deployment"
spec:
  replicas: 3                           # 副本数
  
  selector:                             # Pod 选择器(必须匹配 Pod 标签)
    matchLabels:
      app: my-nginx
  
  strategy:                             # 更新策略
    type: RollingUpdate                 # 滚动更新
    rollingUpdate:
      maxSurge: 1                       # 最多超出副本数
      maxUnavailable: 0                 # 最多不可用副本数
  
  minReadySeconds: 10                   # Pod 就绪后最少保持时间
  
  revisionHistoryLimit: 10              # 保留的历史版本数
  
  paused: false                         # 是否暂停更新
  
  progressDeadlineSeconds: 600         # 进度超时时间
  
  template:                             # Pod 模板
    metadata:
      labels:
        app: my-nginx                   # 必须包含 selector 匹配的所有标签
        version: v1
    spec:
      # 容器配置
      containers:
      - name: nginx
        image: nginx:1.25-alpine
        imagePullPolicy: IfNotPresent   # 镜像拉取策略
        ports:
        - name: http
          containerPort: 80
          protocol: TCP
        - name: https
          containerPort: 443
          protocol: TCP
        
        # 资源管理
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "500m"
        
        # 健康检查
        livenessProbe:
          httpGet:
            path: /healthz
            port: http
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 5
          successThreshold: 1
          failureThreshold: 3
        
        # 启动探针(K8s 1.16+)
        startupProbe:
          httpGet:
            path: /healthz
            port: http
          failureThreshold: 30
          periodSeconds: 10
        
        # 环境变量
        env:
        - name: APP_ENV
          value: "production"
        - name: LOG_LEVEL
          value: "info"
        
        # 配置挂载
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/conf.d
          readOnly: true
        - name: nginx-cache
          mountPath: /var/cache/nginx
        - name: nginx-run
          mountPath: /var/run
      
      # 初始化容器(如需要)
      initContainers:
      - name: init-myservice
        image: busybox:1.36
        command: ['sh', '-c', 'echo Waiting for service; sleep 5']
      
      # 亲和性配置
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: my-nginx
              topologyKey: kubernetes.io/hostname
      
      # 容忍污点
      tolerations:
      - key: "node-role"
        operator: "Equal"
        value: "web"
        effect: "NoSchedule"
      
      # 安全上下文
      securityContext:
        runAsNonRoot: true
        runAsUser: 101
        fsGroup: 101
      
      # 镜像拉取凭证
      imagePullSecrets:
      - name: my-registry-secret
  
  # 共享存储卷
  volumes:
  - name: nginx-config
    configMap:
      name: nginx-config
      items:
      - key: default.conf
        path: default.conf
  - name: nginx-cache
    emptyDir:
      sizeLimit: "100Mi"
  - name: nginx-run
    emptyDir: {}

4.2 各字段含义说明

字段路径类型必填说明
apiVersionstring是API 版本,固定为 apps/v1
kindstring是资源类型,固定为 Deployment
metadata.namestring是Deployment 名称,命名空间内唯一
metadata.namespacestring否所属命名空间,默认 default
metadata.labelsmap否Deployment 的标签
metadata.annotationsmap否注解信息
spec.replicasinteger否期望副本数,默认 1
spec.selectorobject是Pod 选择器,定义如何识别管理的 Pod
spec.selector.matchLabelsmap是标签匹配规则
spec.selector.matchExpressionslist否表达式匹配(可选)
spec.strategy.typestring否更新策略:RollingUpdate 或 Recreate
spec.strategy.rollingUpdate.maxSurgeint/string否滚动更新时最多超出副本数
spec.strategy.rollingUpdate.maxUnavailableint/string否滚动更新时最多不可用副本数
spec.minReadySecondsinteger否Pod 就绪后最少保持时间
spec.revisionHistoryLimitinteger否保留的历史版本数,默认 10
spec.pausedboolean否是否暂停更新
spec.progressDeadlineSecondsinteger否进度超时时间(秒)
spec.templateobject是Pod 模板规格
spec.template.metadataobject是Pod 元数据
spec.template.specobject是Pod 规格定义

4.3 常用配置模式

4.3.1 基础 Web 服务

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-service
  template:
    metadata:
      labels:
        app: web-service
    spec:
      containers:
      - name: web
        image: nginx:1.25-alpine
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: "64Mi"
            cpu: "50m"
          limits:
            memory: "128Mi"
            cpu: "200m"

4.3.2 高可用多副本服务

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ha-service
spec:
  replicas: 5
  selector:
    matchLabels:
      app: ha-service
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: ha-service
    spec:
      affinity:
        # Pod 反亲和,确保副本分布在不同节点
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchLabels:
                app: ha-service
            topologyKey: kubernetes.io/hostname
      containers:
      - name: service
        image: myapp:v2.0
        ports:
        - containerPort: 8080

4.3.3 配置健康检查的服务

yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-with-probes
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app-with-probes
  template:
    metadata:
      labels:
        app: app-with-probes
    spec:
      containers:
      - name: app
        image: myapp:v1.0
        ports:
        - containerPort: 8080
        
        # 启动探针(容器启动期间使用)
        startupProbe:
          httpGet:
            path: /startup
            port: 8080
          failureThreshold: 30
          periodSeconds: 10
        
        # 存活探针(检测容器是否存活)
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
          timeoutSeconds: 3
          failureThreshold: 3
        
        # 就绪探针(检测是否可以接收流量)
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
          timeoutSeconds: 3
          failureThreshold: 3
          successThreshold: 1

五、常用操作指南

5.1 创建与删除

bash

# 创建 Deployment
kubectl apply -f deployment.yaml

# 或使用命令创建
kubectl create deployment my-app --image=nginx:latest --replicas=3

# 查看创建状态
kubectl get deployment my-app
kubectl rollout status deployment/my-app

# 删除 Deployment(会同时删除关联的 ReplicaSet 和 Pod)
kubectl delete deployment my-app

# 强制删除(如果卡住)
kubectl delete deployment my-app --grace-period=0 --force

# 删除并等待完成
kubectl delete deployment my-app --wait=true

5.2 扩缩容

5.2.1 手动扩缩容

bash

# 扩容到 5 个副本
kubectl scale deployment my-app --replicas=5

# 缩容到 1 个副本
kubectl scale deployment my-app --replicas=1

# 扩缩容多个 Deployment
kubectl scale deployment app1,app2,app3 --replicas=3

# 条件扩缩容(仅当副本数满足条件时才执行)
kubectl scale deployment my-app --current-replicas=3 --replicas=5

5.2.2 HPA 自动扩缩容

bash

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

# 查看 HPA
kubectl get hpa

# 删除 HPA
kubectl delete hpa my-app

HPA 配合 Deployment 示例:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                           HPA + Deployment 联动                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│    ┌───────────────┐                                                         │
│    │     HPA       │                                                         │
│    │  min=2        │                                                         │
│    │  max=10       │                                                         │
│    │  target=80%   │                                                         │
│    └───────┬───────┘                                                         │
│            │                                                                  │
│            │ 动态调整 replicas                                                │
│            ▼                                                                  │
│    ┌────────────────────────────────────────────────────────────────────┐    │
│    │                      Deployment Controller                          │    │
│    │                                                                        │    │
│    │   CPU 使用率 ──▶ 高 ──────────▶ replicas: 2 → 3 → 5 → 8 → 10     │    │
│    │   CPU 使用率 ──▶ 低 ──────────▶ replicas: 10 → 8 → 5 → 3 → 2      │    │
│    │                                                                        │    │
│    └────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│   扩缩容触发条件:                                                            │
│   • 当前 CPU 使用率 > targetCPUUtilizationPercentage → 扩容                 │
│   • 当前 CPU 使用率 < targetCPUUtilizationPercentage → 缩容                 │
│   • 冷却时间: 5 分钟(扩容)、5 分钟(缩容)                                │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

5.3 更新策略配置

bash

# 查看当前更新策略
kubectl get deployment my-app -o jsonpath='{.spec.strategy}'

# 修改更新策略(立即生效)
kubectl patch deployment my-app -p '{"spec":{"strategy":{"type":"RollingUpdate","rollingUpdate":{"maxSurge":2,"maxUnavailable":1}}}}'

# 或使用 edit
kubectl edit deployment my-app

常见策略配置组合:

场景maxSurgemaxUnavailable说明
保守更新10逐个替换,最安全
快速更新21平衡速度和安全性
激进更新31快速但资源占用高
最大效率25%25%按百分比计算

5.4 版本回滚

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 status deployment/my-app

5.5 暂停与恢复更新

bash

# 暂停更新(用于批量修改)
kubectl rollout pause deployment/my-app

# 执行多次修改(不会触发滚动更新)
kubectl set image deployment/my-app nginx=nginx:1.24
kubectl set resources deployment/my-app --limits=cpu=500m,memory=256Mi
kubectl label deployment/my-app version=v2

# 查看暂停状态
kubectl get deployment my-app -o jsonpath='{.spec.paused}' # true 表示暂停

# 恢复更新(触发滚动更新)
kubectl rollout resume deployment/my-app

# ⚠️ 注意事项:恢复时会一次性应用所有暂停期间的变更

暂停/恢复流程:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                      暂停与恢复更新流程                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  Step 1: 暂停                                                               │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │  kubectl rollout pause deployment/my-app                             │    │
│  │                                                                       │    │
│  │  结果: spec.paused = true                                            │    │
│  │        Controller 停止监听 Deployment 变更                          │    │
│  │        ReplicaSet 保持不变                                           │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  Step 2: 多次修改(不触发滚动更新)                                          │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │  kubectl set image deployment/my-app nginx=nginx:1.24              │    │
│  │  kubectl set image deployment/my-app nginx=nginx:1.25              │    │
│  │  kubectl set image deployment/my-app nginx=nginx:1.26              │    │
│  │                                                                       │    │
│  │  Deployment spec 已更新,但 ReplicaSet 不受影响                      │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  Step 3: 恢复(一次性应用所有变更)                                          │
│  ┌──────────────────────────────────────────────────────────────────────┐    │
│  │  kubectl rollout resume deployment/my-app                           │    │
│  │                                                                       │    │
│  │  Controller 检测到 paused=false                                     │    │
│  │  发现 spec 与当前 ReplicaSet 不同                                    │    │
│  │  创建新 ReplicaSet 并触发一次滚动更新                                │    │
│  │  (应用的是最后一次的镜像)                                           │    │
│  └──────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

5.6 其他常用命令

bash

# 获取 Deployment 详情
kubectl describe deployment my-app

# 查看 Pod 分布
kubectl get pods -l app=my-app -o wide

# 查看 Deployment 事件
kubectl get events --field-selector involvedObject.name=my-app

# 导出 YAML
kubectl get deployment my-app -o yaml > deployment-backup.yaml

# 应用部分更新(使用 patch)
kubectl patch deployment my-app -p '{"spec":{"replicas":5}}'

# 强制替换(删除后重建,用于不可修改字段)
kubectl replace --force -f deployment.yaml

六、高级特性

6.1 滚动更新参数详解

yaml

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      # maxSurge: 最大超出副本数
      # 形式: 整数 (如 1) 或 百分比 (如 25%)
      # 效果: 滚动更新期间,Pod 总数可以超过 replicas 数量
      maxSurge: 1                    # 或 "25%"
      
      # maxUnavailable: 最大不可用副本数
      # 形式: 整数 (如 1) 或 百分比 (如 25%)
      # 效果: 滚动更新期间,可以有最多这么多 Pod 不可用
      maxUnavailable: 0              # 或 "25%"
      
  # minReadySeconds: Pod 就绪后最少保持时间
  # Pod 必须持续运行这段时间才被认为可用
  minReadySeconds: 10
  
  # progressDeadlineSeconds: 进度超时时间
  # 如果在指定秒数内没有进度,Deployment 状态标记为 False
  progressDeadlineSeconds: 600

参数组合效果:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                    maxSurge 与 maxUnavailable 组合效果                       │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  replicas=3 时的 Pod 数量变化:                                               │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  配置组合              │  最大 Pod 数 │  最小可用 Pod │  更新速度    │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=0, maxUnav=0 │     ❌ 不可能(无意义)                       │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=1, maxUnav=0 │   3+1=4       │     3         │   慢        │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=0, maxUnav=1 │   3          │   3-1=2        │   慢        │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=1, maxUnav=1 │   3+1=4       │   3-1=2        │   中等     │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=25%, maxUnav=0│  ceil(3*1.25)=4│    3          │   慢        │     │
│  ├────────────────────────┼──────────────┼───────────────┼────────────  │     │
│  │  maxSurge=25%, maxUnav=25%│ ceil(3*1.25)=4│ ceil(3*0.75)=3│  中等      │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  图示:                                                                       │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  maxSurge=1, maxUnav=0  (最安全,资源消耗大)                         │     │
│  │  ┌────┬────┬────┬────┐                                              │     │
│  │  │ v1 │ v1 │ v1 │ v2 │ → ✗ → │ v2 │ v2 │ v2 │                       │     │
│  │  └────┴────┴────┴────┘        └────┴────┴────┘                      │     │
│  │  同时最多 4 个 Pod,v1 全部终止后 v2 才完全接管                       │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  maxSurge=1, maxUnav=1  (平衡模式)                                   │     │
│  │  ┌────┬────┬────┬────┐                                              │     │
│  │  │ v1 │ v1 │ v1 │ v2 │ → ✗ → │ v1 │ v2 │ v2 │ → ✗ → │ v2 │ v2 │ v2 │    │
│  │  └────┴────┴────┴────┘      └────┴────┴────┘       └────┴────┴────┘   │
│  │  同时最多 4 个 Pod,最少 2 个可用                                    │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

6.2 金丝雀发布

金丝雀发布允许将新版本逐步推向小部分用户:

yaml

# 1. 主版本 Deployment(v1,承载 95% 流量)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-stable
  labels:
    app: my-app
    track: stable
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      track: stable
  template:
    metadata:
      labels:
        app: my-app
        track: stable
    spec:
      containers:
      - name: my-app
        image: myapp:v1
        ports:
        - containerPort: 8080

---
# 2. 金丝雀 Deployment(v2,承载 5% 流量)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-canary
  labels:
    app: my-app
    track: canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      track: canary
  template:
    metadata:
      labels:
        app: my-app
        track: canary
    spec:
      containers:
      - name: my-app
        image: myapp:v2
        ports:
        - containerPort: 8080

---
# 3. Service 选择器(同时覆盖两个版本)
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  selector:
    app: my-app          # 匹配所有 track
  ports:
  - port: 80
    targetPort: 8080

金丝雀发布流量分配:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                         金丝雀发布架构                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│                           用户请求                                           │
│                               │                                               │
│                               ▼                                               │
│                    ┌────────────────────┐                                    │
│                    │      Service      │                                    │
│                    │   (selector: app)  │                                    │
│                    └─────────┬──────────┘                                    │
│                              │                                               │
│              ┌───────────────┴───────────────┐                               │
│              │                               │                               │
│              ▼                               ▼                               │
│    ┌─────────────────┐             ┌─────────────────┐                       │
│    │  Stable (v1)    │             │   Canary (v2)   │                       │
│    │  replicas: 3    │             │   replicas: 1    │                       │
│    │  track=stable   │             │   track=canary   │                       │
│    └────────┬────────┘             └────────┬────────┘                       │
│             │                               │                                │
│             ▼                               ▼                                │
│    ┌─────────────┐                 ┌─────────────┐                          │
│    │ Pod-1 v1 ✓  │                 │ Pod-4 v2 ✓  │                          │
│    │ Pod-2 v1 ✓  │                 └─────────────┘                          │
│    │ Pod-3 v1 ✓  │                                                     │
│    └─────────────┘                                                     │
│                                                                          │
│    流量比例: 75% ────────────→ Stable                                   │
│              25% ───→ Canary                                            │
│                                                                          │
│    提升金丝雀: replicas: 1 → 3 (50% 流量)                               │
│    完全发布: 合并配置,删除 canary deployment                           │
│    回滚: 删除 canary deployment                                         │
│                                                                          │
└─────────────────────────────────────────────────────────────────────────────┘

6.3 蓝绿部署

蓝绿部署通过两套完整环境实现即时切换:

yaml

# 蓝环境 Deployment(当前生产环境)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-blue
  labels:
    app: my-app
    env: blue
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
      env: blue
  template:
    metadata:
      labels:
        app: my-app
        env: blue
    spec:
      containers:
      - name: my-app
        image: myapp:v1
        ports:
        - containerPort: 8080

---
# 蓝环境 Service
apiVersion: v1
kind: Service
metadata:
  name: my-app-svc
spec:
  selector:
    app: my-app
    env: blue
  ports:
  - port: 80
    targetPort: 8080

蓝绿部署流程:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                         蓝绿部署流程                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  阶段 1: 初始状态(蓝环境为生产)                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  ┌─────────────┐                          ┌─────────────┐         │     │
│  │  │   蓝 v1      │ ◀── active              │   绿 v2      │         │     │
│  │  │ (生产环境)   │                          │ (预发布环境)  │         │     │
│  │  │ replicas=3  │                          │ replicas=3   │         │     │
│  │  └─────────────┘                          └─────────────┘         │     │
│  │          │                                        │                 │     │
│  │          └──────────────┬──────────────────────────┘                 │     │
│  │                         │                                             │     │
│  │                         ▼                                             │     │
│  │                ┌─────────────────┐                                    │     │
│  │                │     Service     │                                    │     │
│  │                │ selector: env=blue  ← 流量全部进入蓝环境             │     │
│  │                └─────────────────┘                                    │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  阶段 2: 部署绿环境                                                          │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  # 更新绿环境 Deployment                                               │     │
│  │  kubectl apply -f my-app-green.yaml                                 │     │
│  │                                                                        │     │
│  │  测试绿环境(直接访问)                                                 │     │
│  │  kubectl run test --image=curlimages/curl --rm -it --restart=Never   │     │
│  │    -- curl http://<green-pod-ip>:8080/health                         │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  阶段 3: 切换流量(蓝绿切换)                                                │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  # 修改 Service selector 切换到绿环境                                 │     │
│  │  kubectl patch service my-app-svc -p '{"spec":{"selector":{"env":"green"}}}'  │
│  │                                                                        │     │
│  │  ┌──────────────────────────────────────────────────────────────┐     │     │
│  │  │                Service selector: env=green                   │     │     │
│  │  │                     ↓ 流量切换                                 │     │     │
│  │  │          ┌─────────────┐                                      │     │     │
│  │  │          │   绿 v2      │ ◀── 新生产环境 (active)              │     │     │
│  │  │          └─────────────┘                                      │     │     │
│  │  │                ✗                                               │     │     │
│  │  │          ┌─────────────┐                                      │     │     │
│  │  │          │   蓝 v1      │ ← 旧环境 (standby)                  │     │     │
│  │  │          └─────────────┘                                      │     │     │
│  │  └──────────────────────────────────────────────────────────────┘     │     │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  阶段 4: 回滚(如需要)                                                      │
│  ┌─────────────────────────────────────────────────────────────────────┐     │
│  │  # 一键回滚到蓝环境                                                   │     │
│  │  kubectl patch service my-app-svc -p '{"spec":{"selector":{"env":"blue"}}}'  │
│  └─────────────────────────────────────────────────────────────────────┘     │
│                                                                              │
│  优点: 即时切换,零停机,支持快速回滚                                        │
│  缺点: 需要双倍资源                                                          │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

6.4 与 HPA/VPA 配合

6.4.1 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
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300    # 缩容冷却 5 分钟
      policies:
      - type: Percent
        value: 10
        periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 0      # 扩容立即执行
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15
      selectPolicy: Max

6.4.2 VPA(垂直自动扩缩容)

yaml

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: my-app-vpa
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  updatePolicy:
    updateMode: "Auto"                   # Auto 或 Off
  resourcePolicy:
    containerPolicies:
    - containerName: my-app
      minAllowed:
        cpu: 50m
        memory: 64Mi
      maxAllowed:
        cpu: 2
        memory: 1Gi
      controlledResources: ["cpu", "memory"]

6.4.3 HPA + VPA 结合

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                      HPA 与 VPA 结合使用                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│                           ┌──────────────────────┐                          │
│                           │       HPA            │                          │
│                           │  水平扩缩容           │                          │
│                           │  控制 replicas        │                          │
│                           └──────────┬───────────┘                          │
│                                      │                                        │
│                                      │                                        │
│  ┌───────────────────────────────────┼───────────────────────────────────┐  │
│  │                                   ▼                                    │  │
│  │                        ┌──────────────────────┐                       │  │
│  │                        │     Deployment       │                       │  │
│  │                        │                      │                       │  │
│  │                        │   replicas: 3 → 6    │                       │  │
│  │                        │   (HPA 扩容)          │                       │  │
│  │                        └──────────┬───────────┘                       │  │
│  │                                   │                                    │  │
│  │                                   │                                    │  │
│  │                                   ▼                                    │  │
│  │                        ┌──────────────────────┐                       │  │
│  │                        │       VPA            │                       │  │
│  │                        │  垂直扩缩容           │                       │  │
│  │                        │  控制 resources       │                       │  │
│  │                        └──────────┬───────────┘                       │  │
│  │                                   │                                    │  │
│  └───────────────────────────────────┼───────────────────────────────────┘  │
│                                      │                                        │
│                                      ▼                                        │
│                           ┌──────────────────────┐                          │
│                           │        Pod           │                          │
│                           │  cpu: 100m → 200m     │                          │
│                           │  memory: 128Mi→ 256Mi │                          │
│                           │  (VPA 调整)           │                          │
│                           └──────────────────────┘                          │
│                                                                              │
│  典型场景:                                                                   │
│  • HPA: 根据 CPU/内存使用率调整副本数                                        │
│  • VPA: 根据历史资源使用自动调整容器规格                                      │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

七、状态与生命周期

7.1 状态字段含义

bash

kubectl get deployment my-app -o wide

输出示例与字段说明:

plaintext

NAME      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES         SELECTOR
my-app    3/3     1            3           10m   my-app       nginx:1.25     app=my-app

字段说明
READY当前就绪 Pod 数 / 期望副本数 (如 3/3)
UP-TO-DATE已更新到期望版本的 Pod 数
AVAILABLE可用(就绪且非终止状态)的 Pod 数
AGEDeployment 创建至今的时间

完整状态查看:

bash

kubectl get deployment my-app -o jsonpath='{.status}'

json

{
  "conditions": [
    {
      "type": "Available",
      "status": "True",
      "reason": "MinimumReplicasAvailable",
      "message": "Deployment has minimum availability."
    },
    {
      "type": "Progressing",
      "status": "True",
      "reason": "NewReplicaSetAvailable",
      "message": "ReplicaSet \"my-app-7d9b65c8f5\" has successfully progressed."
    }
  ],
  "replicas": 3,
  "readyReplicas": 3,
  "availableReplicas": 3,
  "updatedReplicas": 1,
  "collisionCount": 0
}

7.2 条件类型判断

Deployment 通过 Conditions 表示当前状态:

Condition TypeTrue 含义False 含义
Available至少最小可用副本数就绪有 Pod 不可用
ProgressingDeployment 正在推进(创建/更新中)Deployment 进度卡住
ReplicaFailure-创建 Pod 失败

Progressing 条件的详细判断:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                      Progressing 条件判断逻辑                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   Progressing = True (满足任一条件):                                         │
│   ┌─────────────────────────────────────────────────────────────────────┐    │
│   │  1. Deployment 正在执行创建或更新                                   │    │
│   │  2. 所有 Pod 都就绪(READY = replicas)                             │    │
│   │  3. 没有正在终止的 Pod                                               │    │
│   └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
│   Progressing = False (原因):                                               │
│   ┌─────────────────────────────────────────────────────────────────────┐    │
│   │  reason: "ProgressDeadlineExceeded"                                 │    │
│   │  message: "ReplicaSet "xxx" has not progressed...                  │    │
│   │                                                                       │    │
│   │  可能原因:                                                            │    │
│   │  • 超过 progressDeadlineSeconds 未完成更新                           │    │
│   │  • 镜像拉取失败                                                       │    │
│   │  • 容器启动失败                                                       │    │
│   │  • 资源不足无法调度                                                   │    │
│   └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

7.3 事件查看与排查

bash

# 查看 Deployment 相关事件
kubectl get events --field-selector involvedObject.name=my-app --sort-by='.lastTimestamp'

# 查看更详细的事件
kubectl describe deployment my-app

# 查看 Pod 事件
kubectl get events --field-selector involvedObject.name=my-app-pod-xxx

# 查看命名空间级别所有事件
kubectl get events -n default --sort-by='.lastTimestamp'

# 过滤特定类型事件
kubectl get events --field-selector type=Warning
kubectl get events --field-selector reason=Failed

# 查看最新事件(实时)
kubectl get events --watch

八、常见问题与排查

8.1 更新卡住

症状: Deployment 长时间处于 Progressing 状态,Pod 数量不变化。

排查步骤:

bash

# 1. 检查 Deployment 状态
kubectl get deployment my-app
kubectl describe deployment my-app

# 2. 检查 ReplicaSet 状态
kubectl get rs -l app=my-app

# 3. 检查新 ReplicaSet 的 Pod
kubectl get pods -l app=my-app,pod-template-hash=xxx --show-labels

# 4. 检查 Pod 事件
kubectl describe pod <pod-name>

# 5. 检查 Pod 日志
kubectl logs <pod-name> --previous  # --previous 查看前一个容器的日志

常见原因及解决方案:

原因诊断方法解决方案
镜像拉取失败kubectl describe pod 查看 Failed to pull image配置正确的镜像仓库凭证
容器启动失败kubectl logs 查看错误日志修复应用代码或配置
存活探针失败kubectl describe pod 查看探针信息调整探针参数或修复应用
资源不足kubectl describe node 查看资源扩容节点或调整资源请求
节点不可用kubectl get node 查看 NotReady修复节点或驱逐 Pod

强制完成卡住的 Deployment:

bash

# 方法1: 增加 progressDeadlineSeconds
kubectl patch deployment my-app -p '{"spec":{"progressDeadlineSeconds":1200}}'

# 方法2: 标记为 Failed(可用于触发回滚)
kubectl annotate deployment my-app kubernetes.io/change-cause="Force complete"

# 方法3: 删除卡住的 ReplicaSet(慎用)
kubectl delete rs <stuck-replicaset-name>

# 方法4: 回滚
kubectl rollout undo deployment/my-app

8.2 Pod 启动失败

症状: Pod 处于 Pending、ImagePullBackOff、CrashLoopBackOff、Error 等状态。

排查流程:

plaintext

┌─────────────────────────────────────────────────────────────────────────────┐
│                         Pod 启动失败排查流程                                 │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  kubectl get pods -l app=my-app                                              │
│                                                                              │
│  │                                                                           │
│  ├─→ ContainerCreating                                                        │
│  │       │                                                                   │
│  │       ├─→ 原因: 镜像拉取中                                                │
│  │       │       解决: 等待或检查镜像仓库                                     │
│  │       │                                                                   │
│  │       ├─→ 原因: CNI 网络插件问题                                          │
│  │       │       解决: 检查 CNI 配置和节点网络                                │
│  │       │                                                                   │
│  │       └─→ 原因: 资源不足无法调度                                          │
│  │               解决: 检查节点资源或调整资源请求                             │
│  │                                                                           │
│  ├─→ ImagePullBackOff                                                         │
│  │       │                                                                   │
│  │       ├─→ 原因: 镜像不存在                                                │
│  │       │       解决: 检查镜像名称和 tag                                    │
│  │       │                                                                   │
│  │       ├─→ 原因: 镜像仓库认证失败                                          │
│  │       │       解决: 配置 imagePullSecrets                                 │
│  │       │                                                                   │
│  │       └─→ 原因: 网络问题无法访问镜像仓库                                   │
│  │               解决: 检查节点网络配置                                      │
│  │                                                                           │
│  ├─→ CrashLoopBackOff                                                        │
│  │       │                                                                   │
│  │       ├─→ 原因: 应用启动失败                                               │
│  │       │       解决: kubectl logs <pod-name> 查看日志                      │
│  │       │                                                                   │
│  │       ├─→ 原因: 健康检查过于严格                                          │
│  │       │       解决: 调整 liveness/readinessProbe                          │
│  │       │                                                                   │
│  │       └─→ 原因: 依赖服务不可用                                             │
│  │               解决: 检查应用依赖配置                                       │
│  │                                                                           │
│  ├─→ Error                                                                   │
│  │       │                                                                   │
│  │       └─→ 原因: OOMKilled、资源限制、致命错误                              │
│  │               解决: kubectl describe pod 查看事件                        │
│  │                                                                           │
│  └─→ Pending                                                                  │
│          │                                                                   │
│          ├─→ 原因: 调度失败(无满足条件的节点)                               │
│          │       解决: 检查 affinity/taint/nodeSelector                      │
│          │                                                                   │
│          └─→ 原因: PVC 绑定等待                                              │
│                  解决: 检查 PersistentVolumeClaim 状态                      │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

详细排查命令:

bash

# 查看 Pod 详细状态
kubectl describe pod <pod-name>

# 查看 Pod 日志
kubectl logs <pod-name>
kubectl logs <pod-name> --previous        # 前一个容器的日志

# 进入 Pod 调试
kubectl exec -it <pod-name> -- /bin/sh

# 查看资源配额
kubectl describe resourcequota
kubectl describe limitrange

# 检查调度原因
kubectl get events --field-selector involvedObject.name=<pod-name>

8.3 回滚失败

症状: 回滚命令执行后没有效果或报错。

排查步骤:

bash

# 1. 确认回滚命令执行结果
kubectl rollout undo deployment/my-app --to-revision=2
kubectl rollout status deployment/my-app

# 2. 查看回滚历史
kubectl rollout history deployment/my-app

# 3. 检查 ReplicaSet 状态
kubectl get rs -l app=my-app -o wide

# 4. 检查新 Pod 状态
kubectl get pods -l app=my-app

常见回滚失败原因:

原因现象解决方案
指定版本不存在error: unable to find revision 2使用 kubectl rollout history 查看可用版本
Deployment 暂停回滚不生效kubectl rollout resume deployment/my-app
ReplicaSet 被删除版本历史丢失无法回滚,需手动重建
权限不足权限错误检查 RBAC 配置

手动回滚方法:

bash

# 如果自动回滚失败,可以手动执行:

# 1. 查看当前配置
kubectl get deployment my-app -o yaml > current.yaml

# 2. 找到历史版本的 ReplicaSet
kubectl get rs -l app=my-app

# 3. 从历史 ReplicaSet 获取配置
kubectl get rs <historical-replicaset> -o yaml > historical.yaml

# 4. 修改名称后应用
sed -i 's/name: my-app-xxx/name: my-app-rollback/' historical.yaml
kubectl apply -f historical.yaml

# 5. 修改 Deployment 指向新 ReplicaSet
kubectl scale deployment my-app --replicas=0
kubectl edit deployment my-app
# 修改 selector 中的 pod-template-hash 为新 ReplicaSet 的 hash
kubectl scale deployment my-app --replicas=3

8.4 其他常见问题

8.4.1 Selector 冲突

bash

# 错误: Deployment 与已有 ReplicaSet 冲突
# Error: Failed to create deployment: admission webhook "validationwebhook..." denied

解决方案: 使用唯一的 selector 标签

yaml

# 错误示例
spec:
  selector:
    matchLabels:
      app: my-app    # 可能与现有的 Deployment 冲突

# 正确示例
spec:
  selector:
    matchLabels:
      app: my-app
      version: v1     # 添加额外标签确保唯一

8.4.2 Pod 无法调度

bash

# 查看调度失败原因
kubectl describe pod <pod-name> | grep -A 5 "Events:"

# 常见原因
# - 资源不足: Insufficient memory/cpu
# - 污点不匹配: node(s) had taints that the pod didn't tolerate
# - 亲和性冲突: node(s) didn't match pod affinity/anti-affinity rules

8.4.3 版本历史丢失

bash

# 检查 revisionHistoryLimit 配置
kubectl get deployment my-app -o jsonpath='{.spec.revisionHistoryLimit}'

# 如果为 0,则不会保留历史版本
# 解决方案:设置合适的值
kubectl patch deployment my-app -p '{"spec":{"revisionHistoryLimit":10}}'

九、最佳实践

9.1 资源配置最佳实践

yaml

spec:
  template:
    spec:
      containers:
      - name: app
        # ✅ 必须设置资源请求(调度依据)
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          # ✅ 建议设置资源限制(防止异常)
          limits:
            memory: "512Mi"
            cpu: "500m"
        
        # ✅ 建议添加健康检查
        livenessProbe:
          httpGet:
            path: /healthz
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        
        # ✅ 生产环境建议使用 startupProbe
        startupProbe:
          httpGet:
            path: /healthz
            port: 8080
          failureThreshold: 30
          periodSeconds: 10

9.2 更新策略最佳实践

yaml

spec:
  # ✅ 生产环境推荐使用滚动更新
  strategy:
    type: RollingUpdate
    rollingUpdate:
      # 保守策略:确保服务稳定
      maxSurge: 1              # 最多超出 1 个 Pod
      maxUnavailable: 0        # 保持所有 Pod 可用
  
  # ✅ 设置合理的进度超时
  progressDeadlineSeconds: 600  # 10 分钟内必须完成
  
  # ✅ 设置就绪观察时间
  minReadySeconds: 10          # Pod 稳定运行 10 秒后才认为就绪
  
  # ✅ 保留历史版本用于回滚
  revisionHistoryLimit: 10

9.3 高可用部署策略

yaml

spec:
  # ✅ 生产环境至少 2 个副本
  replicas: 3
  
  # ✅ 使用 Pod 反亲和分散部署
  template:
    spec:
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: my-app
              topologyKey: kubernetes.io/hostname
  
  # ✅ 添加 Pod Disruption Budget
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-app-pdb
spec:
  minAvailable: 2    # 或使用 maxUnavailable: 1
  selector:
    matchLabels:
      app: my-app

9.4 版本管理最佳实践

bash

# ✅ 使用 labels 标记版本
kubectl label deployment my-app version=v1.2.3

# ✅ 使用 annotations 记录变更原因
kubectl annotate deployment my-app \
  kubernetes.io/change-cause="Update base image to nginx:1.25-alpine"

# ✅ 避免频繁小版本更新,攒批更新减少滚动次数

# ✅ 发布前在 staging 环境充分测试

# ✅ 使用 pause/resume 进行批量修改
kubectl rollout pause deployment/my-app
# 执行多次配置变更
kubectl rollout resume deployment/my-app

9.5 安全最佳实践

yaml

spec:
  template:
    spec:
      # ✅ 使用非 root 用户运行
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 1000
      
      containers:
      - name: app
        # ✅ 限制容器能力
        securityContext:
          allowPrivilegeEscalation: false
          readOnlyRootFilesystem: true
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      
      # ✅ 使用只读根文件系统 + tmp 目录
      volumes:
      - name: tmp
        emptyDir: {}
      
      # ✅ 分离应用和日志存储
      - name: app-storage
        emptyDir:
          sizeLimit: "100Mi"

9.6 监控与日志

bash

# ✅ 部署时添加监控标签
kubectl label deployment my-app \
  app=my-app \
  environment=production \
  team=backend

# ✅ 推荐配置
# - 使用 Prometheus + Grafana 监控 Deployment 状态
# - 配置 Pod 级别的 metrics 采集
# - 收集日志到集中式日志系统(ELK/Loki)
# - 配置告警规则监控 Deployment 状态异常

9.7 快速恢复脚本

bash

#!/bin/bash
# deployment-utils.sh

DEPLOYMENT=$1
NAMESPACE=${2:-default}

# 回滚 Deployment
rollback_deployment() {
    echo "Rolling back $DEPLOYMENT in $NAMESPACE..."
    kubectl rollout undo deployment/$DEPLOYMENT -n $NAMESPACE
    kubectl rollout status deployment/$DEPLOYMENT -n $NAMESPACE
}

# 查看部署状态
status_deployment() {
    echo "=== Deployment Status ==="
    kubectl get deployment $DEPLOYMENT -n $NAMESPACE
    
    echo -e "\n=== ReplicaSet Status ==="
    kubectl get rs -l app=$DEPLOYMENT -n $NAMESPACE
    
    echo -e "\n=== Pod Status ==="
    kubectl get pods -l app=$DEPLOYMENT -n $NAMESPACE
    
    echo -e "\n=== Recent Events ==="
    kubectl get events -n $NAMESPACE --field-selector involvedObject.name=$DEPLOYMENT --sort-by='.lastTimestamp'
}

# 扩容 Deployment
scale_deployment() {
    REPLICAS=$3
    echo "Scaling $DEPLOYMENT to $REPLICAS replicas..."
    kubectl scale deployment $DEPLOYMENT --replicas=$REPLICAS -n $NAMESPACE
}

# 强制重启
restart_deployment() {
    echo "Force restarting $DEPLOYMENT..."
    kubectl rollout restart deployment/$DEPLOYMENT -n $NAMESPACE
    kubectl rollout status deployment/$DEPLOYMENT -n $NAMESPACE
}

case "$1" in
    status)
        status_deployment
        ;;
    rollback)
        rollback_deployment
        ;;
    scale)
        scale_deployment "$@"
        ;;
    restart)
        restart_deployment
        ;;
    *)
        echo "Usage: $0 {status|rollback|scale|restart} <deployment> [namespace] [replicas]"
        ;;
esac

十、总结

Deployment 是 Kubernetes 中最核心的工作负载资源之一,它通过声明式的配置实现了应用的自动化部署、更新和扩缩容。掌握 Deployment 的原理和最佳实践,对于构建可靠的云原生应用至关重要。

核心要点回顾:

  1. 声明式管理:通过 YAML 声明期望状态,控制器自动调谐
  2. 滚动更新:支持零宕机部署,可配置 maxSurge/maxUnavailable
  3. 版本回滚:自动保存历史版本,支持快速回退
  4. 弹性伸缩:支持手动扩缩容和 HPA/VPA 自动扩缩容
  5. 健康检查:通过 liveness/readiness/startupProbe 保证应用质量
  6. 高级策略:支持金丝雀发布、蓝绿部署等复杂场景

推荐实践:

  • 生产环境使用 replicas ≥ 2 + Pod 反亲和
  • 保守的滚动更新策略:maxSurge=1, maxUnavailable=0
  • 始终配置资源请求和健康检查
  • 保留足够的 revisionHistoryLimit 用于回滚
  • 配合 PDB(PodDisruptionBudget) 保证高可用

更多推荐