Kubernetes Deployment 基础:资源定义、ReplicaSet 与 Pod 的关系、滚动更新策略
Deployment 是 Kubernetes 中用于声明式管理无状态工作负载的核心资源。它通过控制器模式驱动集群状态向期望状态收敛,是灰度升级、回滚、扩缩容等高级运维操作的基础。理解 Deployment 的底层机制,是诊断连接池泄漏等运行时问题的前提。
2.1 Deployment 资源定义
一个标准的 Deployment YAML 清单包含四个关键部分:apiVersion、kind、metadata 和 spec。其中 spec 内部又嵌套了 replicas、selector、template 和 strategy 等字段。
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:1.0.0
ports:
- containerPort: 8080
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
关键字段说明:
replicas:期望运行的 Pod 副本数。selector.matchLabels:Deployment 通过此标签选择器管理其下属的 ReplicaSet 和 Pod。template:Pod 模板,定义了每个 Pod 的容器、挂载卷、资源限制等。strategy:更新策略,决定了如何从旧版本切换到新版本。
2.2 ReplicaSet 与 Pod 的关系
Deployment 并不直接管理 Pod。它通过 ReplicaSet 作为中间层来管理 Pod 的创建、删除和副本数控制。这种分层设计使得 Deployment 能够实现版本追踪、回滚和滚动更新。
| 组件 | 职责 | 生命周期 |
|---|---|---|
| Deployment | 声明期望状态(副本数、镜像版本、更新策略),驱动 ReplicaSet 变更 | 长期存在,版本管理 |
| ReplicaSet | 确保指定数量的 Pod 副本运行,负责 Pod 的创建与删除 | 每次更新生成新的 ReplicaSet,旧版本保留用于回滚 |
| Pod | 运行容器实例,承载应用进程和网络栈 | 短暂、可被替换,由 ReplicaSet 控制 |
连接池泄漏关联: 在灰度升级过程中,旧 ReplicaSet 缩容时,其管理的 Pod 会被终止。如果应用在 Pod 终止前未正确关闭连接池(如数据库连接、HTTP 长连接),就会导致连接泄漏。新 ReplicaSet 扩容时,新 Pod 可能因连接池耗尽而无法建立新连接。
2.3 滚动更新策略
滚动更新(RollingUpdate)是 Deployment 默认的更新策略。它通过逐步替换旧版本 Pod 为新版本 Pod,实现零停机或有限停机升级。策略由两个关键参数控制:maxUnavailable 和 maxSurge。
| 参数 | 含义 | 默认值 | 示例(replicas=3) |
|---|---|---|---|
maxUnavailable |
更新过程中允许不可用的最大 Pod 数量(值或百分比) | 25% | 设为 1 时,最多 1 个 Pod 不可用 |
maxSurge |
更新过程中允许超出期望副本数的最大 Pod 数量(值或百分比) | 25% | 设为 1 时,最多 4 个 Pod 同时运行 |
连接池泄漏风险点: 滚动更新过程中,旧 Pod 被终止(
TERM 信号)与新 Pod 启动(建立连接池)存在时间重叠。如果旧 Pod 的连接池未在 preStop 钩子中优雅关闭,而新 Pod 又尝试建立新连接,可能导致连接池资源耗尽或端口冲突。
2.4 更新策略对比
| 策略类型 | 行为 | 适用场景 | 连接池影响 |
|---|---|---|---|
| RollingUpdate | 逐步替换 Pod,可控制速率 | 生产环境默认策略,灰度升级 | 需配合 preStop 和 readinessProbe 防止泄漏 |
| Recreate | 先删除所有旧 Pod,再创建新 Pod | 开发环境、非关键业务 | 连接池瞬间全部释放,可能导致服务中断 |
最佳实践: 在 Deployment 的
spec.template.spec.containers.lifecycle.preStop 中实现连接池优雅关闭逻辑,并设置 terminationGracePeriodSeconds 足够长以完成连接释放。同时,readinessProbe 应检查连接池健康状态,避免新 Pod 过早接收流量。