一、为何需要 K8s 控制器?—— 解决自主式 Pod 的痛点
在直接创建kind:Pod类型的自主式Pod时,存在一个·关键问题:若Pod因故障或误操作被删除,将无法自动恢复,这对线上业务的稳定性而言风险极高。而K8s控制器的核心价值,就在于代用户管理Pod生命周期:实时监测Pod运行状态,当Pod故障时自动重启或重新部署;当Pod故障时自动重启或重新部署;当Pod副本数低于期望数量时自动补全,高于期望数量时自动终止,确保Pod始终处于用户定义的“目标状态”。其中ReplicaSet与Deployment是管理Pod最核心、最常用的两类控制器。
二、ReplicaSet 控制器:概念、原理解读
2.1 ReplicaSet概述
在K8s的Pod管理体系中,ReplicaSet(简称RS)是承担“副本保障”核心职责的基础控制器,其设计初衷是解决“自主式Pod故障无法自愈”的痛点---通过持续监控与动态调整,确保集群中目标Pod的副本数量始终匹配用户预设值,为业务稳定性提供基础支撑。
从核心功能来看,RS的作用可拆解为三点:
-
副本数量管控:用户定义期望的 Pod 副本数后,ReplicaSet 会实时比对 “当前运行的 Pod 数” 与 “期望数”,若副本数不足(如 Pod 因节点故障被删除、容器崩溃),则自动基于 Pod 模板新建 Pod;若副本数超出(如手动误创建多余 Pod),则自动终止超额 Pod,实现 “多退少补” 的动态平衡。
-
Pod 状态监听:通过 K8s 的 API Server 持续获取所管理 Pod 的运行状态(如 Running、CrashLoopBackOff、Terminating),当检测到 Pod 故障(如容器退出且重启策略不生效)时,会尝试重启 Pod 容器;若重启无效(如镜像拉取失败、配置错误),则触发重新调度,在集群其他可用节点上创建新 Pod。
-
标签关联管理:ReplicaSet 通过 “标签选择器(Label Selector)” 锁定需管理的 Pod,仅对匹配指定标签(如
app: web
)的 Pod 进行监控与调整,这一机制确保了控制器与 Pod 的精准绑定,避免不同业务的 Pod 被误管理。
需要特别注意的是,K8s官方并不推荐直接使用RS,而是建议优先选择Deployment控制器。这是因为Deployment是构建在RS之上的高级控制器,不仅继承了RS的所用副本控制能力,还新增了三个特性:
-
声明式更新:支持通过修改资源清单(YAML)或命令行补丁(
kubectl patch
)更新 Pod 配置,且所有变更会被记录,避免手动操作导致的配置丢失; -
版本化管理:每次更新 Pod(如修改镜像版本)时,Deployment 会创建新的 ReplicaSet,保留旧 ReplicaSet 的历史版本,支持一键回滚到之前的稳定状态;
-
灵活更新策略:提供 “滚动更新(RollingUpdate)” 和 “重建更新(Recreate)” 两种模式,可通过
maxSurge
和maxUnavailable
控制更新节奏,实现零停机升级。
2.2 ReplicaSet 资源清单核心字段解析
编写RS资源编写 ReplicaSet 资源清单(YAML 文件)的核心是明确 “哪些字段是必填项”“各字段的配置逻辑”,可通过kubectl explain rs
系列命令快速查询字段含义与约束,以下是关键字段的分层解析:
(一)顶层必选字段:资源身份定义
字段 | 含义与配置要求 | 示例值 |
---|---|---|
apiVersion | 资源对应的 API 版本,ReplicaSet 固定为apps/v1 (需与kubectl explain rs 显示的 VERSION 一致) | apiVersion: apps/v1 |
kind | 资源类型,明确创建的是 ReplicaSet | kind: ReplicaSet |
metadata | 资源元数据,至少需配置name (控制器名称,需唯一),可选配置labels (用于资源分类) | metadata: {name: frontend, labels: {app: guestbook, tier: frontend}} |
(二)spec 核心字段:副本管理与 Pod 模板
spec
是 ReplicaSet 的 “功能核心区”,定义了 “期望副本数、管理哪些 Pod、如何创建 Pod”,其中selector
(标签选择器)为必填项,且存在严格约束:
-
replicas
:期望的 Pod 副本数,默认值为 1,配置时需根据业务并发需求设定(如测试环境 1 个,生产环境 3 个),示例:replicas: 3
; -
selector
:标签选择器,用于锁定需管理的 Pod,仅支持matchLabels
(精确匹配标签),必须与spec.template.metadata.labels
完全匹配,否则 K8s 会拒绝创建 ReplicaSet,示例:selector: {matchLabels: {tier: frontend}}
; -
template
:Pod 模板(PodTemplate),定义新 Pod 的创建规则,内部包含metadata
(Pod 标签)和spec
(Pod 内容器配置),是 ReplicaSet “生成 Pod” 的依据,示例:
template:
metadata:
labels:
tier: frontend # 需与selector.matchLabels一致
spec:
containers: # 容器配置,至少需包含name和image
- name: php-redis # 容器名称,唯一
image: docker.io/library/nginx:latest # 容器镜像
imagePullPolicy: IfNotPresent # 镜像拉取策略(本地有则不拉取,推荐生产使用)
(三)关键约束提醒:避免配置错误
-
标签一致性:
spec.selector.matchLabels
与spec.template.metadata.labels
必须完全匹配(如均为tier: frontend
),否则会报 “selector does not match template labels” 错误; -
容器必填项:
spec.template.spec.containers
中,name
(容器名)和image
(镜像地址)为必填项,缺失会导致 Pod 创建失败; -
状态字段不可改:
status
字段用于显示 ReplicaSet 的实时状态(如当前副本数、就绪数),由 K8s 自动维护,不可在清单中手动配置。
2.3、标准 ReplicaSet 资源清单示例(含完整注释)
# 1. 资源身份定义
apiVersion: apps/v1
kind: ReplicaSet
# 2. 资源元数据
metadata:
name: frontend # ReplicaSet控制器名称,需在命名空间内唯一
labels:
app: guestbook # 业务标签:标识属于guestbook应用
tier: frontend # 层级标签:标识属于前端服务
# 3. 副本管理与Pod模板(核心功能区)
spec:
replicas: 3 # 期望3个Pod副本,实现高可用
# 标签选择器:仅管理带有“tier: frontend”标签的Pod
selector:
matchLabels:
tier: frontend
# Pod模板:新Pod的创建规则
template:
metadata:
# Pod标签:必须与selector.matchLabels一致,否则控制器无法管理
labels:
tier: frontend
spec:
# 容器配置:前端服务使用nginx镜像
containers:
- name: php-redis # 容器名称,需在Pod内唯一
image: docker.io/library/nginx:latest # 容器镜像(指定仓库地址,避免拉取失败)
imagePullPolicy: IfNotPresent # 镜像拉取策略:本地有则不拉取,节省带宽
ports: # 可选配置:暴露容器端口(便于后续Service关联)
- name: http # 端口名称,便于识别
containerPort: 80 # 容器内应用监听的端口
创建命令与验证:
# 应用清单创建ReplicaSet
kubectl apply -f replicaset.yaml
# 验证ReplicaSet状态:DESIRED=期望数,CURRENT=当前数,READY=就绪数
kubectl get rs
# 验证Pod状态:Pod名称格式为“ReplicaSet名称-随机字符串”
kubectl get pods
三、ReplicaSet 管理 Pod 实操:扩容、缩容与更新
ReplicaSet 的核心价值是 “动态管理 Pod 生命周期”,无需手动创建 / 删除 Pod,通过修改配置即可实现副本数调整与镜像更新,以下是具体操作方法:
(一)动态扩容 / 缩容:调整 Pod 副本数
两种操作方式均支持实时生效,推荐生产环境使用 “修改清单文件”(便于版本控制),应急场景使用 “实时编辑”(快速生效):
-
方式 1:修改清单文件(推荐)
编辑replicaset.yaml
中的replicas
值(如从 3 改为 4),执行kubectl apply -f replicaset.yaml
,K8s 会自动创建新 Pod;缩容时将replicas
改小(如从 4 改为 2),K8s 会自动终止超额 Pod。 -
方式 2:实时编辑控制器(应急)
执行kubectl edit rs frontend
(frontend
为 ReplicaSet 名称),在编辑界面修改spec.replicas
的值(如改为 5),保存退出后,K8s 会立即调整 Pod 数量,验证命令:
# 查看调整后的ReplicaSet状态
kubectl get rs frontend
# 查看新增的Pod
kubectl get pods -l tier=frontend # 通过标签筛选控制器管理的Pod
(二)Pod 镜像更新:替换容器镜像
ReplicaSet 的镜像更新需注意:仅对新创建的 Pod 生效,已运行的旧 Pod 需手动删除,步骤如下:
-
修改镜像配置
执行kubectl edit rs frontend
,找到spec.template.spec.containers.image
,将镜像改为目标版本(如从nginx:latest
改为docker.io/library/tomcat:8.5-jre8-alpine
),保存退出; -
验证配置生效
执行kubectl get rs frontend -o wide
,查看IMAGES
字段是否变为新镜像,示例输出:
NAME DESIRED CURRENT READY IMAGES
frontend 2 2 2 docker.io/library/tomcat:8.5-jre8-alpine
3.替换旧Pod
旧 Pod 仍使用原镜像,需手动删除,ReplicaSet 会基于新模板创建新 Pod:
# 删除旧Pod(可通过kubectl get pods获取旧Pod名称)
kubectl delete pods frontend-glb2c
# 验证新Pod创建:新Pod名称与旧Pod不同,镜像为新版本
kubectl get pods -o wide
(三)生产环境更新建议:避免手动操作风险
ReplicaSet 的镜像更新需 “手动删除旧 Pod”,存在操作繁琐、易出错的问题,生产环境推荐两种优化方案:
-
蓝绿发布:创建两个 ReplicaSet(RS1 为旧版本,RS2 为新版本),通过修改 Service 的标签选择器,将流量从 RS1 切换到 RS2,实现 “零停机更新”,切换失败可快速切回;
-
使用 Deployment:Deployment 是 ReplicaSet 的高级封装,支持 “滚动更新”(自动创建新 Pod、删除旧 Pod,无需手动干预)和 “版本回滚”(更新失败可一键恢复旧版本),完全规避 ReplicaSet 的手动操作风险。
三、Deployment 控制器:概念与原理解读
3.1 Deployment 概述
Deployment 是 Kubernetes 中最核心、最常用的工作负载控制器,它为 ReplicaSet 和 Pod 提供了声明式的生命周期管理。通过 Deployment,你可以轻松定义应用的期望状态,Kubernetes 会自动协调实际状态向期望状态演进,无需手动干预复杂的 Pod 调度和维护过程。
核心特性与价值
Deployment 构建在 ReplicaSet 之上,继承了其副本数量管理能力,同时增加了多项关键特性:
-
声明式更新:通过修改 YAML 配置文件定义期望状态,使用
kubectl apply -f
命令即可完成更新,无需手动操作 Pod 或 ReplicaSet -
滚动升级:支持零停机更新应用,通过控制新老 Pod 的替换节奏,确保服务持续可用
-
版本回滚:保留历史版本记录,当新版本出现问题时,可快速回滚到之前的稳定版本
-
自动修复:当 Pod 或节点发生故障时,会自动创建新的 Pod 以维持期望的副本数量
工作原理
Deployment 采用分层管理架构,形成 "Deployment → ReplicaSet → Pod" 的管控链:
- 每个 Deployment 管理多个 ReplicaSet,每个 ReplicaSet 对应应用的一个版本
- 每次更新应用(如修改镜像版本),Deployment 会创建一个新的 ReplicaSet
- 新 ReplicaSet 逐步创建新 Pod,同时旧 ReplicaSet 逐步删除旧 Pod
- 同一时刻只有一个 ReplicaSet 处于活跃状态(管理运行中的 Pod)
- 历史 ReplicaSet 会被保留(默认保留 10 个),以便需要时回滚
这种设计使得应用更新过程安全可控,即使新版本出现问题,也能通过回滚机制迅速恢复服务。
3.2 Deployment 更新节奏与更新逻辑
3.2.1、核心定义
-
更新节奏:控制更新时 Pod 数量的波动范围(最多超配多少、最少保留多少可用),决定更新速度与资源占用上限。
-
更新逻辑:新老 Pod 的替换规则,核心是 “先确保新 Pod 可用,再删旧 Pod”,避免服务中断。
3.2.2、更新节奏:2 个关键参数
通过 spec.strategy.rollingUpdate
配置,支持整数或百分比(如 5、20%):
参数 | 作用 | 默认值 | 示例(5 个 Pod) |
---|---|---|---|
maxSurge | 最多可超出期望副本数的 Pod 数(限制资源过载) | 25% | 设 1→最多 6 个 Pod |
maxUnavailable | 最少需保留的可用 Pod 数(保障服务稳定) | 25% | 设 0→始终 5 个可用 |
3.2.3、更新逻辑:3 个核心机制
-
健康探测:新 Pod 需通过
readinessProbe
(就绪探针,如探测 80 端口)才会被启用,避免 “假活”; -
ReplicaSet 协调:先扩新 ReplicaSet(新版本),再缩旧 ReplicaSet(旧版本),循环直到替换完成;
-
故障保护:新 Pod 启动失败 / 更新超时会自动停止,旧 Pod 继续服务,防止故障扩散。
4、Deployment 资源清单编写技巧:核心字段与配置指南
4.1、清单清单结构核心组成
Deployment 资源清单由 5 个顶层字段构成,核心配置集中在spec
:
apiVersion: apps/v1 # 固定版本
kind: Deployment # 资源类型
metadata: # 元数据(名称、命名空间等)
spec: # 核心配置区(副本数、更新策略等)
status: # 状态字段(自动生成,不可配置)
4.2、spec 关键字段解析(按重要性排序)
1. 核心必选字段
字段 | 作用 | 示例 |
---|---|---|
replicas | 期望 Pod 副本数 | replicas: 3 |
selector | 标签选择器(需匹配 Pod 模板标签) | selector: {matchLabels: {app: nginx}} |
template | Pod 模板(定义 Pod 配置) | 包含metadata.labels 和spec.containers |
2. 更新策略配置(strategy
)
控制 Pod 更新方式,默认RollingUpdate
(滚动更新):
strategy:
type: RollingUpdate # 可选Recreate(重建式更新)
rollingUpdate:
maxSurge: 1 # 最多超配1个Pod(或20%)
maxUnavailable: 0 # 最少保持全量可用(或0%)
3. 版本管理与控制
revisionHistoryLimit: 5
:保留 5 个历史版本(默认 10 个)minReadySeconds: 30
:新 Pod 就绪后等待 30 秒再继续更新progressDeadlineSeconds: 300
:更新超时时间(300 秒未完成则标记异常)paused: false
:是否暂停更新(临时调试时设为 true)
4.3、Pod 模板(template
)配置要点
spec.template
定义 Pod 的创建规则,与独立 Pod 清单类似但无需 apiVersion 和 kind:
template:
metadata:
labels:
app: nginx # 必须匹配spec.selector.matchLabels
spec:
containers: # 至少一个容器,必填name和image
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
readinessProbe: # 就绪探针(更新必备)
tcpSocket: {port: 80}
initialDelaySeconds: 10
5、完整示例清单(含注释)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: default
spec:
replicas: 3 # 3个副本
revisionHistoryLimit: 5 # 保留5个历史版本
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 1 # 最多超配1个
maxUnavailable: 0 # 不允许不可用
type: RollingUpdate
template:
metadata:
labels:
app: nginx # 与selector匹配
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
readinessProbe: # 确保新Pod就绪后再替换旧Pod
tcpSocket:
port: 80
initialDelaySeconds: 10
periodSeconds: 5
5、编写注意事项
- 标签一致性:
spec.selector.matchLabels
必须与template.metadata.labels
完全一致 - 探针配置:生产环境务必添加
readinessProbe
,避免新 Pod 未就绪就接收流量 - 更新策略:核心服务建议
maxUnavailable: 0
,非核心服务可放宽以加速更新 - 版本控制:通过
revisionHistoryLimit
控制历史版本数量,避免占用过多资源
通过kubectl explain deployment.spec
可随时查询字段详情,按需扩展配置(如亲和性、资源限制等)。
注:点赞+关注+收藏,下期我们接着讲工作负载,不见不散。