一、什么是控制器
控制器是Kubernetes控制平面(Control Plane)上一种常驻运行的、基于事件驱动的控制循环(Control Loop) 。它通过监视集群的共享状态(通过API Server获取),并将系统的当前实际状态 (Actual State)持续修正至用户所声明的期望状态 (Desired State)。这是Kubernetes实现声明式API 和自动化运维的核心执行引擎。
简单来说控制器就是一个**"永不睡觉的纠偏机器"**。你给它一张"理想蓝图"(比如:我要3个Pod),它就瞪大了眼睛盯着现实(现在只有2个Pod)。只要发现蓝图和现实对不上,它二话不说立马动手,直到现实完全符合蓝图为止。它只管"纠错",至于纠错的过程,它自己看着办,不用你操心。
二、工作机制
控制器的核心逻辑是基于调谐循环(Reconcile Loop) 的迭代过程。其标准工作流包含以下三个连续步骤:
观察(Observe):通过List-Watch机制从API Server获取特定资源的期望状态(Spec)和当前状态(Status)。
对比(Diff):比较期望状态与当前实际状态,计算两者之间的偏差。
执行(Act):根据偏差调用相应的API接口执行动作(如创建、更新、删除Pod),直至偏差归零。
三、执行权限
控制器本身是一个运行在集群中的普通Pod,它之所以拥有操作资源的权限,是因为在启动时通过ServiceAccount(服务账号) 绑定了RBAC(基于角色的访问控制)策略。该策略赋予了控制器对特定资源(如Pod、ReplicaSet等)进行增、删、改、查的授权。
也就是说控制器也是个打工的,只不过它入职的时候,领导给它发了一个**"高级操作证"(ServiceAccount)**。这张证上写明了它的权限:"允许创建Pod、允许删除Pod、允许修改Deployment"。所以它干活的时候,系统认它的证不认人,它就有权利去指挥集群里的各种资源。
四、控制器种类
1.ReplicaSet(副本集)
ReplicaSet的核心职责是确保集群中任何时刻都有指定数量的Pod副本在运行。它通过标签选择器(Label Selector)来识别并管理属于自己管辖的Pod。当Pod因故障或被删除导致数量不足时,ReplicaSet会触发新Pod的创建;当数量过剩时(比如手动多创建了一个),它会主动终止多余的Pod。
关键要点 :在实际生产环境中,没有人会单独创建ReplicaSet。因为Deployment底层会自动创建和管理ReplicaSet,我们只需要跟Deployment打交道就行。说白了,ReplicaSet是给Deployment当小弟用的。






2.Deployment ------ 手握大权的"项目经理"
Deployment是建立在ReplicaSet之上的更高级控制器,它实现了Pod的声明式更新(Declarative Update)。当用户修改Deployment的Pod模板(如镜像版本)时,Deployment会启动滚动更新(RollingUpdate)过程,通过创建新的ReplicaSet并逐步缩减旧的ReplicaSet来实现零宕机发布。同时,每次更新都会生成一个"修订版本号"(Revision),供用户随时进行版本回退。
也就是说,Deployment是真正的老板。他不会直接管干活的Pod,而是指挥手下的小组长(ReplicaSet)去干活。
(1)升级(滚动更新) :
老板要换新机器(新版本)。他不懂技术,但他懂管理。他的策略是:先找几个新人(新版本Pod)在旁边试用,等确认新人能干活了,再踢走几个旧人(旧版本Pod) 。如此循环,始终保持总人数不变,且始终有人在岗。这就是滚动更新------用户根本感觉不到服务中断。
如果你没耐心等滚动过程,只想赶紧全换完(比如在测试环境),可以设置更新策略为Recreate。这个策略粗暴得很:先把所有旧Pod全干掉,再一起起新Pod。这中间会有一段服务完全不可用的时间,所以生产环境基本不用,只有测试环境图省事才用。





2. 回滚 :
老板发完新机器,发现新机器有严重Bug,冒烟了。这时候他有"后悔药"------直接敲命令kubectl rollout undo。老板立刻翻出上一次的施工记录(历史Revision),指挥小组长把Pod恢复成以前的样子。整个过程跟升级一样,也是平滑的,不会造成新的中断。

3.版本更新管理及优化
(1)查看更新策略信息
通过kubectl rollout status命令可以实时查看滚动更新的进度;通过kubectl rollout history命令可以查看Deployment的所有历史修订版本记录。

(2)设定更新策略
更新策略在Deployment的spec字段中定义,核心参数有两个:maxSurge(最大激增数)和maxUnavailable(最大不可用数)。这两个参数共同决定了滚动更新的速度和对服务的影响面。
这两个值决定了你是"求稳"还是"求快"。求稳就把maxUnavailable设成0,maxSurge设小一点(比如1或10%),这样更新过程极其平滑,但耗时较长;求快就把maxSurge设大一点,但会占用额外系统资源。

3. 更新暂停和恢复(金丝雀发布的核心)
kubectl rollout pause命令可以暂停当前的滚动更新,使Deployment维持在更新过程中的某个中间状态。此时,虽然新的Pod已经创建,但旧的Pod尚未完全销毁。结合流量管理(如Service的权重),可以实现"金丝雀发布"(灰度发布)。验证通过后,使用kubectl rollout resume恢复更新,继续完成剩余的滚动过程。
为什么不用别的方法? 如果不用暂停,Deployment会一股脑全换完,根本没有给你留"卡在中间验证"的机会。所以,暂停/恢复是生产环境部署高级策略(灰度发布)的必要手段。




4.DaemonSet
DaemonSet控制器确保集群中的每个(或部分)节点上都运行一个Pod副本。当新节点加入集群时,DaemonSet会自动在该节点上创建对应的Pod;当节点被移除时,Pod会被自动回收。DaemonSet的Pod独立于调度策略,通常用于执行系统级的后台任务。
这个特别好理解。假设你管理着一栋写字楼(K8s集群),每层楼(每台物理机)你都必须配一个灭火器(监控程序)和一个保洁员(日志收集器)。你不能说"这层楼我忘了装",也不能说"三楼的灭火器搬到四楼去"------那是绝对不行的。DaemonSet干的就是这件事:强制规定每台机器必须且只能跑一个我的Pod。只要集群里新买了一台机器(新Node加入),DaemonSet立刻自动在这台新机器上部署一个Pod;如果机器报废了,Pod也跟着撤走。
典型用途:
日志收集:比如Fluentd,每台机器的日志必须由本地的Fluentd收集,不能跨网络。
节点监控:比如Prometheus的NodeExporter,必须跑在每台机器上才能采集CPU、内存等硬件信息。
网络插件:很多CNI网络插件本身也是以DaemonSet形式部署的,保证每个节点都有网络代理。

#另外开启一个主机node3,并设定在初始化集群时的所有设定确保所有服务的开启
#在master中重新生成集群主机注册时需要的token


#当node3加入集群后会在node3中立即群星指定的pod,其原因是因为运行了daemonset
#可以在master中观察pod的状态
5.Job
Job控制器负责管理一次性任务。它会创建一个或多个Pod,并持续追踪这些Pod的执行状态,直到指定数量的Pod成功完成(状态码为0)才算任务结束。如果Pod执行失败,Job会根据restartPolicy(重启策略)决定是否重新创建Pod进行重试。
关键配置:
restartPolicy: OnFailure:脚本报错退出了(非0状态码),Job会重新拉起来再试一次。
restartPolicy: Never:脚本报错退了,Job也不管了,直接标记为失败。
completions:如果你想并行跑好几个脚本,可以设置这个值。



6.CronJob
CronJob控制器是基于时间调度的Job,它按照用户指定的Cron表达式(如0 3 * * *)定时创建并启动Job。每个Job负责执行一次任务,CronJob自身负责管理这些Job的生命周期,并清理历史遗留的Job资源。
典型场景:
每天凌晨3点全量备份数据库。
每周六早上8点清理过期日志文件。
每月1号生成上个月的报表。
关键配置点:
schedule :就是用Linux标准的Cron语法写时间,比如0 3 * * *表示每天凌晨3点。
jobTemplate:里面写的就是Job的配置,也就是说CronJob每次创建出来的"临时工",长得完全一样。
concurrencyPolicy :这是个大坑!如果上一次的Job还没跑完,下一次的调度时间又到了,怎么办?Allow(允许并发重叠跑)、Forbid(禁止并发,等这次跑完再跑下一次)、Replace(把没跑完的旧Job干掉,开个新的)。
一个重要的提醒 :CronJob默认不会保留历史Job的日志,如果不清理,海量的历史Job会填满etcd数据库。记得设置successfulJobsHistoryLimit(成功记录保留几条)和failedJobsHistoryLimit(失败记录保留几条),默认好像是3条和1条,通常可以调大一点方便排查问题,但别调得太大。

