Deployment 是 Kubernetes 中最常用的控制器,专门用来部署和管理无状态服务。所谓无状态服务,是指不依赖本地存储和会话保持的应用,任意一个 Pod 副本都可以被随时替换而不影响整体功能,典型代表有 Nginx、API 服务、前端静态页面等。本文将系统讲解 Deployment 的使用方法,包括编写配置清单、扩缩容、滚动更新和版本回滚等核心操作。

一、Deployment 的核心概念与工作原理
要理解 Deployment 的行为,首先要弄清它和 ReplicaSet、Pod 三者之间的关系。Deployment 并不直接管理 Pod,而是通过 ReplicaSet 间接控制。当你创建一个 Deployment 时,Kubernetes 会自动生成一个 ReplicaSet,由这个 ReplicaSet 负责维持指定数量的 Pod 副本。如果某个 Pod 因为节点故障或程序崩溃而消失,ReplicaSet 会立刻创建新的 Pod 来补足数量,这就是所谓的自愈能力。
这种分层设计最大的价值在于版本管理。当你修改 Deployment 中的镜像版本时,控制器会创建一个新的 ReplicaSet,新 ReplicaSet 逐步增加副本数,旧 ReplicaSet 逐步减少副本数,整个过程就是滚动更新。更新完成后,旧的 ReplicaSet 并不会被删除,而是保留副本数为零的记录,这为快速回滚提供了基础。可以通过 revisionHistoryLimit 参数控制保留的历史版本数量,默认是 10 个。
与 ReplicaSet 相比,Deployment 的优势非常明显:ReplicaSet 只能保证副本数量,更新镜像时需要手动删除旧 Pod 才能触发重建,而 Deployment 把整个更新流程自动化了,还提供了暂停、恢复、回滚等操作入口。因此生产环境中几乎不会直接使用 ReplicaSet,一律用 Deployment 来管理无状态应用。
二、编写 Deployment 的 YAML 配置清单
创建 Deployment 最常见的方式是编写 YAML 文件,然后使用 kubectl apply 提交到集群。下面是一个部署 Nginx 的完整示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
这份配置中有几个关键字段需要注意。replicas 指定期望的副本数量,这里是 3 个。selector.matchLabels 定义了选择器,它必须和 template.metadata.labels 完全匹配,否则 API Server 会拒绝创建,这是新手最常踩的坑之一。template 部分则是 Pod 的模板,描述了每个副本的具体形态,包括容器镜像、端口和资源限制。
resources 字段建议在生产环境中一定要配置。requests 表示调度时的资源申请量,影响 Pod 被调度到哪个节点;limits 是资源上限,防止单个容器耗尽节点资源。配置完成后执行 kubectl apply -f nginx-deploy.yaml,再用 kubectl get deployment 查看状态,当 READY 列显示 3/3 时说明所有副本已正常运行。如果想看详细的事件信息,可以使用 kubectl describe deployment nginx-deploy。
三、扩缩容与滚动更新实战
当业务流量变化时,最直接的操作就是调整副本数量。使用命令 kubectl scale deployment nginx-deploy --replicas=5 可以把副本数扩展到 5 个,缩容同理。修改 YAML 文件中的 replicas 字段再 apply 也能达到相同效果,而且配置文件方式便于版本管理,推荐优先采用。
滚动更新是 Deployment 最核心的能力。修改镜像版本后,Deployment 会按照策略逐步替换旧 Pod。默认策略是 RollingUpdate,它由两个参数控制:maxSurge 表示更新过程中允许超出期望副本数的最大值,可以是整数或百分比;maxUnavailable 表示更新过程中允许不可用的 Pod 数量。例如下面的配置:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
上面的配置含义是:更新时先多创建 1 个新 Pod,确认新 Pod 就绪后再销毁一个旧 Pod,任何时刻可用副本数都不会低于期望值,适合对可用性要求高的服务。如果追求更新速度,可以设置 maxUnavailable 为 1,允许销毁一个旧 Pod 再创建新 Pod,但更新期间可用容量会短暂下降。另一种策略是 Recreate,即先删除全部旧 Pod 再创建新 Pod,更新期间服务完全不可用,除非应用有特殊限制,一般不推荐。
触发更新的命令是 kubectl set image deployment nginx-deploy nginx=nginx:1.26,执行后可以用 kubectl rollout status deployment nginx-deploy 观察更新进度。需要注意的是,如果镜像使用 latest 标签且模板内容没有其他变化,Deployment 检测不到变更,不会触发更新,因此生产环境强烈建议使用明确的版本号。
四、版本回滚与历史管理
发布出问题是难免的,Deployment 提供了完善的回滚机制。使用 kubectl rollout history deployment nginx-deploy 可以查看历史版本列表,每次镜像或模板变更都会生成一个新的修订号。回滚到上一个版本执行 kubectl rollout undo deployment nginx-deploy,回滚到指定版本则加上 --to-revision=2 参数。
回滚的底层原理其实和滚动更新一样:控制器把旧 ReplicaSet 的副本数重新扩起来,把当前版本的副本缩下去,整个过程依然是平滑的,服务不会中断。这也是 Deployment 保留历史 ReplicaSet 的原因。如果集群中应用数量很多,想节省资源可以把 revisionHistoryLimit 调小,但要明白调小之后过旧的版本将无法回滚,需要权衡使用。
除了回滚,Deployment 还支持暂停和恢复更新:kubectl rollout pause 和 kubectl rollout resume。这个功能在需要连续修改多处配置时很实用,先暂停更新,改完所有字段后再恢复,避免中间状态触发多次不必要的滚动更新。
五、配合 Service 对外提供服务
Deployment 本身只保证副本数量和版本管理,要让外部流量访问到这些 Pod,还需要配合 Service。最常用的是 ClusterIP 类型 Service,通过标签选择器把流量负载均衡到所有匹配的 Pod 上:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
这里 Service 的 selector 匹配 Pod 的标签 app: nginx,流量会自动分发到 Deployment 管理的所有副本。由于 Service 基于标签转发而非固定 Pod 地址,滚动更新期间新 Pod 就绪后会自动加入负载均衡,旧 Pod 终止前会被摘除,对外服务完全无感知。
总结一下,Deployment 是管理无状态服务的标准方案,掌握了 YAML 编写、扩缩容命令、滚动更新参数和回滚操作,就能应对绝大多数日常发布场景。实际生产中还可以进一步搭配 HPA 实现自动扩缩容,配合就绪探针保证新版本真正可用后再接收流量,这些进阶用法可以在此基础上逐步探索。
KubernetesDeployment滚动更新修改时间:2026-09-09 13:58:00