第 6 / 18 篇

第 5 章 用 Deployment 管理应用

从“启动一次”变成“持续保持”

Deployment 管理无状态应用的副本和更新。它通过 ReplicaSet 维持 Pod 数量。一般情况下,你维护 Deployment 清单,不直接编辑它生成的 Pod,也不手工修改它管理的 ReplicaSet。

把以下内容保存为 deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-web
  template:
    metadata:
      labels:
        app: hello-web
    spec:
      containers:
        - name: web
          image: nginx:1.28
          ports:
            - containerPort: 80

template 是 Pod 模板。selector.matchLabels 告诉 Deployment 哪些 Pod 属于自己,必须与模板的标签匹配。标签(Label)是键值标记,如 app: hello-web;名字标识单个对象,标签则帮助筛选一组对象。Deployment 的选择器创建后通常不能直接修改,修改时要规划重建。

kubectl apply -n k8s-book -f deployment.yaml
kubectl rollout status deployment/hello-web -n k8s-book --timeout=120s
kubectl get deployments,replicasets,pods -n k8s-book

Deployment 中 READY 最终应为 2/2。Pod 名称带自动生成的后缀,这是正常现象。

亲手观察自愈

kubectl get pods -n k8s-book -l app=hello-web

从输出复制一个 Pod 名,将下面的占位符替换后执行:

kubectl delete pod <实际的Pod名称> -n k8s-book
kubectl get pods -n k8s-book -w

你会看到一个新名字的 Pod 被创建。-w 持续观察,Ctrl+C 结束。这不是旧 Pod 起死回生,而是控制器创建了替代品。Pod 的 IP 和名字都可能变化,因此应用之间不应该依赖某一个 Pod 的地址。

扩容和声明文件的一致性

kubectl scale deployment hello-web -n k8s-book --replicas=3
kubectl get pods -n k8s-book

这是一次命令式修改。如果 deployment.yaml 里仍是 replicas: 2,下次 apply 可能把它改回两个。长期管理要把你真正希望的副本数写回清单。练习完成后,将副本数恢复为两个,并重新应用文件。

本章自测:删除 Deployment 管理的一个 Pod 后发生什么?为什么它的替代品通常不沿用旧名字?