Deployment 是什么
Deployment 是无状态应用的标准控制器:你声明期望的副本数与 Pod 模板,它负责让集群里的实际状态向声明靠拢。它自身不直接管 Pod,而是为每一次模板变化创建对应的 ReplicaSet,由 ReplicaSet 维护 Pod 数量。发布、扩缩容、回滚这三件事都围绕它完成,日常运维大部分时间都在跟它打交道。
为什么要有这一层
裸 Pod 没有自愈与升级能力:节点故障即消失,改配置只能删了重建。Deployment 通过模板哈希区分版本,让新旧 ReplicaSet 同时存在,滚动更新时按策略逐步替换,出问题只要把副本切回旧 ReplicaSet 就完成回滚。这也是它比直接管理 Pod 更适合生产的原因。
基本信息
| 适用环境 | 任何 Kubernetes 发行版,API 版本 apps/v1 |
|---|---|
| 适用对象 | 无状态、可水平扩展的应用;有状态应用改用 StatefulSet |
| 管理关系 | Deployment 管 ReplicaSet,ReplicaSet 管 Pod |
| 默认策略 | RollingUpdate,按比例逐步替换旧副本 |
| Pod 命名 | 负载名 + 模板哈希 + 随机后缀 |
| 关键字段 | replicas、selector、template、strategy、revisionHistoryLimit |
典型使用场景
- 发布新版本:修改模板里的镜像标签,由控制器自动完成滚动替换
- 扩缩容:调整副本数应对流量变化,或交给自动扩缩组件接管
- 回滚:新版本出现问题,切回上一个修订版本
- 重建全部实例:让新的配置或密钥生效
- 配置驱动部署:清单纳入版本管理,环境差异通过覆盖层解决
- 容量演练:临时提高副本数验证节点资源与调度约束是否满足
Deployment 清单
Deployment 清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
namespace: prod
spec:
replicas: 3
revisionHistoryLimit: 10 # 保留的历史修订数,回滚依赖它
selector: # 必须匹配下面的模板标签
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: registry.example.com/web:1.26.0
ports:
- containerPort: 8080日常操作
日常操作
kubectl apply -f web-deploy.yaml # 提交清单
kubectl get deploy web -o wide # 看副本就绪情况
kubectl rollout status deploy/web # 等待发布完成
kubectl scale deploy/web --replicas=5 # 手工扩缩容
kubectl rollout history deploy/web # 查看历史修订
kubectl rollout undo deploy/web # 回滚到上一版关键字段读法
| 字段 | 含义 | 设置要点 |
|---|---|---|
| replicas | 期望的 Pod 数量 | 设为 0 会保留对象但清空 Pod |
| selector | 本 Deployment 认领哪些 Pod | 创建后不可修改,写错只能重建 |
| template | Pod 模板,改动即触发发布 | 任何字段变化都会生成新修订 |
| strategy | 更新方式与节奏 | 默认 RollingUpdate,可按需调比例 |
| revisionHistoryLimit | 保留的历史修订数 | 过小会导致回滚目标已被清理 |
| minReadySeconds | 新副本就绪后需稳定多久才继续 | 对启动期抖动明显的应用很有用 |
生产使用要点
- 补上就绪探针,否则滚动更新期间流量会打到还没准备好的新副本
- 补上资源请求,否则调度装箱不准、节点容易被压垮
- 副本数至少两个并配置反亲和,避免单节点故障导致整体不可用
- 用明确的镜像标签而不是最新标签,回滚时才知道回到哪个版本
Pod 名中间的哈希段对应模板版本,同一 ReplicaSet 下的 Pod 哈希相同,据此可以判断某个 Pod 属于哪次发布。
缩容到零与暂停发布也由这个对象控制,排查「Pod 全没了」时先看副本数是否被改成 0,以及是否有自动扩缩组件把它调下去。
滚动更新的推进条件是「新副本就绪」,就绪由就绪探针定义;探针写得过于宽松时,新版本没准备好就被判定为完成。
与其他控制器的分工
- 无状态可水平扩展的服务用 Deployment,这是绝大多数业务负载的选择
- 需要稳定名称与独立存储的有状态服务用 StatefulSet
- 需要在每个节点上跑一份的基础组件用 DaemonSet
- 需要跑完即止的一次性任务用 Job,周期性任务用 CronJob