k8s控制器实战
K8s控制器核心原理与常用控制器完整笔记
一、控制器基础介绍
1.1 什么是控制器
控制器是K8s中用于自动化管理、持续维护资源期望状态的核心工具,全程无需人工干预,自动完成资源的调度、修复、更新、扩缩容等运维操作,是K8s集群自动化能力的核心支撑。
控制器整体分为两大类:
- 内置控制器
K8s原生自带,覆盖绝大多数常规业务场景,包含:ReplicaSet、Deployment、DaemonSet、StatefulSet、Job、CronJob、HPA等,每种控制器拥有独立、专属的资源管理逻辑,各司其职。
- 自定义控制器
针对复杂个性化业务场景,开发者基于K8s原生API自行开发的控制器,用于弥补内置控制器的能力短板,适配特殊业务需求。
1.2 为什么需要控制器管理资源
用户手动编写并提交K8s资源YAML,本质只是向Etcd数据库写入一条资源声明数据,仅完成资源的定义,并不会自动创建底层Pod、调度节点、维持资源运行状态。
而控制器的核心作用就是:持续监听对应资源的变更事件,根据用户定义的期望配置创建真实业务资源,并且永久维护资源运行状态,当资源异常、缺失、状态偏移时自动修复,实现集群全流程自动化运维。
1.3 控制器核心工作原理(调谐机制)
所有K8s控制器底层都遵循无限循环调谐逻辑,核心是持续对比资源的期望状态和当前实际状态,主动抹平二者的状态差异,保证集群运行状态始终贴合用户配置。
核心原理伪代码:
for {
desired := getDesiredState() # 期望状态:资源yaml中spec定义的配置
current := getCurrentState() # 当前实际状态:集群中status真实运行状态
if current == desired {
// 状态一致,无需操作
} else {
// 状态不一致,自动调谐,修正为期望状态
change current to desired status
}
}
工作流程:控制器持续watch监听指定资源类型 → 检测到资源新增、变更、删除事件 → 对比spec期望状态与status实际状态 → 自动完成资源创建、更新、删除、故障修复等调谐操作。
补充说明:watch监听是控制器的核心机制,无需轮询遍历集群资源,仅在资源发生变化时触发调谐,性能高效,是K8s集群稳定运行的核心保障。
二、常用内置控制器详解
2.1 ReplicaSet 副本控制器
核心功能:专门用于管理Pod副本数量,保证集群中始终维持指定数量的健康Pod,当Pod异常退出、被手动删除时,会自动重建Pod,维持副本数量稳定。
使用规范:ReplicaSet一般不独立使用,日常业务几乎全部通过Deployment间接管理ReplicaSet。Deployment通过控制ReplicaSet,实现版本迭代、滚动更新、版本回退等高级功能。
层级关系:Deployment → ReplicaSet → Pod
补充特性:ReplicaSet仅负责副本数量管控,不支持版本管理、滚动更新、灰度发布,功能单一,这也是其被Deployment替代独立使用的核心原因。
2.1.1 ReplicaSet 实验示例(完整可复现)
- 编写ReplicaSet完整YAML(rs-demo.yaml)
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: rs-demo
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: rs-demo
template:
metadata:
labels:
app: rs-demo
spec:
containers:
- name: nginx
image: nginx:1.18
- 创建资源
kubectl apply -f rs-demo.yaml
- 查看资源状态
kubectl get rs,pod
- 修改副本数量(两种方式)
方式一:直接修改YAML改replicas数值重新apply
方式二:命令行快速扩缩容
kubectl scale rs rs-demo --replicas=5
- 实验结论
ReplicaSet只会监听并响应 副本数量变化;如果仅修改Pod镜像、端口、标签等yaml配置,重新apply后,ReplicaSet不会触发更新,无法感知配置变化。即:ReplicaSet仅管控副本数,不支持业务配置迭代更新。
2.1.2 ownerReferenes 级联删除机制
ReplicaSet管理的Pod资源中,会自动携带 ownerReferenes 字段,记录上级控制器UID。
效果类似于数据库级联删除:
-
手动单独删除Pod,控制器调谐机制会立刻重建Pod,无法彻底删除
-
删除上级ReplicaSet资源,所有关联Pod会被自动级联删除
查看Pod归属关系命令:
kubectl get pod pod-name -o yaml | grep ownerReferences -A 5
2.2 Deployment 部署控制器(无状态服务核心)
Deployment是K8s管理无状态服务的核心控制器,依托ReplicaSet实现副本数量管理,核心优势是支持滚动更新和版本管理,实现业务不停机更新迭代,保障服务高可用。
资源层级:Deployment(顶层控制器)→ ReplicaSet(版本副本管理)→ Pod(业务容器)
2.2.1 Deployment 基础实验示例
- 基础部署yaml(deploy-demo.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-demo
namespace: default
spec:
replicas: 3
selector:
matchLabels:
app: deploy-demo
template:
metadata:
labels:
app: deploy-demo
spec:
containers:
- name: nginx
image: nginx:1.18
- 基础操作命令
# 创建
kubectl apply -f deploy-demo.yaml
# 查看
kubectl get deploy,rs,pod
# 删除
kubectl delete -f deploy-demo.yaml
2.2.2 Deployment 命名规则
Deployment更新时会生成新的ReplicaSet,命名规则:deploy名称 + 随机hash值
Pod标签中 pod-template-hash 是ReplicaSet自动添加的标签,用于精准匹配管理当前版本Pod。
查看Pod完整标签:
kubectl get pods --show-labels
2.2.3 Deployment 水平扩缩容(四种修改方式)
水平扩缩容仅修改副本数量,不改动业务版本,属于日常高频运维操作。
方式1:scale命令(最常用)
kubectl scale deployment deploy-demo --replicas=4
方式2:修改yaml文件后重新apply
方式3:kubectl edit 在线编辑实时保存
kubectl edit deploy deploy-demo
方式4:kubectl patch 打补丁(了解,极少用)
kubectl patch deploy deploy-demo -p '{"spec": {"replicas": 4}}'
查看扩缩容、更新实时进度:
kubectl rollout status deployment deploy-demo
kubectl get deploy,svc,pod
补充:水平扩缩容并不是Deployment核心能力,滚动更新、版本迭代、回退才是Deployment核心价值。
2.2.4 Deployment 滚动更新策略详解
更新策略定义在spec层级下,支持两种策略,默认滚动更新。
- Recreate 重建更新
更新逻辑:先批量删除所有旧版本Pod,全部销毁完成后,再批量创建新版本Pod。更新过程中集群无业务Pod运行,业务会完全中断,仅适用于测试环境、内网可停机业务。
- RollingUpdate 滚动更新(默认)
更新逻辑:新旧Pod交替替换,逐步迭代更新,全程保留可用Pod,实现不停机更新,保障生产环境业务高可用。可通过两个核心参数精准控制更新节奏:
-
maxSurge:最大超量Pod数。滚动更新时,可在spec.replicas预设副本数基础上,额外新建的最大Pod数量,用于控制新Pod创建速度,默认值1。支持百分比和整数两种配置方式。
-
maxUnavailable:最大不可用Pod数。滚动更新时,允许同时销毁的旧版本Pod最大数量,用于控制旧Pod销毁速度,默认值1。支持百分比和整数两种配置方式。
重要限制:maxSurge 和 maxUnavailable 不可以同时设置为0,否则无法完成滚动更新。
优化配置建议:
-
maxSurge:不建议超过现有副本总数,避免瞬时创建大量Pod抢占集群资源
-
maxUnavailable:保持少量不可用数量,保障更新期间业务可用率
-
minReadySeconds:新版本Pod就绪后,延迟指定时间再判定为正常运行,提升服务稳定性
滚动更新完整配置示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy-demo
namespace: default
spec:
replicas: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 3
selector:
matchLabels:
app: deploy-demo
template:
metadata:
labels:
app: deploy-demo
spec:
containers:
- name: nginx
image: nginx:1.18
2.2.5 滚动更新暂停与恢复
适用于灰度发布、分批更新场景,更新一半暂停,观察无误后继续发布。
# 暂停更新
kubectl rollout pause deployment deploy-demo
# 恢复更新
kubectl rollout resume deployment deploy-demo
2.2.6 Deployment 版本历史与回退
Deployment每次更新都会生成新ReplicaSet,保留历史版本,支持快速回滚。
# 查看版本历史
kubectl rollout history deployment deploy-demo
# 查看指定版本详情
kubectl rollout history deployment deploy-demo --revision=1
# 回退到上一个版本
kubectl rollout undo deployment deploy-demo
# 回退到指定版本
kubectl rollout undo deployment deploy-demo --to-revision=3
生产最佳实践:实际业务迭代不依赖命令行回退,直接修改正式YAML镜像版本重新apply,版本可控、可追溯。
2.3 DaemonSet 节点守护控制器
2.3.1 DaemonSet 核心特点与应用场景
核心特点:默认在集群所有可用节点上各运行一个Pod副本,节点新增时自动部署Pod,节点销毁时自动清理对应Pod;支持通过nodeSelector、节点亲和性筛选指定节点部署,实现定向部署。
典型应用场景:适用于所有节点需要常驻运行的基础组件、监控采集、运维工具类服务
-
集群网络组件:flanneld网络代理Pod、calico网络组件
-
流量转发组件:kube-proxy负载均衡Pod,负责集群内外流量转发
-
运维监控服务:节点日志采集、指标监控、审计服务
-
集群运维工具:节点巡检、漏洞扫描、安全监控服务
补充特性:DaemonSet不支持自定义副本数,副本数量由集群可用节点数量决定;不适用业务应用部署,仅适配节点级基础服务。
完整示例YAML
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ds
namespace: default
spec:
selector:
matchLabels:
k8s-app: nginx-ds
template:
metadata:
labels:
k8s-app: nginx-ds
spec:
containers:
- name: c1
image: nginx:1.18
2.3.2 标签筛选定向部署(指定节点运行)
默认所有节点部署,通过nodeSelector实现仅指定标签节点部署DaemonSet。
- 给节点打标签
kubectl label node node01 env=test
- DaemonSet配置nodeSelector匹配标签
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-ds
namespace: default
spec:
selector:
matchLabels:
k8s-app: nginx-ds
template:
metadata:
labels:
k8s-app: nginx-ds
spec:
nodeSelector:
env: test
containers:
- name: c1
image: nginx:1.18
2.3.3 DaemonSet 更新策略
支持两种更新策略:OnDelete、RollingUpdate
-
OnDelete:仅删除旧Pod后才会新建更新,更新被动触发
-
RollingUpdate:滚动更新(默认),支持配置maxUnavailable控制最大更新节点数
滚动更新配置示例:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 2
2.4 StatefulSet 有状态服务控制器
StatefulSet虽然具备固定域名、有序启停、持久化存储等优良特性,但生产使用率较低。因为有状态服务(数据库、中间件)场景复杂、差异性大,内置StatefulSet无法适配个性化复杂需求,复杂场景一般通过自定义控制器、中间件原生集群方案实现。
2.4.1 有状态与无状态服务区别
无状态服务:运行不依赖历史持久化数据,所有Pod实例完全一致,配置、数据相互独立可通用,Pod可随意漂移、扩容、销毁、重建,由Deployment专属管理,适用于Web服务、接口服务等常规业务。
有状态服务:运行依赖历史持久化数据,每个Pod拥有独立专属数据和身份标识,Pod无法随意漂移、重建,需要固定身份、固定存储、固定网络标识,由StatefulSet管理,适用于数据库、缓存、消息队列等中间件。
2.4.2 核心功能与使用场景
适用于常规轻量有状态服务,复杂分布式有状态业务仍需结合自定义控制器、中间件集群能力实现。
StatefulSet提供三大核心稳定能力,完美适配有状态服务运行需求:
-
稳定启停次序:多副本Pod按0、1、2...有序编号,严格顺序依次启动,销毁、缩容时逆序执行,启停过程有序可控,规避集群数据同步冲突。
-
稳定网络标识:每个Pod拥有固定不变的FQDN域名,Pod重启、重建后IP会变化,但域名永久固定,保障集群内服务访问稳定性。
-
稳定持久化存储:通过PVC模板为每个Pod独立创建专属PV,Pod之间存储完全隔离、互不共享;删除、缩容Pod时,不会销毁对应数据卷,持久化数据永久保留,避免数据丢失。
2.4.3 两大核心依赖组件
- Headless Service 无头服务
区别于普通Service,无头服务通过配置clusterIP: None实现,无负载均衡能力、无集群IP,核心作用是为每个Pod生成固定FQDN域名,支持集群内点对点精准访问单个有状态Pod,满足中间件集群节点通信需求。
-
上游访问者可以直接访问FQDN域名来访问pod,不需要svc做流量转发,没有负载均衡效果
-
无头服务需要绑定固定的pod名,也只有statefulset能创建固定名字的pod
- volumeClaimTemplates PVC模板
存储持久化核心组件,为每一个StatefulSet副本独立创建专属PVC/PV,Pod重启、重建后可自动绑定原有数据卷,保证数据不丢失,实现存储状态持久化。
- statefulset独有该字段,用于批量创建pvc,每个pod独占一个pvc,不共享存储
2.4.4 无头服务详解(重点补全)
无头服务的真正作用在于让每个pod都有一个固定不变的访问域名,实现精准单点访问。
FQDN固定域名格式
$(podname).(headless-svc-name).namespace.svc.cluster.local
示例:web-0.nginx.default.svc.cluster.local
普通Service vs 无头Service 访问区别(完整补全)
-
普通Service:域名经coredns解析为ClusterIP,通过IPVS负载均衡随机转发到后端任意Pod,实现流量均分,无法精准访问单个Pod,适配无状态服务。
-
无头Service:域名经coredns直接解析为对应Pod的真实IP,无IPVS负载均衡规则、无流量转发能力。DNS解析结果直接返回单个Pod真实IP,交由客户端自行处理访问逻辑,可直接精准访问任意单个有状态Pod,适配中间件集群节点两两通信、主从选举场景。
核心总结:普通SVC负责流量负载均衡,无头SVC负责有状态Pod固定身份标识。
补充说明:提前创建PV只是写入etcd声明数据,只有被PVC绑定使用时,才会真正落地创建存储资源。
2.4.5 StatefulSet 完整部署实验
- 无头服务yaml(必须提前创建)
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
ports:
- port: 80
name: web
targetPort: 80
clusterIP: None
selector:
app: nginx
- StatefulSet部署yaml(必须指定serviceName绑定无头服务)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
namespace: default
spec:
serviceName: "nginx" # 绑定无头服务,必须配置
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.18
- 部署命令
kubectl apply -f headless-svc.yaml
kubectl apply -f statefulset.yaml
kubectl get sts,pod,svc
2.4.6 验证存储稳定性实验
- 进入不同Pod写入独立测试数据
kubectl exec -it web-0 -- echo "pod0-data" > /usr/share/nginx/html/index.html
kubectl exec -it web-1 -- echo "pod1-data" > /usr/share/nginx/html/index.html
- 手动删除Pod
kubectl delete pod web-0 web-1
- 等待Pod重建完成,重新访问验证
结论:重建后Pod IP发生变化,但原有数据完全保留,互不干扰,实现状态持久化。
2.4.7 启停策略与更新策略
默认启停策略:串行启停,严格按照0、1、2顺序启动,逆序删除,保证集群数据同步安全。
并行启停配置(特殊场景使用):
spec:
podManagementPolicy: Parallel
更新策略:支持滚动更新,逻辑与Deployment类似,有序分批更新。
扩容说明:StatefulSet扩容受volumeClaimTemplates存储模板约束,若无StorageClass自动创建PV,手动扩容可能因PV未就绪卡住,串行模式下前一个Pod未就绪,下一个Pod不会启动。
扩容命令:
kubectl scale statefulset web --replicas=4
2.4.8 普通服务VS无头服务完整对比YAML
普通服务YAML
apiVersion: v1
kind: Service
metadata:
name: nginx1
namespace: default
labels:
app: nginx1
spec:
ports:
- port: 80
name: web
targetPort: 80
selector:
app: nginx
无头服务YAML
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
labels:
app: nginx
spec:
ports:
- port: 80
name: web
targetPort: 80
clusterIP: None
selector:
app: nginx
2.5 Job 与 CronJob 任务控制器
Job:一次性任务控制器,用于执行单次、短周期的离线任务。创建Pod执行任务,任务执行成功后Pod正常退出,不会自动重启;任务失败可配置重试策略,适用于数据备份、脚本执行、一次性初始化任务。
CronJob:周期性任务控制器,基于Linux crontab定时规则,周期性自动创建Job执行任务,任务执行完成后自动销毁资源,适用于定时备份、定时清理、定时巡检等周期运维场景。
层级关系:CronJob → Job → Pod
补充区别:常驻服务控制器(Deployment/StatefulSet)保证Pod永久运行,任务类控制器(Job/CronJob)保证任务执行完成即可退出,核心目标完全不同。
2.6 HPA 弹性扩缩容控制器
HPA(Horizontal Pod Autoscaler)即Pod水平自动扩缩容控制器,可实时监控集群资源指标(CPU使用率、内存使用率、QPS流量等),根据用户预设的阈值规则,自动对Deployment、StatefulSet等控制器管理的Pod进行副本扩容和缩容,实现业务弹性伸缩,流量高峰自动扩容承压,流量低谷自动缩容节省资源。
补充特性:HPA仅支持Pod水平扩缩容(增减副本数),不支持单Pod资源垂直扩容;适配互联网波动流量业务,实现资源利用率最大化与业务高可用平衡。
三、六大内置控制器核心总结(背诵重点)
- ReplicaSet:仅管理Pod副本数量,无高级功能,不独立使用,为Deployment底层依赖。
- Deployment:无状态服务首选,支持滚动更新、版本回退,生产环境业务核心控制器。
- DaemonSet:节点级常驻服务专用,每节点运行一个Pod,适配基础组件、监控采集。
- StatefulSet:有状态服务专用,提供有序启停、固定域名、持久化存储,适配中间件。
- Job:一次性离线任务专用,任务完成即退出。
- CronJob:周期性定时任务专用,基于crontab规则循环执行任务。
- HPA:弹性扩缩容专用,根据负载自动调整Pod副本数。

浙公网安备 33010602011771号