4. 资源调度之标签与控制器
本文最后更新于28 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、标签 Label

1. 概念

标签是附加在 K8s 资源(Pod、Deployment、Service 等)上键值对元数据。

  • 作用:资源分组筛选,控制器依靠标签选择器关联管理 Pod
  • 控制器工作原理:控制器selector标签选择器 → 匹配 Pod 标签 → 管理匹配到的 Pod

类比:标签 = 身份证,选择器 = 寻人启事。

2. 标签语法规范

  • 字符:大小写字母、数字、-_.
  • key 最大 253 字符,value 最大 63 字符
  • 不能以特殊符号开头,不能带空格

3. 官方标准标签(app.kubernetes.io/*)

labels:
  app.kubernetes.io/name: "nginx"        #应用名称
  app.kubernetes.io/instance: "nginx-01" #实例名称
  app.kubernetes.io/version: "1.27"      #版本
  app.kubernetes.io/component: "web"    #组件类型
  app.kubernetes.io/part-of: "shop"      #所属上层应用
  app.kubernetes.io/managed-by: "helm"   #管理工具

4. 标签常用命令

#创建pod带标签
kubectl run nginx --image=nginx --labels="app=nginx,env=test"

#给已有pod打标签
kubectl label pod nginx env=prod

#覆盖已有标签,必须加--overwrite
kubectl label pod nginx env=dev --overwrite

#删除标签,key后面加"-"
kubectl label pod nginx env-

#查看并显示标签
kubectl get pod --show-labels

5. 标签选择器 Selector

①等式选择器(=、!=),逻辑与(逗号分隔同时满足)

kubectl get pod -l app=nginx,env=prod
kubectl get pod -l env!=test

②集合选择器(in /notin/exists)

#in:值属于集合中任意一个
kubectl get pod -l "env in (dev,test)"
#notin:不在集合
kubectl get pod -l "env notin (prod)"
#exists:标签key存在,不管value
kubectl get pod -l env
#!key:标签key不存在
kubectl get pod -l '!env'

注意:yaml 中控制器spec.selector.matchLabels必须和 pod 模板 labels 完全匹配,否则控制器无法管理 Pod。


二、无状态服务 vs 有状态服务

表格

类型无状态服务 Stateless有状态服务 Stateful
控制器DeploymentStatefulSet
Pod 身份Pod 名称随机,重建身份改变Pod 固定名称 web‑0/web‑1,重建名称不变
网络标识PodIP 随机变化搭配 Headless Service 获取稳定 DNS 域名
存储重建数据丢失,共享存储 /emptyDir每个 Pod 独立 PVC,重建挂载原有数据
启停顺序并行启停无序有序创建 0→N;缩容逆序 N→0
适用场景web、nginx、微服务 APIMySQL、Redis 集群、Kafka、Zookeeper

无状态:所有 Pod 完全等价,可以随意销毁重建; 有状态:每个 Pod 有专属身份、专属数据,不能随便乱删乱换。

三、K8s 各类控制器总览

表格

控制器作用典型场景
ReplicaSet保证指定 Pod 副本数;Deployment 底层依赖,一般不直接操作被 Deployment 调用
Deployment无状态应用,滚动更新、版本回退、金丝雀发布web、微服务
StatefulSet有状态应用,稳定身份、有序更新、独立 PVC数据库、分布式中间件
DaemonSet每个(指定)节点运行且只运行 1 个 Pod日志采集 filebeat、监控 exporter、网络插件 calico
Job一次性任务,执行完成退出数据迁移、脚本批处理
CronJob定时周期任务,基于 Job定时备份、定时清理日志

自主 Pod:直接 kubectl run /yaml 创建,删除不会自动重建;控制器管理 Pod,故障删除自动重建,维持期望副本。

1.ReplicaSet(副本集)

  • apiVersion: apps/v1
  • 功能:维持副本数量、故障自愈、扩缩容;Deployment 底层使用,生产不直接写 RS yaml
  • 核心字段:replicas期望副本;selector选择器;templatePod 模板

⚠️ selector.matchLabels 必须与 template.metadata.labels 保持一致。

kubectl get rs
kubectl scale rs xxx --replicas=5

四、Deployment 重点(无状态控制器)

1. 层级关系

Deployment → ReplicaSet → Pod Deployment 通过管理 ReplicaSet 间接管理 Pod;每一次版本更新生成新 ReplicaSet,旧 RS 保留用于回退。

2. 核心 yaml 关键字段

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 3                     #期望副本数
  revisionHistoryLimit: 3        #保留历史RS版本数量,用于回退
  strategy:                       #更新策略
    type: RollingUpdate           #默认滚动更新
    rollingUpdate:
      maxSurge: 25%               #更新期间允许超出replicas最大副本数
      maxUnavailable: 25%         #更新期间允许最大不可用Pod数量
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.27.1

3. 两种更新策略

  1. Recreate 重建更新:先全部删除旧 Pod,再创建全部新 Pod。会业务中断,测试环境用
  2. RollingUpdate 滚动更新(默认,生产):逐步替换 Pod,业务不中断
    • maxSurge:最多可以多跑多少 Pod;
    • maxUnavailable:最多允许多少 Pod 不可用。

4. 常用操作命令

#命令创建
kubectl create deployment nginx --image=nginx --replicas=3

#扩缩容
kubectl scale deployment nginx --replicas=5

#修改镜像版本
kubectl set image deployment nginx nginx=nginx:1.27.1

#查看升级历史
kubectl rollout history deployment nginx

#添加版本变更注释
kubectl annotate deployment nginx kubernetes.io/change-cause="更新到nginx1.27.1"

#回退上一个版本
kubectl rollout undo deployment nginx
#回退指定revision版本
kubectl rollout undo deployment nginx --to-revision=1

#查看发布进度
kubectl rollout status deployment nginx

#金丝雀发布:更新镜像并且暂停更新,新旧版本共存,验证新版本
kubectl set image deployment nginx nginx=nginx:1.28 && kubectl rollout pause deployment nginx

#继续完成全量更新
kubectl rollout resume deployment nginx

✨金丝雀发布原理:pause 暂停滚动更新,此时只创建 maxSurge 数量新版本 Pod,旧 Pod 保留;小流量验证新版本,没问题再 resume 全量升级,有问题直接 undo 回滚。

五、StatefulSet 有状态控制器⭐重点

核心特性

  1. Pod 固定命名:web-0、web-1、web-2,重建名称不变;
  2. 需要搭配Headless Service,给 Pod 提供稳定 DNS 域名;
  3. 有序管理:
    • 扩容:序号从小到大 0 →1→2,前一个就绪才创建下一个;
    • 缩容:序号从大到小 2→1→0,先删最大序号;
  4. volumeClaimTemplates:模板自动创建独立 PVC,每个 Pod 专属存储,重建数据保留。

更新策略

  1. RollingUpdate(默认)
    • 逆序更新:从最大序号往小序号逐个更新;串行,一个就绪再更新下一个
    • 关键字段partition:分区灰度发布
      • partition=N:只更新序号 ≥ N 的 Pod;小于 N 保持旧版本。
      • 示例partition=2:只更新 web‑2、web‑3;web‑0、web‑1 保留旧版本,实现金丝雀。
  2. OnDelete:修改 sts 模板不会自动更新 Pod;必须手动删除 Pod,删除后才用新版本重建;适合数据库等极高稳定性场景。

StatefulSet没有 maxSurge/maxUnavailable 参数!

StatefulSet 金丝雀发布步骤

  1. 设置 partition,划定更新边界
kubectl patch statefulset mysql -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":2}}}}'
  1. 更新镜像,触发更新;只有序号≥2 的 Pod 升级新版本
  2. 验证新版本业务正常,逐步调小 partition 直到 0 完成全部更新

常用命令

kubectl get sts
#扩容缩容
kubectl scale statefulset mysql --replicas=4
#更新镜像
kubectl set image statefulset mysql mysql=mysql:8.0
#patch局部修改资源,不需要完整yaml
kubectl patch

六、DaemonSet

  1. 不需要写replicas副本数;
  2. 集群每个符合条件 Node 运行恰好一个 Pod;新增节点自动创建 Pod,节点下线自动销毁 Pod;
  3. 可以配合nodeSelector/nodeAffinity,只在部分节点部署(如 GPU 节点)。
  4. 典型用途:calico 网络插件、filebeat 日志采集、node‑exporter 监控。

yaml 简要示例

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
spec:
  selector:
    matchLabels:
      app: filebeat
  template:
    metadata:
      labels:
        app: filebeat
    spec:
      containers:
      - name: filebeat
        image: filebeat:7.17

七、Job & CronJob(一次性 / 定时任务)

Job:一次性任务

  • 用途:批处理、数据迁移,任务完成 Pod 退出(exit0),状态 Succeeded
  • Job 下 Pod重启策略只能用:OnFailure / Never,禁止 Always。
  • 参数:parallelism并行 Pod 数量;completions需要成功完成次数。

CronJob:定时任务

  • 基于 crontab 时间表达式,定时自动创建 Job 对象执行任务;
  • 字段:schedule: "0 2 * * *"(每天凌晨两点);
  • 可配置保存成功、失败 Job 历史记录。

八、汇总

  1. Deployment 和 StatefulSet 区别
  • Deployment:无状态;Pod 名称随机;并行无序启停;滚动更新 maxSurge/maxUnavailable;无专属存储;适合 web 微服务。
  • StatefulSet:有状态;Pod 固定序号名称;有序创建逆序删除;逆序串行更新,使用 partition 做灰度;独立 PVC 持久存储;需要 HeadlessService;适合数据库、分布式中间件。
  1. StatefulSet partition 作用?如何实现金丝雀? partition 是更新分区阈值;只更新序号大于等于 partition 的 Pod; 流程:设置 partition → 更新镜像 → 验证高序号新版本 Pod → 逐步降低 partition 直至 0,完成全量更新。
  2. Deployment 金丝雀(pause/resume)原理 更新镜像后执行rollout pause暂停滚动;只生成 maxSurge 数量新版本 Pod,旧 Pod 保留;小流量验证,异常直接 undo 回滚;验证没问题rollout resume完成全部滚动更新。
  3. DaemonSet 作用,和 Deployment 区别? DaemonSet 每个节点运行一个 Pod,用于节点级服务(日志、监控、网络插件),不设置 replicas;Deployment 指定副本数,Pod 随机调度到节点。
  4. Job 为什么不能用 restartPolicy:Always? Job 是一次性任务,如果 Always,任务执行完成退出后会无限反复重启 Pod,不符合一次性任务语义。
  5. 标签和标签选择器的作用 标签是资源的键值对元数据,用于分类;控制器依靠标签选择器筛选匹配标签的 Pod,实现扩缩容、自愈管理。
  6. Replicaset 和 Deployment 关系? Deployment 底层管理 ReplicaSet;每次版本更新产生新 ReplicaSet;旧 ReplicaSet 保留,用于版本回退;一般不直接操作 ReplicaSet。

九、重要命令汇总

#标签
kubectl label
kubectl get pod -l / --show-labels

#deployment
kubectl scale
kubectl set image
kubectl rollout history / undo / status / pause / resume

#statefulset
kubectl patch
kubectl scale sts

#查看各类控制器
kubectl get deploy,rs,sts,ds,job,cronjob
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇