Skip to content

Deployment 发布

Deployment 是无状态服务最常用的工作负载对象。它通过 ReplicaSet 管理 Pod 副本,提供滚动更新、回滚、暂停和发布状态查看。

Deployment 和 ReplicaSet 的关系

Deployment 不直接管理每个 Pod——它创建 ReplicaSet,ReplicaSet 再维护 Pod 数量:

旧 ReplicaSet 会保留一段时间,用于回滚:

bash
kubectl -n demo get deploy,rs,pod -l app=web
kubectl -n demo rollout history deploy/web

基础 Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: demo
  labels:
    app: web
spec:
  replicas: 3
  revisionHistoryLimit: 5 # 保留最近 5 个历史 ReplicaSet,多了浪费 etcd 空间
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
        version: v1
    spec:
      containers:
        - name: web
          image: harbor.example.com/demo/web:v1.0.0
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            periodSeconds: 5

selector.matchLabels 和 Pod 模板的 labels 必须对上。Deployment 创建后 selector 基本不适合改——改错会导致控制器接管关系混乱。

滚动更新

滚动更新通过逐批创建新 Pod、删除旧 Pod 来完成:

yaml
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1        # 更新期间最多额外多 1 个 Pod
    maxUnavailable: 0  # 更新期间不允许有不可用 Pod

发布新镜像:

bash
kubectl -n demo set image deploy/web web=harbor.example.com/demo/web:v1.0.1
kubectl -n demo rollout status deploy/web

maxSurgemaxUnavailable 要结合服务容量看。副本数很少的服务(比如只有 2 个副本),maxUnavailable: 1 就可能让可用容量直接下降 50%。

readinessProbe 在滚动更新中的作用

Deployment 滚动更新的节奏依赖 Pod Ready 状态。readinessProbe 失败时,新 Pod 不会进入 Service 后端,旧 Pod 也不会被删除——滚动更新卡在这里:

yaml
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3

没有 readinessProbe 时,容器进程一启动就被认为可接流量。启动慢的 Java 服务、需要预热缓存的服务、启动后要连外部依赖的服务,容易出现"Pod 已经 Running 但请求返回 5xx"。

回滚

查看发布历史:

bash
kubectl -n demo rollout history deploy/web
kubectl -n demo rollout history deploy/web --revision=2

回滚到上一版:

bash
kubectl -n demo rollout undo deploy/web

回滚到指定版本:

bash
kubectl -n demo rollout undo deploy/web --to-revision=2

回滚只恢复 Deployment 模板到旧版本。它不回滚数据库 schema、外部配置、缓存数据和消息消费进度——只靠 Deployment 回滚,复杂业务经常不够。

暂停和恢复

连续改多个字段时,可以暂停 rollout,让变更累积后一次触发:

bash
kubectl -n demo rollout pause deploy/web
kubectl -n demo set image deploy/web web=harbor.example.com/demo/web:v1.0.2
kubectl -n demo set resources deploy/web -c web --requests=cpu=200m,memory=256Mi
kubectl -n demo rollout resume deploy/web

暂停期间的所有变更会堆在一起,恢复后触发一次滚动——适合手工维护时减少多次 Pod 重建。

发布排查

发布卡住时:

bash
kubectl -n demo rollout status deploy/web
kubectl -n demo describe deploy web
kubectl -n demo get rs,pod -l app=web -o wide
kubectl -n demo describe pod <pod-name>
现象方向
新 Pod ImagePullBackOff镜像 tag 写错、仓库认证、节点到仓库网络
新 Pod Running 但不 ReadyreadinessProbe 失败、应用启动异常、依赖不可用
新 Pod Pending资源不足、调度规则、PVC
rollout 超时progressDeadlineSeconds 到期、新副本仍未 Ready

发布故障里要区分"平台没创建起 Pod"和"Pod 创建起来了但不能接流量"。前者看事件和节点,后者看探针、应用日志和入口指标——两条路径的排查方向完全不同。