Skip to main content
Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Kubernetes Deployment

📘 Kubernetes Deployment 详解(适用版本 ≥ 1.20 ~ 1.33)

Deployment 是 Kubernetes 中最常用的工作负载(Workload)之一,用于:

  • 管理 无状态应用(stateless)
  • 滚动升级(Rolling Update)
  • 回滚(Rollback)
  • 自动重建副本(self-healing)
  • 控制 Pod 副本数(ReplicaSet)

Deployment 通过 ReplicaSet 来管理 Pod,但用户几乎不直接操作 ReplicaSet,而是操作 Deployment,K8s 自动维护一致性。

1. Deployment 的核心结构

最简 Deployment 示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: demo
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
        - name: demo
          image: nginx:1.27

结构解读:

字段 含义
replicas Pod 副本数量
selector Deployment 使用 selector 绑定 ReplicaSet
template Pod 模板,变化时触发滚动更新
strategy 更新策略(RollingUpdate / Recreate)

2. Deployment 工作机制(最重要)

Deployment -> 创建 ReplicaSet(RS) -> RS 创建 Pod

当 Deployment 模板变化时:

  1. 生成新的 ReplicaSet
  2. 逐步扩容新的 RS
  3. 逐步缩容旧的 RS
  4. 完成后旧 RS 保留(用于回滚)

可以同时存在多个历史 ReplicaSet。

3. Deployment 更新策略(RollingUpdate & Recreate)

3.1 默认:Rolling Update(滚动更新)

Deployment 默认使用:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 25%
    maxSurge: 25%

含义:

字段 含义
maxUnavailable 更新期间允许“最少缺失”的 Pod 比例或数量
maxSurge 更新期间允许“多出来”的 Pod 比例或数量

例如:replicas=4,maxSurge=1,maxUnavailable=1

更新时允许:

  • 最多 5 个 Pod 运行(4 + 1)
  • 最少 3 个 Pod 可用(4 - 1)

可避免服务中断,是推荐方式。

3.2 Recreate(重建)

strategy:
  type: Recreate

更新时:

  • 先删光所有 Pod
  • 再创建新 Pod

适用场景:

  • 需要唯一访问控制,如:

    • MySQL(除非 StatefulSet)
    • ElasticSearch 单节点
    • 某些不能并发运行的 legacy app

4. Deployment 常用 spec 字段详解

4.1 revisionHistoryLimit

保留多少条历史 ReplicaSet(用于回滚)

revisionHistoryLimit: 10

默认值是 10。

4.2 progressDeadlineSeconds

Deployment 更新最大时间,超时则标记失败。

progressDeadlineSeconds: 600

默认 600 秒。

4.3 minReadySeconds

新建 Pod 在 ready 状态至少保持多长时间才算“成功”。

minReadySeconds: 5

适合需要预热的服务。

5. Pod 模板变化与滚动更新触发规则

哪些变化会触发新 RS?

会触发的:

  • 镜像 tag变化
  • 环境变量变化
  • configmap/secret 名称变化
  • command/args 变化
  • labels(template 部分)变化
  • 资源限制变化(CPU/Mem)
  • 端口配置变化

不会触发的:

  • Deployment 的注解变更
  • Deployment 的 labels(不影响 template)

6. Deployment 生命周期管理

6.1 更新

kubectl set image deploy/demo demo=nginx:1.28

Kubernetes 会自动滚动更新。

6.2 暂停更新(Pause)

用于进行参数修改后,统一 apply。

kubectl rollout pause deploy/demo

然后更新字段:

kubectl edit deploy/demo

完成后:

kubectl rollout resume deploy/demo

6.3 查看状态

kubectl rollout status deploy/demo

6.4 查看历史版本

kubectl rollout history deploy/demo

6.5 回滚

回滚到上一个版本:

kubectl rollout undo deploy/demo

回滚到指定 revision:

kubectl rollout undo deploy/demo --to-revision=3

7. 高可用/生产级 Deployment 最佳实践

以下内容非常关键,基本上所有生产集群都建议遵循。

7.1 设置资源限制(requests/limits)

resources:
  requests:
    cpu: 100m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 1Gi

不设置意味着 Node 资源调度不可控,引发过载。

7.2 Liveness/Readiness/Startup probes(强烈建议)

livenessProbe:
  httpGet: { path: /healthz, port: 8080 }
  initialDelaySeconds: 10
  periodSeconds: 10

readinessProbe:
  httpGet: { path: /ready, port: 8080 }
  initialDelaySeconds: 5
  periodSeconds: 5

服务可用性明显提升。

7.3 Anti-affinity(跨节点容灾)

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: demo
          topologyKey: kubernetes.io/hostname

确保 Pod 分散在多个节点。

7.4 PodDisruptionBudget(PDB)

保证滚动升级或节点维护不会一次性干掉太多 Pod。

apiVersion: policy/v1
kind: PodDisruptionBudget
spec:
  minAvailable: 2
  selector:
    matchLabels:
      app: demo

7.5 HorizontalPodAutoscaler(HPA)

自动扩容(需 metrics-server):

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler

8. 完整生产级 Deployment 示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 4
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
  minReadySeconds: 5
  selector:
    matchLabels:
      app: demo
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        app: demo
    spec:
      containers:
      - name: demo
        image: nginx:1.27
        ports:
        - containerPort: 80
        resources:
          requests: { cpu: "200m", memory: "256Mi" }
          limits: { cpu: "1", memory: "512Mi" }
        readinessProbe:
          httpGet: { path: "/", port: 80 }
          initialDelaySeconds: 3
        livenessProbe:
          httpGet: { path: "/", port: 80 }
          initialDelaySeconds: 10
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchLabels:
                  app: demo
              topologyKey: kubernetes.io/hostname

9. Deployment 常见问题排查

Pod 不更新?

Deployment template 没有变化,不会触发新 RS。

更新卡住?

检查:

  • readinessProbe 不通过
  • 镜像拉取失败
  • maxUnavailable 设置过低(如 0)
  • PDB 导致无法驱逐旧 Pod
  • 新 Pod 调度失败(资源不足)

10. Deployment 与其他 Workload 对比

Workload 特点
Deployment 无状态、滚动更新、回滚
StatefulSet 有状态、有序启动、稳定网络标识、持久存储
DaemonSet 每个 Node 一个 Pod
Job / CronJob 一次性任务 / 定时任务
ReplicaSet Deployment 的底层管理对象,很少直接使用

YAML

Kubernetes Deployment YAML 配置详解(逐字段解释 + 最佳实践)

内容包括:

  • Deployment 整体结构
  • 每个字段的详细含义
  • 实际 YAML 模板 + 逐行解释
  • 多副本滚动更新、探针、资源限制、策略等
  • 最佳实践

💡 1. Deployment 是什么?

Deployment 是 Kubernetes 中最常用的 workload,用于:

  • 管理 多个副本 Pod
  • 自动重建、自动修复
  • 提供 滚动更新(rolling update)
  • 提供 版本回滚

Deployment 是对 ReplicaSet 的高级封装。

📦 2. Deployment 的 YAML 完整结构

一个 Deployment 主要包含四层:

apiVersion
kind
metadata
spec
  ├─ replicas
  ├─ selector
  ├─ strategy
  ├─ template
      ├─ metadata
      └─ spec

🧱 3. 最完整可复用 Deployment 模板(K8s 1.33)

下面是一个功能最完整的 Deployment 示例,

你可以根据需要裁剪、扩展:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  namespace: default
  labels:
    app: my-app

spec:
  replicas: 3
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600
  minReadySeconds: 5
  paused: false

  selector:
    matchLabels:
      app: my-app

  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%     # 更新过程中至少保留多少可用 Pod
      maxSurge: 25%           # 更新过程中最多超出的 Pod 数量

  template:
    metadata:
      labels:
        app: my-app
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"

    spec:
      serviceAccountName: default
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst

      containers:
        - name: my-app
          image: my-app:1.0.0
          imagePullPolicy: IfNotPresent

          ports:
            - containerPort: 8080
              name: http

          env:
            - name: ENV
              value: "production"

          envFrom:
            - configMapRef:
                name: my-config
            - secretRef:
                name: my-secret

          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"

          startupProbe:
            httpGet:
              path: /startup
              port: 8080
            failureThreshold: 30
            periodSeconds: 5

          readinessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

          livenessProbe:
            httpGet:
              path: /alive
              port: 8080
            periodSeconds: 10

          volumeMounts:
            - name: app-config
              mountPath: /etc/my-app

      initContainers:
        - name: init-db
          image: busybox
          command: ["sh", "-c", "echo preparing"]

      volumes:
        - name: app-config
          configMap:
            name: my-config

📝 4. 逐字段解释(最详细)

4.1 metadata

metadata:
  name: my-app
  namespace: default
  labels:
    app: my-app
  • name:Deployment 名称
  • namespace:作用的命名空间
  • labels:为 Deployment 自身打标签

4.2 spec

🧩 replicas

replicas: 3

期望运行 3 个 Pod。

🧩 revisionHistoryLimit

revisionHistoryLimit: 10

最多保留 10 个旧 ReplicaSet(用于回滚)。

🧩 progressDeadlineSeconds

progressDeadlineSeconds: 600

若 600 秒内更新没有完成,则 Deployment 进入 ProgressDeadlineExceeded 状态。

🧩 minReadySeconds

minReadySeconds: 5

Pod 就绪后需要至少 ready 5 秒才算可用。

🧩 paused

paused: false

为 true,则暂停滚动更新。

4.3 selector(必须和 Pod template 的 labels 匹配)

selector:
  matchLabels:
    app: my-app

用于“选中” template 生成的 Pod。

4.4 strategy(滚动更新策略)

默认类型是 RollingUpdate:

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 25%
    maxSurge: 25%
  • maxUnavailable:更新时最多允许 25% Pod 不可用
  • maxSurge:更新时最多多创建 25% Pod

👉 Recreate 模式

strategy:
  type: Recreate
  • 先删旧 Pod -> 再创建新 Pod
  • 适用于:不能并存两个版本的应用(如 MySQL 主节点)。

5. template (Pod 模板)

这是 Deployment 最重要的部分。

5.1 template.metadata

labels:
  app: my-app
annotations:
  prometheus.io/scrape: "true"

labels 与 selector 匹配非常关键。

5.2 template.spec

Deployment 管理的 Pod 内容,例如:

容器列表

containers:
  - name: my-app

5.3 imagePullPolicy

imagePullPolicy: IfNotPresent

三种:

  • Always:每次启动都拉镜像
  • IfNotPresent:本地有就不用拉
  • Never:永远不拉

🔹 推荐:生产使用 IfNotPresent + tag 固定版本

避免 latest 导致更新不可控。

5.4 资源限制

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"
  • requests:调度时 Pod 需要的资源
  • limits:容器最大可用资源

最佳实践:

  • Web 应用:100m–200m
  • API 服务:256Mi–512Mi

5.5 Probe 探针

startupProbe(初始化准备)

防止容器还没启动就被重启。

readinessProbe(是否对外可用)

控制 Service 的流量转发。

livenessProbe(容器是否存活)

不健康 -> 自动重启。

5.6 initContainers

initContainers:
  - name: init-db
    image: busybox

用于初始化:

  • 等待数据库
  • 初始化目录

initContainers 按顺序执行

5.7 volumes

如挂载 ConfigMap / Secret:

volumes:
  - name: app-config
    configMap:
      name: my-config

🏆 5. Deployment 使用最佳实践(K8s 1.33)

使用固定标签,不要使用 latest

image: my-app:v1.3.0

使用 readinessProbe 控制流量

避免服务启动早期收到流量而崩溃。

滚动更新策略合理配置

maxUnavailable = 25%
maxSurge = 25%

requests/limits 必须设置(防止节点压力过大)

使用 revisionHistoryLimit 避免副本爆炸

推荐将日志 stdout/stderr 输出到容器标准输出

使用 PodDisruptionBudget(PDB)防止升级导致全挂