【10-kubernetes的控制器】

什么是控制器?

在kubernetes中运行了一系列控制器来确保集群的当前状态与期望状态对齐保持一致,他们就是Kubernetes集群内部的管理控制中心或者说是中心大脑。比如ReplicaSet控制器负维护集群中运行的Pod数量;Node控制器负责监控节点的状态,并在节点出现故障时,执行自动修复流程,确保集群始终处于预期的工作状态。

常见的Pod控制器

ReplicationControllet 和ReplicaSet

RC用来确保容器应用的副本数量始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;过多会回收。新版本RS支持集合式的selector选择。

YAML 复制代码
详解    
apiVersion: v1
kind: ReplicationController                #类型要写ReplicationController
metadata:
  name: rc-demo
spec:
  replicas: 3        #表示3副本,创建3个pod
  selector:        #标签选择器
    app: rc-demo        #标签为rc-demo的pod被我管理
  template:        #定义pod的创建模板
    metadata:
      labels:        #定义pod的标签
        app: rc-demo                #必须是上面选择器的子集合,不然报错
    spec:
      containers:
      - name: rc-demo-container
        image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/wangyanglinux/myapp:v1.0
        env:                #环境变量
        - name: GET_HOSTS_GROM
          value: dns
        - name: zhangsan
          value: "123"
        ports:        #端口映射
        - containerPort: 80

matchLabels:标签与pod做子集运算,如果是子集则匹配,比如matchLables是app=myapp,只要pod的标签含有app=myapp,就会匹配到。

表达式:selector.matchExpressions RS在标签选择器上除了可以自定义键值对的选择形式还支持matchExpression字段,提供多种选择。

In label的值在某个列表中

YAML 复制代码
# app的value不匹配子集的情况
selector:
    matchExpressions:
    - key: app
      operator: In
      values:
      - spring-k8s
      - hahah  

Notln 不在某个列表中

Exists 某个label存在

YAML 复制代码
selector:
    matchExpressions:
      - key: app
        operator: Exists

DoesNotExist 某个labe不存在

控制器创建时,会接管符合标签的pod,把它算作副本,前提是该pod没被其他控制器接管。如果一个pod被RS抛弃,变成了孤儿pod,有可能会被其他RS控制器接管。

Deployment 与 RS 的关系

Deployment为Pod和ReplicaSet提供一个声明式定义(deccarative)方法,用来替代以前的RC来方便管理应用。典型的场景包括:

  • 定义Deployment来创建Pod和RS

  • 滚动升级和回滚应用

  • 扩容和缩容

  • 暂停和继续Deployment

创建deployment

YAML 复制代码
#kubectl apply -f myapp-deploy-1.0.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp-deploy
  name: myapp-deploy
spec:
  selector:
    matchLabels:
      app: myapp-deploy
  template:
    metadata:
      labels:
        app: myapp-deploy
    spec:
      containers:
      - name: myapp
        image: registry.cn-hangzhou.aliyuncs.com/wangyangshare/share:myappv1.0

Deployment特性

Deployment 无状态控制器是维护不同版本的RS中的副本数量来实现滚动更新。支持声明式表达,支持更新回滚操作。当创建一个Deployment时,他会创建一个RS,由RS去创建POD副本,当更新时,deployment会去创建新的RS,新的RS会逐步去替换原来的Pod.

核心特征:通过RS去间接管理Pod,Pod名称随机,可随时替换。支持滚动更新和重建策略,支持回滚到历史版本。支持暂停和恢复。

更新滚动完成后,原来的RS不会删除,如果代码有BUG要回滚版本,同样也是,新建POD,逐步回滚右边的POD。

create apply replace之间的区别

YAML 复制代码
kubectl replace -f deployment.yaml
kubectl apply -f deployment.yaml
kubectl diff -f deployment.yaml

replace:使用新的配置会完全替换掉现有的资源。意味着新配置将覆盖现有的资源所有字段和属性,包括未指定的字段,会导致整个资源的替换。

apply:使用新的配置部分地更新现有的资源配置。它会根据提供的配置文件或参数,只更新与新配置中不同的部分,而不会覆盖整个资源的配置。

creat:创建资源对象,命令式适用于初次创建,如果已经创建了,即使对yaml文件做了更改,比如更改了镜像,执行creat会报错。

滚动更新策略RollingUpdate

控制字段:

YAML 复制代码
revisionHistoryLimit: 10  #10 个历史版本
strategy:
  type: RollingUpdate          # ← 这个
  rollingUpdate:
    maxSurge: 25%
    maxUnavailable: 25%

maxSurge:25% ->控制最多能同时创建多少新的Pod。两种方式指定数量和百分比。

maxUnavailable:25% ->最多几个不可用,控制最多能同时销毁多少旧Pod即最低业务可用率。

执行铁律:先创建,后删除;不超上限,不跌破下限。

执行流程:

  1. 新建新Pod,直到活跃总数触达上限,停止创建。

  2. 删除旧Pod,直到可用总数触达下限,停止删除。

  3. 新Pod就绪,重复循环,直到全量替换完成。

type 决定了更新策略的种类,rollingUpdate下面的参数只在 type: RollingUpdate 时生效。

YAML 复制代码
type: RollingUpdate   ← 滚动更新(逐步替换,默认默认值)
type: Recreate        ← 先全部销毁,再全部创建

暂停/恢复更新

YAML 复制代码
正常的流程(无暂停):
    修改镜像或者资源→触发滚动更新→再次修改→再次触发滚动更新
暂停流程:
    pause → 修改镜像→v2 → 修改副本数→5 → 修改资源limit → resume  resume 时一次性创建新 RS,只滚动一次到最新的期望状态。

适用于需要批量修改多处配置的场景,避免每次修改都触发一次更新:
# 暂停 Deployment 的滚动更新
kubectl rollout pause deployment/<deployment-name>
# 恢复 Deployment 的滚动更新
kubectl rollout resume deployment/<deployment-name>

回滚

YAML 复制代码
kubectl rollout history deploy nginx    # 查看所有修订版本
kubectl rollout undo deploy nginx       # 回滚到上一个版本
kubectl rollout undo deploy nginx --to-revision=2  # 回滚到指定版本
可定义历史保留最多的版本数量,默认10
revisionHistoryLimit: 10    

节点调度器

nodeSelector vs nodeName ,使当前创建的pod调度到指定的node节点中。

YAML 复制代码
# nodeSelector node标签选择器
#打上标签
kubectl label nodes k8s-node01 disktype=ssd  
kubectl label nodes k8s-node02 disktype=hdd  
kubectl label nodes k8s-node03 disktype=ssd
#使用方式
nodeSelector:    
    disktype: ssd    # 必须匹配    
    gpu: "true"      # 可以多个条件,全部满足才行(AND 关系)
#nodeName node 标签指定器
nodeName: k8s-node02    # 硬编码,就跑在这个节点

Statefulset 有状态控制器

核心特性:有固定的名称,稳定的网络标识通过Headless实现,有稳定独立PVC持久化存储,有序部署有序更新有序删除。

DNS 解析格式

YAML 复制代码
# 在集群内部借助core DNS 插件功能实现pod内不同服务的稳定访问。
serviceName: "web"       # 指向 Service 分配稳定的DNS名称
#解析格式为:
#  同一命名空间下的简写
    <pod名>.<svc名>
    web-0.nginx
#跨命名空间全限定域名
    <pod名>.<svc名>.<命名空间>.svc.cluster.local
    例:web-0.nginx.default.svc.cluster.local
格式:<pod名>.<svc名>.<命名空间>.svc.cluster.local
实例:
  web-0.nginx-svc.default.svc.cluster.local
  │      │         │       │   │       │
  │      │         │       │   │       └── 根域
  │      │         │       │   └────────── 集群域
  │      │         │       └────────────── 类型
  │      │         └────────────────────── 命名空间
  │      └──────────────────────────────── Headless Service
  └─────────────────────────────────────── Pod 名称(StatefulSet 固定的)

扩缩容顺序

YAML 复制代码
扩容(正序):web-0(已有) → web-1(已有) → web-2(新建) → web-3(新建)
缩容(倒序):web-3(删除) → web-2(删除) → web-1(保留) → web-0(保留)

分段更新(部分更新 / 灰度更新)

YAML 复制代码
#通过 patition 参数实现灰度发布
updateStrategy:
  type: RollingUpdate
  rollingUpdate:
    partition: 3    # 只有序号 >= 3 的 Pod 才会更新

删除方式

YAML 复制代码
非级联删除到底解决什么问题?为什么需要它
场景一:StatefulSet 配置坏了有些字段不可变比如serviceName、volumeClaimTemplates,但 Pod 还在正常服务
使用级联删除会删除pod 重建,非级联删除后,重新apply会接管原pod.

# 非级联删除,pod成孤儿
kubectl delete sts web --cascade=false   # StatefulSet 没了,Pod 还活着!
kubectl apply -f correct.yaml            # 新的 StatefulSet 接管这些 Pod

# 级联删除
kubectl delete sts web

并发Pod管理

YAML 复制代码
#并发模式下依然有序,不在保证只是不再保证启动顺序和删除顺序。
#Parallel 模式下创建多个有状态 Pod 不需要等前一个就绪
podManagementPolicy: Parallel   # 设置并发策略

#策略适合场景
OrderedReady 有启动依赖、需要主从顺序启动(如数据库集群)
Parallel     之间互不依赖、追求快速部署、批量无状态化应用

DaemonSet 守护进程集

核心特征:确保集群中的每个(或指定)节点都运行一个Pod的副本。

YAML 复制代码
新增节点 → 自动创建 Pod
移除节点 → 自动删除 Pod
修改标签 → 不匹配的删除,新匹配的创建

应用场景:日志收集、监控代理、网络插件、存储守护进程。

指定节点部署

YAML 复制代码
#使用 节点调度器
spec:
  template:
    spec:
      nodeSelector:
        disktype: ssd    # 只在有此标签的节点上运行

更新策略

YAML 复制代码
# RollingUpdate(自动滚动更新)  VS OnDelete(手动删除才更新)
updateStrategy:    
    type: RollingUpdate       # 滚动更新策略 /OnDelete
    rollingUpdate:      
        maxUnavailable: 1     # 每次最多1个节点不可用,控制节奏
        

Job 控制器

核心特征:job 负责跑一次就结束的批处理任务,确保指定数量的Pod成功完成任务后终止。与deployment不同,job不是一直运行的,而是完成任务即结束。

YAML 复制代码
apiVersion: batch/v1           
kind: Job                                             
metadata:                                               
  name: job-demo                                    
spec:                                             
  template:                  
    metadata:                      
      name: job-demo-pod                     
    spec:                     
      containers:                    
      - name: job-demo-container                    
        image: registry.cn-hangzhou.aliyuncs.com/wangyangshare/share:maqingpythonv1
      restartPolicy: Never

需要完成的Pod总数

YAML 复制代码
completions: 5 其参数值未设置默认为1,只要有一个pod成功就算成功。
场景:1用作数据迁移脚本,或者批量处理分片数据。

同时运行的Pod数量

YAML 复制代码
parallelism: 3 控制并发度,保证指定的pod 同时处于runing 状态

重启策略

YAML 复制代码
`re`startPolicy  和其他的控制器不同,只有Never(推到重建Pod) 和 OnFailure(同一个Pod) 两种策略 
遇到部署类的不用管重启策略,遇到 Job 类的在 Never 和 OnFailure 里选一个,就够了。

标志失败 Pod 的重试最大时间

YAML 复制代码
activeDeadlineSeconds 300 从job 开始算,5分钟内没成功标记失败。

CronJob

核心特征:给Job 加了个定时闹钟,按时间规律自动创建job.

YAML 复制代码
apiVersion: batch/v1
kind: CronJob
metadata:
  name: xxx
spec:
  schedule: "??? ? ? ? ?"          # 什么时候跑
  concurrencyPolicy: Allow/Forbid/Replace  # 怎么处理并发
  successfulJobsHistoryLimit: 3     # 成功留几个
  failedJobsHistoryLimit: 1         # 失败留几个
  
  jobTemplate:                      # Job 模板
    spec:
      completions: 1
      parallelism: 1
      activeDeadlineSeconds: 300
      template:
        spec:
          restartPolicy: Never      # 或 OnFailure
          containers:
          - name: xxx
            image: xxx

定时规则

YAML 复制代码
# schedule 就是cron的表达式
记忆口诀:分 时 日 月 周,星号代表"每"。

job模板

YAML 复制代码
#告诉cronjob 到点了该创建什么样的job
jobTemplate:
  spec:
    template:
      spec:
        containers:
        - name: task
          image: my-task:latest
        restartPolicy: Never

并发策略

YAML 复制代码
# concurrencyPolicy: Allow/Forbid/Replace  上次的job 还未执行完,新的到时间怎么办?
Allow : 不管新job照常创建,两个同时运行。(任务之间互不影响)
Forbid : 跳过这次,不创建新的job。(不允许重叠,数据库锁)
Replace : 替换,干掉旧的,创建新的。(始终用最新执行)

保留成功/失败的job记录

YAML 复制代码
failedJobsHistoryLimit(默认 1)  #保留几个成功的job
successfulJobsHistoryLimit(默认 3)# 保留几个失败的job方便你查看出错原因

错过时间策略

YAML 复制代码
jobTemplate**.space.**startingDeadlineSeconds 100
不设即错过的全补回来,设置N秒,超过N秒不补了。
YAML 复制代码
CronJob
  └─ spec
       ├─ schedule                    ← 定时
       ├─ concurrencyPolicy           ← 并发处理
       ├─ jobTemplate                 ← Job 模板
       │    └─ spec
       │         ├─ completions       ← Job 参数
       │         ├─ parallelism
       │         └─ template          ← Pod 模板
       │              └─ spec
       │                   ├─ restartPolicy
       │                   └─ containers
       └─ successfulJobsHistoryLimit: 3    
       └─ failedJobsHistoryLimit: 1 
相关推荐
无望__wsk2 小时前
k8s控制器
java·docker·kubernetes
2301_810730102 小时前
K8s的Pod管理
linux·容器·kubernetes
CJY6212 小时前
k8s控制器管理
云原生·容器·kubernetes
无念是……3 小时前
K8s 控制器管理详解|RC、RS、Deployment、StatefulSet、DaemonSet、Job&CronJob
云原生·容器·kubernetes·控制器
mohesashou3 小时前
k8s的pod管理
云原生·容器·kubernetes
WThh3 小时前
k8s中的控制器管理
云原生·容器·kubernetes
养海绵宝宝的小蜗3 小时前
【Kubernetes系列】控制器(Controller)全解:ReplicaSet、Deployment、DaemonSet、Job 与 CronJob
云原生·容器·kubernetes
UseLessQQ4 小时前
云原生 kubenetes 控制器管理
云原生·kubernetes
浪兎兎14 小时前
【Kubernetes 实战】(二)部署 Ruoyi-Cloud —— 部署服务
云原生·容器·kubernetes