k8s控制器管理

第一部分:控制器管理

1.1 ReplicaSet

概念说明:

ReplicaSet 是 Kubernetes 中确保 Pod 副本数量的基础控制器。其核心职责是维持期望的 Pod 副本数:当实际副本数低于期望值时自动创建新 Pod,当实际副本数高于期望值时删除多余 Pod。ReplicaSet 通过 selector.matchLabels 声明式地管理一组具有相同标签的 Pod。

核心字段说明:

字段 说明
spec.replicas 期望的 Pod 副本数量
spec.selector.matchLabels 标签选择器,用于识别由该 ReplicaSet 管理的 Pod
spec.template Pod 模板,新创建的 Pod 将基于此模板定义

实验命令:

bash 复制代码
# 使用 dry-run 生成 YAML 文件
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > repset.yml

# 将 kind 修改为 ReplicaSet,配置 replicas 和 selector
# repset.yml 内容:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

# 应用配置
kubectl apply -f repset.yml

# 实时监控 Pod 变化
watch -n 1 kubectl get pods --show-labels
# 输出:
# NAME               READY   STATUS    RESTARTS   AGE   LABELS
# webcluster-tbxq4   1/1     Running   0          6m    app=webcluster
# webcluster-jna23   1/1     Running   0          6m    app=webcluster

# 水平扩展:将副本数调整为 4
kubectl scale replicaset webcluster --replicas 4

# 水平收缩:将副本数恢复为 2
kubectl scale replicaset webcluster --replicas 2

# 缩容至 0(暂停副本运行)
kubectl scale replicaset webcluster --replicas 0

实时监控可看具体变化

YAML 水平扩展/收缩效果:

bash 复制代码
# 直接修改 YAML 中的 replicas 值后 apply
# replicas: 4  → Kubernetes 自动创建额外的 2 个 Pod
kubectl apply -f repset.yml

# 监控效果:
# NAME               READY   STATUS    RESTARTS   AGE
# webcluster-4sxz4   1/1     Running   0          13s   ← 新创建
# webcluster-lvtsn   1/1     Running   0          13s   ← 新创建
# webcluster-tbxq4   1/1     Running   0          9m    ← 原有
# webcluster-tr5qk   1/1     Running   0          13s   ← 新创建

1.2 Deployment

概念说明:

Deployment 是管理无状态应用的核心控制器,在 ReplicaSet 的基础上提供了声明式更新和版本回滚能力。每次 Deployment 的 spec 发生变更时,Deployment Controller 会创建一个全新的 ReplicaSet 来管理新版本 Pod,同时逐步缩容旧版 ReplicaSet,从而实现滚动更新。所有历史版本均被保留,支持快速回滚。

实际生产中,Deployment 是最广泛使用的控制器。

实验命令:

bash 复制代码
# 创建 Deployment
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > dep.yml

# dep.yml 内容:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  minReadySeconds: 5
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

# 应用配置
kubectl apply -f dep.yml

# 同时监控 Pod 和 ReplicaSet 的变化
watch -n 1 "kubectl get pods --show-labels; echo ====; kubectl get replicasets.apps"
# 输出:
# NAME                          READY   STATUS    RESTARTS   AGE   LABELS
# webcluster-77c87d9946-49kh5   1/1     Running   0          45s   app=webcluster,pod-template-hash=77c87d9946
# webcluster-77c87d9946-m2x2d   1/1     Running   0          45s   app=webcluster,pod-template-hash=77c87d9946
# ===
# NAME                    DESIRED   CURRENT   READY   AGE
# webcluster-77c87d9946   2         2         2       45s

# 发布 Service 供集群内访问
kubectl expose deployment webcluster --port 80 --target-port 80

# 访问验证
curl 10.107.142.60
# 输出:Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

1.3 滚动更新策略(Rolling Update)

概念说明:

滚动更新是 Deployment 的默认更新策略。其工作原理是:在更新过程中,逐步创建新版本 Pod 并同时终止旧版本 Pod,确保服务在整个升级过程中始终可用。

关键参数:

参数 默认值 说明
spec.strategy.rollingUpdate.maxSurge 25% 更新期间允许超出期望副本数的最大 Pod 数量(可为整数或百分比)
spec.strategy.rollingUpdate.maxUnavailable 25% 更新期间允许不可用的最大 Pod 数量(可为整数或百分比)

实验:查看和修改更新策略

bash 复制代码
# 将副本数扩展为 6,便于观察滚动更新过程
kubectl scale deployment webcluster --replicas 6

# 查看当前更新策略
kubectl describe deployments.apps webcluster
# 输出:RollingUpdateStrategy:  25% max unavailable, 25% max surge

# 修改更新策略:设置 maxSurge=1、maxUnavailable=0(零停机升级)
# 在 dep.yml 中追加 strategy 配置:
spec:
  replicas: 6
  strategy:
    rollingUpdate:
      maxSurge: 1            # 最多比期望值多 1 个 Pod,即最多 7 个 Pod 同时存在
      maxUnavailable: 0      # 不允许任何 Pod 不可用

# 应用策略修改
kubectl apply -f dep.yml

# 升级镜像版本(将 v1 替换为 v2)
# 修改 dep.yml 中的 image: myapp:v2
kubectl apply -f dep.yml

# 滚动更新过程:
# 1. 创建新版 Pod(总数最多增至 7 个)
# 2. 新版 Pod 进入 Ready 状态后,终止一个旧版 Pod
# 3. 重复上述步骤,直至所有 Pod 均运行 myapp:v2
# 4. 最终 6 个 Pod 全部运行新版本

1.4 版本回滚(Rollback)

概念说明:

Deployment 控制器会记录每次 spec 变更的修订历史(Revision)。通过 rollout history 可查看版本变更日志,通过 rollout undo 可将 Deployment 回滚到指定历史版本。回滚本质上是创建一个新的修订版本,其 spec 与目标历史版本一致。

实验命令:

bash 复制代码
# 先升级至 v2
# 修改 dep.yml 中的 image 为 myapp:v2
kubectl apply -f dep.yml

# 验证升级成功
curl 10.107.142.60
# 输出:Hello MyApp | Version: v2 | ...

# 查看更新历史
kubectl rollout history deployment webcluster
# 输出:
# REVISION  CHANGE-CAUSE
# 7         <none>
# 8         <none>

# 回滚至上一版本(v1)
# 修改 dep.yml 中的 image 改回 myapp:v1
kubectl apply -f dep.yml

# 验证回滚成功
curl 10.107.142.60
# 输出:Hello MyApp | Version: v1 | ...

# 查看回滚后的修订历史
kubectl rollout history deployment webcluster
# 输出:
# REVISION  CHANGE-CAUSE
# 8         <none>
# 9         <none>

暂停与恢复更新(批量配置变更场景):

bash 复制代码
# 暂停更新:暂停期间对 Deployment 的修改不会立即触发滚动更新
kubectl rollout pause deployment webcluster

# 在暂停状态下,可多次修改配置
# 例如同时修改镜像版本和副本数

# 修改镜像为 v2
# 在 dep.yml 中修改 image: myapp:v2
kubectl apply -f dep.yml

# 因处于暂停状态,不会触发滚动更新
kubectl rollout history deployment webcluster
# 修订历史未新增版本

# 恢复更新:一次性触发所有待处理变更的滚动更新
kubectl rollout resume deployment webcluster

# 验证更新已触发
kubectl rollout history deployment webcluster
# 新增修订版本

# 查看指定修订的详细信息
kubectl rollout history deployment webcluster --revision=9

1.5 DaemonSet

概念说明:

DaemonSet 确保集群的每个(或符合条件的)节点上运行一个指定 Pod 的副本。当节点加入集群时,DaemonSet 自动在该节点上创建 Pod;当节点被移除时,对应 Pod 被回收。DaemonSet 适用于需要在每个节点上运行守护进程的场景。

典型使用场景:

  • 日志收集代理(如 Fluentd、Filebeat,每个节点采集本地日志)
  • 监控指标采集(如 node_exporter,每个节点暴露系统指标)
  • 网络插件组件(如 CNI 插件的节点端代理)

实验命令:

bash 复制代码
# 生成 DaemonSet 的 YAML
kubectl create deployment daemonset --image myapp:v1 --dry-run=client -o yaml > daemonset.yml

# 将 kind 修改为 DaemonSet
# daemonset.yml 内容:
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: daemonset
  name: daemonset
spec:
  selector:
    matchLabels:
      app: daemonset
  template:
    metadata:
      labels:
        app: daemonset
    spec:
      containers:
      - image: myapp:v1
        name: myapp

# 应用配置
kubectl apply -f daemonset.yml

# 效果:集群中每个节点都会运行一个 Pod
# 新增节点加入集群时,DaemonSet 自动在该节点上调度 Pod

1.6 Job

概念说明:

Job 控制器用于运行批处理任务。与 Deployment 不同,Job 的目标是完成任务后退出,而非持续运行。Job 支持并行执行(多个 Pod 同时运行)和失败重试机制。

核心参数说明:

参数 说明
spec.completions 任务成功完成的总次数
spec.parallelism 同一时间最多允许运行的 Pod 数量
spec.backoffLimit 任务失败后重试的最大次数
spec.template.spec.restartPolicy 建议设为 NeverOnFailure,任务完成后不再重启

实验命令:

bash 复制代码
# 生成 Job 的 YAML
kubectl create job job --image busybox:latest --dry-run=client -o yaml > job.yml

# job.yml 内容:计算圆周率前 2000 位
apiVersion: batch/v1
kind: Job
metadata:
  name: job
spec:
  completions: 6        # 总共需要成功完成 6 次
  parallelism: 2        # 同时最多运行 2 个 Pod
  template:
    spec:
      containers:
      - image: perl:5.34.0
        name: job
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never   # 任务完成后不再重启
  backoffLimit: 4          # 失败最多重试 4 次

# 应用配置
kubectl apply -f job.yml

# 查看 Job 状态
kubectl get jobs

# 查看运行中的 Pod
kubectl get pods

# 查看 Pod 的输出结果(圆周率前 2000 位)
kubectl logs job-4b45g
# 输出:
# 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069

第二部分:Service 与控制器配合

2.1 Service 暴露控制器

概念说明:

Pod 的 IP 地址是临时的,Pod 重启或重建后 IP 会发生变化。Service 通过提供稳定的 ClusterIP 和 DNS 名称,将客户端流量负载均衡到后端一组标签匹配的 Pod 上。Service 与控制器(如 Deployment)配合使用时,Service 的 selector 自动发现并跟踪控制器管理的 Pod 集合,实现服务发现与负载均衡。

实验:同时创建 Deployment 和 Service

bash 复制代码
# 生成包含 Service 和 Deployment 的 YAML
kubectl create service clusterip --tcp 80:80 webservice --dry-run=client -o yaml >> webservice.yaml
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml >> webservice.yaml

# webservice.yaml 内容:
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: webservice
  name: webservice
spec:
  ports:
  - name: webport
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: webcluster    # selector 匹配 Deployment 管理的 Pod 标签
  type: ClusterIP

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

# 一次性应用
kubectl apply -f webservice.yaml

# 监控 Service Endpoints 自动指向 Pod
watch -n 1 "kubectl describe svc webservice; kubectl get pods --show-labels"

# 通过 Service IP 访问,验证负载均衡
curl 10.98.31.55/hostname.html
# 输出轮转:
# webcluster-77c87d9946-tlzxj
# webcluster-77c87d9946-pz5nq

2.2 Service 的 IPVS 模式

概念说明:

Service 默认使用 iptables 规则实现流量转发。当后端 Pod 数量较大时,iptables 规则的线性匹配会导致转发延迟增加。IPVS(IP Virtual Server)模式基于 Linux 内核的 netfilter 框架,使用哈希表实现 O(1) 复杂度的负载均衡,性能显著优于 iptables 模式。

切换步骤:

bash 复制代码
# 在所有节点安装 ipvsadm 管理工具
for name in 100 10 20 200; do
  ssh -l root 172.25.254.$name "dnf install ipvsadm -y"
done

# 修改 kube-proxy 配置,将转发模式从 iptables 切换为 ipvs
kubectl -n kube-system edit cm kube-proxy
# 将 mode: "iptables" 修改为 mode: "ipvs"

# 删除 kube-proxy Pod 使其自动重启并加载新配置
kubectl -n kube-system delete pods -l app=kube-proxy

# 验证 IPVS 规则已生效
ipvsadm -Ln
# 输出示例:
# TCP  10.98.31.55:80 rr
#   -> 10.244.2.8:80                Masq    1      0          0
#   -> 10.244.5.95:80               Masq    1      0          0

第三部分:知识点速查总结

控制器选型指南

控制器 适用场景 特点
ReplicaSet 基础副本控制 维持指定数量的 Pod 副本
Deployment Web 应用、微服务 支持滚动更新和版本回滚的副本控制器(最常用)
DaemonSet 日志收集、监控代理 每个节点运行一个副本
Job 批处理任务、数据计算 一次性任务,完成后自动退出
相关推荐
无念是……1 小时前
K8s 控制器管理详解|RC、RS、Deployment、StatefulSet、DaemonSet、Job&CronJob
云原生·容器·kubernetes·控制器
EterNity_TiMe_2 小时前
一个网页管理多种远程连接:Docker 部署 Next Terminal 与资产审计
运维·人工智能·docker·ai·容器
mohesashou2 小时前
k8s的pod管理
云原生·容器·kubernetes
WThh2 小时前
k8s中的控制器管理
云原生·容器·kubernetes
养海绵宝宝的小蜗2 小时前
【Kubernetes系列】控制器(Controller)全解:ReplicaSet、Deployment、DaemonSet、Job 与 CronJob
云原生·容器·kubernetes
nxb5562 小时前
云原生:控制器
java·开发语言·云原生
UseLessQQ2 小时前
云原生 kubenetes 控制器管理
云原生·kubernetes
是枚小菜鸡儿吖5 小时前
把视频教程变成可复习的笔记:Docker 部署 BiliNote,自动转写与总结
笔记·docker·容器
浪兎兎13 小时前
【Kubernetes 实战】(二)部署 Ruoyi-Cloud —— 部署服务
云原生·容器·kubernetes