Kubernetes Deployment 是用于管理无状态应用的工作负载资源对象。它并不直接创建 Pod,而是在底层创建 ReplicaSet,再由 ReplicaSet 创建和维护 Pod。这样分层的好处是,Deployment 可以专注于版本管理和发布策略,而副本数量的稳定性交给 ReplicaSet。对新手来说,理解 Deployment 相当于掌握了 Kubernetes 应用发布的核心入口。

在开始之前,建议你有一个可用的 Kubernetes 集群,可以是 minikube、kind 或云厂商的托管集群。确保 kubectl 已正确连接到集群,并且有权限创建 Deployment。接下来会围绕一个 nginx 应用展开,所有命令都可以直接复制执行。
一、为什么需要 Deployment:从裸 Pod 到控制器的演进
直接创建 Pod 看起来最简单,但 Pod 一旦被删除、所在节点宕机或发生驱逐,Kubernetes 不会自动把它重新拉起来。如果手动创建多个 Pod 副本来应对流量,更新镜像版本时只能一个个删除再创建,非常容易造成服务中断。即使使用 ReplicaSet 固定副本数,它也只能保证数量,无法在镜像更新时自动完成灰度替换,仍然需要人工介入。
Deployment 的价值在于把期望状态声明出来,剩下的协调工作交给控制循环。你只需要告诉集群需要几个副本、运行哪个镜像、使用什么更新策略,Deployment 控制器就会持续调整实际状态向期望状态收敛。这个过程被称为声明式管理,它避免了手工运维中的大量重复操作和误操作风险。
从对象层级看,Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod。每次 Deployment 的模板发生变更,比如镜像标签变化,就会生成一个新的 ReplicaSet。旧的 ReplicaSet 不会立刻被删除,而是根据滚动更新策略逐步缩容,这为回滚保留了历史依据。
二、创建第一个 Deployment:YAML 字段与执行流程
下面是一个最小的 Deployment 配置示例,文件名为 nginx-deploy.yaml。它声明 3 个 nginx 副本,使用 nginx:1.24.0 镜像,容器暴露 80 端口。注意 labels 和 selector 必须匹配,否则 Deployment 无法找到它管理的 Pod,会导致副本数异常。
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.24.0
ports:
- containerPort: 80
核心字段解释如下:apiVersion 指定资源所属 API 组和版本,Deployment 使用 apps/v1;kind 声明资源类型;metadata.name 是 Deployment 的名称;spec.replicas 是期望副本数;spec.selector.matchLabels 用于筛选 Pod 标签;spec.template 定义 Pod 模板,里面的 labels 必须满足 selector。容器部分与标准 Pod 规格一致,包括镜像、端口、环境变量和资源限制等。
保存文件后执行 kubectl apply -f nginx-deploy.yaml 创建资源。apply 是声明式命令,如果资源已存在会进行差异化更新。随后可以运行 kubectl get deploy nginx-deploy、kubectl get rs 和 kubectl get pods 查看 Deployment、ReplicaSet 和 Pod 的状态。刚创建时 Pod 可能处于 ContainerCreating 阶段,稍等几秒后会进入 Running。
kubectl apply -f nginx-deploy.yaml kubectl get deploy nginx-deploy kubectl get rs -l app=nginx kubectl get pods -l app=nginx
如果看到 READY 列为 3/3,说明三个副本都已就绪。如果 READY 一直没有达到期望值,可以使用 kubectl describe deploy nginx-deploy 查看事件,通常镜像拉取失败、资源不足或探针失败是最常见的原因。
三、滚动更新:参数含义与实际发布过程
当需要升级应用时,最简单的做法是修改 Deployment 的镜像版本。例如执行 kubectl set image deployment/nginx-deploy nginx=nginx:1.25.3,该命令会把容器 nginx 的镜像更新为 nginx:1.25.3。Deployment 控制器检测到模板变化后,会创建一个新的 ReplicaSet,并按照滚动更新策略逐步将旧 Pod 替换为新 Pod。
kubectl set image deployment/nginx-deploy nginx=nginx:1.25.3 kubectl rollout status deployment/nginx-deploy
滚动更新的默认行为是一次替换 25% 的 Pod。这个比例由 spec.strategy.rollingUpdate 下的两个参数控制:maxSurge 表示更新过程中允许超出期望副本数的最大数量或百分比,maxUnavailable 表示更新过程中允许不可用的最大数量或百分比。例如 replicas 为 4,maxSurge 为 1,maxUnavailable 为 0,升级时会先创建一个新 Pod,等待就绪后再删除一个旧 Pod,如此循环直到全部替换完成。这样可以保证服务始终有足够副本在运行。
如果希望更精细地控制发布节奏,可以在 YAML 中显式配置策略。下面示例将 maxSurge 和 maxUnavailable 都设为 25%。这两个字段支持整数或百分比,百分比会基于副本数向上取整。需要注意,maxUnavailable 设置为 0 时,升级过程中任何时间都不会出现副本数不足,但需要集群有额外资源容纳 maxSurge 创建出的临时 Pod。
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
发布过程中可以随时运行 kubectl get pods -w 观察新旧 Pod 的交替。由于 Deployment 会保留旧 ReplicaSet,当新版本出现问题时,旧 Pod 并不会全部被销毁,这为快速回滚提供了基础。生产环境中建议结合就绪探针使用,只有新 Pod 真正可以对外服务后,才允许继续缩容旧版本。
四、回滚、扩缩容与日常排查
如果升级后发现新版本有问题,例如启动报错、接口异常或资源消耗飙升,可以使用 kubectl rollout undo deployment/nginx-deploy 回滚到上一个版本。这个操作会让 Deployment 重新调整新旧 ReplicaSet 的副本数,把流量切回旧 Pod。回滚过程同样遵循滚动策略,不会造成整个服务瞬间中断。
kubectl rollout undo deployment/nginx-deploy kubectl rollout history deployment/nginx-deploy kubectl rollout undo deployment/nginx-deploy --to-revision=2
查看发布历史有助于定位问题。history 命令会列出 Deployment 的修订记录,每次模板变更都会生成一个新 revision。使用 --to-revision 可以回滚到指定历史版本,而不仅仅是上一个版本。需要特别注意的是,revision 记录的数量受资源对象中 revisionHistoryLimit 字段限制,默认保留 10 个。
扩缩容同样非常直接。执行 kubectl scale deployment/nginx-deploy --replicas=5 就可以把副本数从 3 调整到 5。这个操作不会创建新的 ReplicaSet,因为 Pod 模板没有变化,只改变 replicas 字段。如果希望保留修改记录,也可以编辑 YAML 后重新 apply。日常排查时,kubectl describe deploy 和 kubectl logs -l app=nginx 是最常用的两个命令,前者展示事件和状态,后者查看应用日志。
删除 Deployment 时默认会级联删除它管理的 ReplicaSet 和 Pod。如果只想删除 Deployment 但保留 Pod,可以执行 kubectl delete deploy nginx-deploy --cascade=orphan。不过保留的 Pod 将失去控制器管理,之后需要手动清理。初学者建议直接使用默认级联删除,避免留下难以追踪的孤儿 Pod。
五、Deployment 使用建议与常见误区
第一,始终通过修改 Deployment 的 Pod 模板来触发更新,而不是手动删除 Pod。手动删除 Pod 后 ReplicaSet 会立即用旧模板重新创建,版本并不会升级。第二,labels 和 selector 一旦创建后不建议随意修改。如果必须修改选择器,需要先删除 Deployment 再重新创建,否则会导致控制器失去对已有 Pod 的追踪。
第三,生产环境应为容器配置 resources 和 readinessProbe。滚动更新只有在 Pod 就绪后才会继续,如果没有就绪探针,Pod 可能刚启动还未真正可服务就被纳入流量,导致短暂错误。第四,合理设置 revisionHistoryLimit,保留过多历史 ReplicaSet 会占用 etcd 存储并增加管理复杂度。
Deployment 适合无状态应用,如果应用需要稳定的网络标识、持久化存储或有序启停,StatefulSet 会是更合适的选择。但大多数 Web 服务、API 网关和微服务无状态组件,都应该优先使用 Deployment 来管理。理解 Deployment 的声明式模型和滚动更新机制,是进一步学习 Service、Ingress 和 Helm 的基础。
Kubernetes Deployment滚动更新容器编排修改时间:2026-08-24 21:52:01