当前位置: 首页 > news >正文

k8s(六)Pod的资源控制器

文章目录

  • 前言
  • 一、Pod控制器
    • 1.1 Pod控制器概述
      • 1.1.1 核心功能
    • 1.2 Pod控制器的类型
    • 1.3 Deployment控制器
      • 1.3.1 核心特点
      • 1.3.2 配置案例
      • 1.3.3 查看控制器配置
      • 1.3.4 查看历史版本
    • 1.4 StatefulSet控制器(有状态)
      • 1.4.1 核心特点
      • 1.4.2 三个核心组件
      • 1.4.3 关键问题解答
        • 1.4.3.1 StatefulSet 解决的核心问题
        • 1.4.3.2 StatefulSet 的核心能力
          • 1. 稳定的 Pod 身份:固定的“名称 + Hostname”
          • 2. 持久化数据的“一对一绑定”:基于 PVC 模板的存储分配
          • 3. 有序的部署、扩展与缩容
          • 4. 稳定的网络访问:基于 Headless Service 的 DNS 解析
        • 1.4.3.3 StatefulSet 的典型应用场景
        • 1.4.3.4 为什么需要Headless Service?
        • 1.4.3.5 为什么需要volumeClaimTemplates?
      • 1.4.4 StatefulSet + NFS 持久卷案例
        • 1.4.4.1 定义Headless Service
        • 1.4.4.2 定义StatefulSet(动态存储)
        • 1.4.4.3 创建与验证
        • 1.4.4.4 滚动更新
        • 1.4.4.5 Pod的名称解析
      • 1.4.6 无状态与有状态应用对比
    • 1.5 DaemonSet控制器
      • 1.5.1 核心功能
      • 1.5.2 典型应用场景
      • 1.5.3 配置案例
    • 1.6 Job控制器
      • 1.6.1 核心功能
      • 1.6.2 应用场景
      • 1.6.3 配置案例1(计算圆周率)
      • 1.6.4 配置案例2(测试重试策略)
    • 1.7 CronJob控制器
      • 1.7.1 核心功能
      • 1.7.2 应用场景
      • 1.7.3 配置案例(每分钟打印问候信息)
      • 1.7.4 CronJob其他常用参数配置
      • 1.7.5 创建与验证CronJob
      • 1.7.6 常见问题解决(权限不足)
    • 1.8 常规Service与Headless Service对比
    • 1.9 附录:服务发现机制
      • 1.9.1 Kubernetes内置DNS服务的演进
      • 1.9.2 Pod间通信的域名格式
    • 1.10 Pod控制器总结
  • 总结


前言

在 Kubernetes(简称 K8s)的容器编排生态中,Pod 作为最小部署单元,其生命周期管理与状态维持直接决定了应用的稳定性与可用性。然而,仅依靠手动创建和管理 Pod,难以应对集群规模扩大、服务负载波动、节点故障等复杂场景 —— 一旦 Pod 意外退出、节点宕机,服务便可能中断;若需更新应用版本或调整副本数量,手动操作不仅效率低下,还易引发人为失误。
正是为解决这些问题,Pod 控制器(Controller)应运而生。作为 Kubernetes 中管理 Pod 的 “中间层”,Pod 控制器通过 “声明式配置” 的理念,让用户只需定义应用的 “期望状态”(如副本数量、运行版本、存储需求等),底层系统便会自动监控 Pod 的 “当前状态”,并通过重建、扩容、滚动更新等操作,确保两者始终一致。
本文将系统梳理 Kubernetes 中核心的 Pod 控制器类型,包括面向无状态应用的 Deployment、面向有状态应用的 StatefulSet、确保节点级任务运行的 DaemonSet,以及处理一次性 / 周期性任务的 Job 与 CronJob。通过对每种控制器的核心功能、应用场景、配置案例及关键特性对比的详细解析,帮助读者掌握不同控制器的适用场景与使用方法,进而高效管理 Kubernetes 集群中的各类应用负载,为实际生产环境中的容器编排提供清晰指引。

一、Pod控制器

Pod控制器(Controller),也被称为工作负载(Workload),是Kubernetes里用于管理Pod的中间层。它的核心职责是确保集群中的Pod资源始终符合用户预先定义的“期望状态”,比如维持Pod的副本数量、处理Pod异常退出后的重建等。

1.1 Pod控制器概述

1.1.1 核心功能

  • 保障Pod副本数量与用户期望一致,不会因意外情况导致副本数量减少。
  • 当Pod出现异常退出时,能依据预设的重启策略自动重建Pod,保证服务连续性。
  • 支持对Pod进行伸缩操作(包括扩容以应对高负载、缩容以节省资源)、滚动更新(在不中断服务的情况下更新Pod版本)以及回滚(当更新出现问题时,恢复到之前的稳定版本)。

1.2 Pod控制器的类型

不同类型的Pod控制器适用于不同的应用场景,其功能和应用场景对应关系如下表所示:

控制器功能应用场景
ReplicaSet保证指定数量的Pod副本存在,支持滚动扩缩容。不过通常不直接使用,而是由Deployment进行管理。无状态应用
Deployment管理ReplicaSet,实现声明式部署(用户只需定义期望状态,Kubernetes自动完成部署过程)、滚动升级、回滚等操作。Web服务
StatefulSet管理有状态应用,为其提供稳定的网络标识(固定的Pod名称和DNS名称)与专属存储。数据库、Zookeeper
DaemonSet确保在集群中的每个Node节点上都运行一个Pod副本。日志收集(如Fluentd/Logstash)、监控(如Prometheus Node Exporter)、Agent类程序
Job用于执行一次性任务,任务完成后Pod即退出。数据迁移、批处理、安全扫描、离线数据处理
CronJob用于执行周期性任务,类似Linux系统中的Crontab。定期备份、定时通知、日志清理

1.3 Deployment控制器

Deployment是Kubernetes中最常用的控制器之一,主要用于管理无状态应用。

1.3.1 核心特点

  • 专门针对无状态应用进行管理,无状态应用的各个Pod实例之间没有差异,可随意替换。
  • 支持滚动更新,在更新过程中,先启动新的Pod副本,待新副本正常运行后再删除旧的Pod副本,确保服务不中断。
  • 支持回滚操作,当更新后的版本出现问题时,能快速恢复到之前的稳定版本。
  • 采用声明式配置更新,用户只需修改配置文件中期望的状态,Kubernetes会自动对比当前状态和期望状态,并完成差异调整。
  • 与ReplicaSet协作使用,Deployment通过管理ReplicaSet来间接管理Pod的副本数量。

1.3.2 配置案例

vim nginx-deployment.yaml
apiVersion: apps/v1  # API版本,Deployment属于apps组下的v1版本
kind: Deployment     # 资源类型为Deployment
metadata:name: nginx-deployment  # Deployment的名称labels:app: nginx            # 给Deployment添加的标签,用于标识和筛选
spec:replicas: 3  # 期望的Pod副本数量为3selector:matchLabels:app: nginx  # 选择匹配标签为app:nginx的Pod进行管理template:  # Pod模板,用于创建Podmetadata:labels:app: nginx  # 给Pod添加的标签,需与selector中的matchLabels匹配spec:containers:  # 容器配置- name: nginx  # 容器名称image: nginx:1.15.4  # 容器使用的镜像及版本ports:- containerPort: 80  # 容器暴露的端口号
# 创建Deployment
kubectl create -f nginx-deployment.yaml
# 查看Pod、Deployment、ReplicaSet的状态
kubectl get pods,deploy,rs

在这里插入图片描述

1.3.3 查看控制器配置

通过以下命令可查看Deployment的详细配置信息:

kubectl edit deployment/nginx-deployment

配置信息如下(关键部分已标注注释):

apiVersion: apps/v1
kind: Deployment
metadata:annotations:deployment.kubernetes.io/revision: "1"  # Deployment的修订版本号,用于回滚creationTimestamp: "2025-10-15T11:39:08Z"  # Deployment的创建时间generation: 1  # 生成次数,配置更新时会递增labels:app: nginx  # Deployment资源的标签name: nginx-deployment  # Deployment名称namespace: default  # 所属命名空间,默认为defaultresourceVersion: "148264"  # 资源版本号,用于跟踪资源变更selfLink: /apis/apps/v1/namespaces/default/deployments/nginx-deployment uid: 94d6c9df-7f77-4cdb-a013-bd9c0556cd2d  # 资源的唯一标识符
spec:progressDeadlineSeconds: 600  # 部署进度超时时间,超过该时间仍未完成部署则标记为失败replicas: 3  # 期望的Pod数量,默认是1revisionHistoryLimit: 10  # 保留的历史修订版本数,超过该数量的旧版本会被清理selector:matchLabels:app: nginx  # 选择匹配标签为app:nginx的Podstrategy:  # 更新策略rollingUpdate:  # 滚动更新配置maxSurge: 25%  # 升级过程中允许超出期望Pod数量的最大比例(也可以是绝对值,如2),这里表示最多可多启动25%的PodmaxUnavailable: 25%  # 升级过程中允许不可用的Pod最大比例(也可以是绝对值),这里表示最多有25%的Pod不可用type: RollingUpdate  # 更新类型为滚动更新template:  # Pod模板metadata:creationTimestamp: null  # Pod创建时间,创建后会自动填充labels:app: nginx  # Pod副本关联的标签,需与selector匹配spec:containers:- image: nginx:1.15.4  # 镜像名称及版本,将镜像版本修改可以观察到,容器的更新imagePullPolicy: IfNotPresent  # 镜像拉取策略,IfNotPresent表示本地有则不拉取,本地没有再从远程拉取name: nginx  # 容器名称ports:- containerPort: 80  # 容器暴露的监听端口protocol: TCP  # 协议类型,默认为TCPresources: {}  # 资源限制配置,这里未设置,可添加requests(请求资源)和limits(限制资源)terminationMessagePath: /dev/termination-log  # 容器终止时日志的输出路径terminationMessagePolicy: File  # 终止日志的获取策略,File表示从指定文件获取dnsPolicy: ClusterFirst  # DNS策略,ClusterFirst表示优先使用集群内的DNS服务restartPolicy: Always  # 容器重启策略,Always表示容器退出后总是重启schedulerName: default-scheduler  # 使用的调度器名称,默认为default-schedulersecurityContext: {}  # 安全上下文配置,用于设置容器的权限等terminationGracePeriodSeconds: 30  # 容器终止前的优雅退出时间,单位为秒,这段时间内会处理完正在进行的请求

在这里插入图片描述

1.3.4 查看历史版本

通过以下命令可查看Deployment的历史版本信息:

[root@master01 ~]# kubectl rollout history deployment nginx-deployment 
deployment.apps/nginx-deployment 
REVISION  CHANGE-CAUSE
1         <none>  # CHANGE-CAUSE为<none>表示未设置版本变更原因,可在创建Deployment时通过--record参数记录变更原因

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.4 StatefulSet控制器(有状态)

StatefulSet主要用于管理有状态应用,与Deployment管理的无状态应用有显著区别。

1.4.1 核心特点

  1. 稳定存储:基于PVC(PersistentVolumeClaim,持久化存储声明)实现,每个Pod都有独立的存储资源,即使Pod重建,存储的数据也不会丢失。
  2. 稳定网络标识:Pod的名称和DNS名称是固定的,不会因Pod重建或调度到其他节点而改变,确保有状态应用之间的网络通信稳定。
  3. 有序部署/删除:部署Pod时,按照从0 → N-1的顺序创建;删除Pod时,按照从N-1 → 0的顺序删除,保障有状态应用的依赖关系和数据一致性。
  4. 依赖Headless Service:需要与Headless Service(无头服务)配合使用,Headless Service不为Service分配ClusterIP,而是直接通过DNS记录将请求解析到后端Pod的IP地址。

1.4.2 三个核心组件

  1. Headless Service(无头服务):用于为Pod资源标识符生成可解析的DNS记录,使Pod能通过固定的DNS名称进行通信。
  2. volumeClaimTemplates(存储卷申请模板):基于静态或动态PV(PersistentVolume,持久化存储卷)供给方式,为每个Pod资源提供专有的固定存储,每个Pod都会根据该模板自动创建一个PVC。
  3. StatefulSet:用于管控Pod资源,确保Pod按照有序的方式部署、更新和删除,并与Headless Service和volumeClaimTemplates协作,为有状态应用提供稳定的运行环境。

1.4.3 关键问题解答

在 Kubernetes(K8s)的控制器体系中,StatefulSet 是专门为管理“有状态应用”设计的核心控制器。要理解为何需要它,首先要明确“有状态应用”与“无状态应用”的本质差异——前者依赖稳定的身份、持久化数据或有序部署/扩展,而常规的 Deployment(用于无状态应用)无法满足这些需求。

1.4.3.1 StatefulSet 解决的核心问题

Deployment 等无状态控制器的核心逻辑是“替换式管理”:Pod 是临时的、可随意销毁重建的,重建后的 Pod 会分配新的名称、IP,且不绑定固定的存储。但现实中,大量应用(如数据库、分布式集群、消息队列)具备以下“状态依赖”,Deployment 无法支撑:

  1. 稳定的身份标识:Pod 需要固定的名称、网络标识(如 hostname),重建后身份不改变(例如数据库主从节点 mysql-0/mysql-1,不能变成随机名称)。
  2. 持久化数据绑定:每个 Pod 的数据需要独立存储,且重建后仍能挂载原有的存储卷(例如 mysql-0 的数据不能被 mysql-1 复用)。
  3. 有序操作:部署/扩展时需按顺序创建 Pod(如先启动主节点 mysql-0,再启动从节点 mysql-1),删除/缩容时需按逆序执行(先删从节点,再删主节点),避免集群脑裂或数据丢失。
  4. 稳定的网络访问:需要通过固定的 DNS 名称访问 Pod(即使 Pod 重建、IP 变化,DNS 仍指向该 Pod)。

StatefulSet 的设计初衷,就是通过“状态固化”和“有序管理”,解决上述有状态应用的部署痛点。

1.4.3.2 StatefulSet 的核心能力

StatefulSet 通过以下 4 个核心特性,精准匹配有状态应用的需求,这也是它存在的核心价值:

1. 稳定的 Pod 身份:固定的“名称 + Hostname”
  • Deployment 的 Pod 名称是随机生成的(如 nginx-deploy-7f98d7c6b4-2xqzk),重建后名称完全改变;
  • StatefulSet 的 Pod 名称遵循 “StatefulSet 名称 + 序号” 的固定格式(如 redis-cluster-0redis-cluster-1),序号从 0 开始递增,重建后名称和序号不变
  • 同时,每个 Pod 的 hostname 与 Pod 名称完全一致(可通过 spec.hostname 配置),应用可通过 hostname 识别自身或其他节点(例如分布式集群中通过 hostname 确认节点角色)。
2. 持久化数据的“一对一绑定”:基于 PVC 模板的存储分配

StatefulSet 通过 volumeClaimTemplates(存储卷声明模板) 为每个 Pod 自动创建独立的 PVC(PersistentVolumeClaim),并与 Pod 强绑定:

  • 每个 Pod 对应一个专属的 PVC(命名格式:模板名-StatefulSet名-序号,如 data-redis-cluster-0);
  • PVC 会自动绑定到符合条件的 PV(PersistentVolume),Pod 挂载该 PVC 存储数据;
  • 即使 Pod 被销毁重建,新 Pod 仍会挂载原序号对应的 PVC,数据不丢失

对比 Deployment:若使用 PVC,所有 Pod 会共享同一个 PVC(数据冲突);若使用 emptyDir,Pod 销毁后数据直接丢失——均无法满足“每个 Pod 独立持久化”的需求。

3. 有序的部署、扩展与缩容

StatefulSet 严格按照 “序号递增” 执行部署和扩展,按 “序号递减” 执行缩容和删除,确保有状态应用的集群逻辑不被破坏:

  • 部署/扩展(Scale Up):必须等 Pod-0 完全就绪(Running + Ready)后,才创建 Pod-1Pod-1 就绪后再创建 Pod-2,以此类推(例如主从数据库需先启动主节点,再启动从节点并同步数据)。
  • 缩容/删除(Scale Down/Delete):必须先删除 Pod-n(最大序号),待其完全销毁后,再删除 Pod-n-1;最后删除 Pod-0(例如先删从节点,再删主节点,避免从节点无法同步数据)。

对比 Deployment:所有 Pod 并行创建/删除,无法保证顺序,极易导致分布式集群脑裂或数据不一致。

4. 稳定的网络访问:基于 Headless Service 的 DNS 解析

StatefulSet 需配合 Headless Service(无头服务) 使用,为每个 Pod 提供固定的 DNS 域名,即使 Pod 重建、IP 变化,其他组件仍能通过 DNS 稳定访问:

  • DNS 域名格式:Pod名称.Service名称.命名空间.svc.cluster.local(例如 redis-cluster-0.redis-svc.default.svc.cluster.local);
  • Pod 重建后,IP 会变化,但 Pod 名称和 DNS 域名不变,网络访问不中断

对比 Deployment:Pod IP 随机变化,且无固定 DNS 标识,只能通过 Service 的 ClusterIP 访问(负载均衡到任意 Pod),无法指向特定 Pod(如数据库主节点)。

为何必须使用 StatefulSet?
简单来说:Deployment 管理“无状态应用”,核心是“替换”;StatefulSet 管理“有状态应用”,核心是“固化”
当应用需要稳定的身份、独立的持久化数据、有序的操作或固定的网络访问时,Deployment 完全无法满足需求,而 StatefulSet 正是通过“身份固化、数据绑定、有序管理、稳定 DNS”这四大能力,成为 Kubernetes 中管理有状态应用的唯一标准方案。

1.4.3.3 StatefulSet 的典型应用场景

只有当应用具备“状态依赖”时,才需要使用 StatefulSet。常见场景包括:

  1. 分布式数据库:MySQL 主从集群、PostgreSQL 集群、MongoDB 副本集(需固定节点身份、独立数据存储、有序启停);
  2. 分布式缓存:Redis Cluster、Elasticsearch 集群(需节点身份识别、数据分片持久化);
  3. 消息队列:Kafka 集群、RabbitMQ 集群(需 broker 节点固定身份、日志和消息持久化);
  4. 需要固定身份的服务:如分布式锁服务、配置中心(需节点身份唯一,避免重复注册)。

反之,若应用是无状态的(如 Nginx 静态服务、API 接口服务、前端静态页面),则优先使用 Deployment + Service,因为 Deployment 更轻量、调度更灵活(支持滚动更新、并行伸缩)。

1.4.3.4 为什么需要Headless Service?

在Deployment中,每个Pod的名称是随机生成的字符串,且是无序的,Pod重建后名称会改变。而StatefulSet要求Pod有序且名称固定,当Pod所在节点故障,重建后的Pod标识符(名称、DNS)必须保持不变,才能确保有状态应用的正常运行(如数据库主从节点的身份识别)。为了实现标识符的稳定,就需要Headless Service直接将DNS解析到Pod的IP地址,同时给Pod配置唯一且固定的名称。

1.4.3.5 为什么需要volumeClaimTemplates?

大部分有状态应用(如数据库、分布式存储)都需要持久存储,且每个实例的数据是独立的,不能共享存储(若多个数据库实例共享存储,会导致数据冲突和一致性问题)。在Deployment的Pod模板中创建的存储卷是共享的,多个Pod会使用同一个存储卷,无法满足有状态应用的需求。而volumeClaimTemplates会为每个Pod自动生成一个PVC,每个PVC会请求绑定一个独立的PV,从而使每个Pod都有自己专用的存储卷,保障数据独立性。

1.4.4 StatefulSet + NFS 持久卷案例

以下案例将结合NFS(Network File System,网络文件系统)持久卷,实现StatefulSet的部署和使用。

1.4.4.1 定义Headless Service

首先创建Headless Service,为StatefulSet的Pod提供稳定的DNS解析:

vim stateful-headless.yaml
apiVersion: v1  # API版本
kind: Service   # 资源类型为Service
metadata:name: myapp-svc  # Service的名称
spec:ports:- port: 80  # Service暴露的端口name: web  # 端口名称,用于标识clusterIP: None  # 设置为None,表示这是一个Headless Service,不分配ClusterIPselector:app: myapp-pod  # 选择匹配标签为app:myapp-pod的Pod
# 创建Headless Service
kubectl apply -f stateful-headless.yaml

在这里插入图片描述

1.4.4.2 定义StatefulSet(动态存储)

接着创建StatefulSet,配置动态存储申请(需提前部署好StorageClass,此处使用nfs-client-storageclass):

vim stateful-demo.yaml
apiVersion: apps/v1  # API版本
kind: StatefulSet  # 资源类型为StatefulSet
metadata:name: myapp  # StatefulSet的名称
spec:serviceName: myapp-svc  # 关联的Headless Service名称,必须与前面创建的Headless Service名称一致replicas: 3  # 期望的Pod副本数量为3selector:matchLabels:app: myapp-pod  # 选择匹配标签为app:myapp-pod的Podtemplate:  # Pod模板metadata:labels:app: myapp-pod  # 给Pod添加的标签,需与selector匹配spec:containers:- name: myapp  # 容器名称image: ikubernetes/myapp:v1  # 容器使用的镜像及版本ports:- containerPort: 80  # 容器暴露的端口name: web  # 端口名称volumeMounts:  # 容器挂载存储卷的配置- name: myappdata  # 存储卷名称,需与volumeClaimTemplates中的名称一致mountPath: /usr/share/nginx/html  # 存储卷在容器内的挂载路径volumeClaimTemplates:  # 存储卷申请模板- metadata:name: myappdata  # PVC的名称,与volumeMounts中的name对应annotations:  # 注解,用于关联StorageClassvolume.beta.kubernetes.io/storage-class: nfs-client-storageclass  # 指定使用的StorageClass名称,实现动态PV创建spec:accessModes: ["ReadWriteOnce"]  # 存储卷的访问模式,ReadWriteOnce表示只能被一个节点以读写方式挂载resources:requests:storage: 2Gi  # 请求的存储容量为2Gi

解析:由于StatefulSet资源依赖于已存在的Headless Service资源,所以需要先创建名为myapp-svc的Headless Service,用于为每个Pod创建DNS记录。然后创建名为myapp的StatefulSet,通过Pod模板创建3个Pod副本,并基于volumeClaimTemplates向指定的StorageClass请求2Gi的专用存储卷,每个Pod会自动创建一个PVC并绑定到对应的PV。
在这里插入图片描述

1.4.4.3 创建与验证
# 创建StatefulSet
kubectl apply -f stateful-demo.yaml
# 查看StatefulSet、PVC、PV、Pod的状态
kubectl get sts,pvc,pv,pods

在这里插入图片描述
在这里插入图片描述

1.4.4.4 滚动更新

StatefulSet的滚动更新会按照固定顺序进行,先删除并重新创建序号最大的Pod,待其正常运行并就绪后,再更新下一个序号较小的Pod,具体操作如下:

# 修改StatefulSet的Pod模板(如更新镜像版本)
kubectl edit sts myapp
# 观察Pod的更新顺序,会按照2→1→0的顺序更新
kubectl get pods -w

在这里插入图片描述

1.4.4.5 Pod的名称解析

在StatefulSet中,Pod可以通过固定的DNS名称进行通信,DNS名称的格式为(pod_name).(service_name).(namespace_name).svc.cluster.local,具体验证如下:

# 进入myapp-0 Pod的容器内
kubectl exec -it myapp-0 /bin/sh
# 解析myapp-1的DNS名称
nslookup myapp-1.myapp-svc.default.svc.cluster.local
# 解析myapp-2的DNS名称
nslookup myapp-2.myapp-svc.default.svc.cluster.local

从解析结果可以看出,在容器内可以通过Pod的固定DNS名称解析到对应的IP地址,确保了有状态应用之间通信的稳定性。
在这里插入图片描述

1.4.6 无状态与有状态应用对比

对比项无状态(Deployment)有状态(StatefulSet)
Pod 名称随机生成固定、有序(0→N-1)
存储共享存储或无持久卷每个Pod独立PVC
网络标识不固定稳定DNS名称
扩缩容顺序无序有序(依次创建/删除)
应用示例Web、APIMySQL、ZooKeeper

1.5 DaemonSet控制器

1.5.1 核心功能

DaemonSet的核心功能是确保集群中的每个Node节点上都运行一个Pod副本(可通过节点选择器、亲和性等配置控制在特定节点上运行)。它常用于运行系统级的后台任务(守护进程),这些任务需要在每个节点上都存在以提供基础服务。

1.5.2 典型应用场景

  • 日志收集:如Fluentd、Logstash,在每个节点上收集容器和系统日志。
  • 监控:如Prometheus Node Exporter、collectd、Datadog代理、New Relic代理,或Ganglia gmond,在每个节点上采集监控指标。
  • 存储服务:如Ceph、GlusterFS的节点代理程序,确保每个节点都能参与存储集群。

1.5.3 配置案例

vim ds.yaml 
apiVersion: apps/v1  # API版本
kind: DaemonSet  # 资源类型为DaemonSet
metadata:name: nginx-daemonset  # DaemonSet的名称labels:app: nginx  # 标签,用于标识
spec:selector:matchLabels:app: nginx  # 选择匹配标签为app:nginx的Podtemplate:  # Pod模板metadata:labels:app: nginx  # Pod的标签,需与selector匹配spec:containers:- name: nginx  # 容器名称image: nginx:1.15.4  # 容器镜像及版本ports:- containerPort: 80  # 容器暴露的端口
# 创建DaemonSet后,会在每个Node节点上创建一个Pod
kubectl apply -f ds.yaml
# 查看Pod状态,每个节点会有一个对应的Pod
kubectl get pods
# 示例输出(假设有2个Node节点)
nginx-daemonSet-4kr6h   1/1     Running     0          35s
nginx-daemonSet-8jrg5   1/1     Running     0          35s

在这里插入图片描述

1.6 Job控制器

1.6.1 核心功能

Job控制器用于执行一次性任务,当任务完成(Pod的容器成功退出)后,Job会标记为完成状态,不会再重启Pod。如果Pod在执行任务过程中失败(如容器异常退出),Job会根据配置的重试策略重新创建Pod,直到任务成功或达到最大重试次数。

1.6.2 应用场景

  • 数据迁移:如将旧数据库中的数据迁移到新数据库。
  • 批处理:如对大量数据进行批量计算或处理。
  • 安全扫描:如对集群内的节点或应用进行一次性安全漏洞扫描。
  • 离线数据处理:如对历史日志数据进行离线分析。

1.6.3 配置案例1(计算圆周率)

vim job.yaml
apiVersion: batch/v1  # API版本,Job属于batch组下的v1版本
kind: Job  # 资源类型为Job
metadata:name: pi  # Job的名称
spec:template:  # Pod模板spec:containers:- name: pi  # 容器名称image: perl  # 容器镜像,perl镜像包含perl解释器command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]  # 执行的命令,用于计算圆周率的前2000位restartPolicy: Never  # 重启策略,Never表示Pod失败后不重启(Job会重新创建新的Pod)backoffLimit: 4  # 最大重试次数,若Pod失败,Job最多重新创建4次Pod,超过则标记Job为失败
# 创建Job
kubectl apply -f job.yaml
# 查看Job的日志,获取圆周率计算结果
kubectl logs job/pi

参数解释

  • .spec.template.spec.restartPolicy:该属性有三个候选值:OnFailure、Never和Always。默认值为Always。在Job中,只能将此属性设置为OnFailure或Never,若设置为Always,当Pod任务完成后,Kubernetes会不断重启Pod,导致Job无法完成。
  • .spec.backoffLimit:用于设置Job失败后进行重试的次数,默认值为6。默认情况下,除非Pod失败或容器异常退出,Job任务将不间断地重试,一旦达到.spec.backoffLimit设置的次数,作业将被标记为失败。

注意事项:由于perl镜像体积较大,为避免创建Pod时拉取镜像耗时过长,建议提前在所有Node节点上拉取镜像:

docker pull perl

创建Job后,查看Pod状态:

kubectl get pods

在这里插入图片描述

查看任务结果(圆周率前2000位):

kubectl logs pi-4cc8w

在这里插入图片描述

任务完成后,若需清理Job资源,执行以下命令:

kubectl delete -f job.yaml

1.6.4 配置案例2(测试重试策略)

vim job-limit.yaml
apiVersion: batch/v1
kind: Job
metadata:name: busybox  # Job名称
spec:template:spec:containers:- name: busybox  # 容器名称image: busybox  # 容器镜像imagePullPolicy: IfNotPresent  # 镜像拉取策略,本地有则不拉取command: ["/bin/sh", "-c", "sleep 10;date;exit 1"]  # 执行的命令:睡眠10秒→打印当前日期→以退出码1(表示失败)结束restartPolicy: Never  # 不重启PodbackoffLimit: 2  # 最大重试次数为2,即最多创建3个Pod(1个初始Pod+2个重试Pod)

创建Job并查看状态:

kubectl apply -f job-limit.yaml
# 查看Job和Pod状态
kubectl get job,pods
# 示例输出(3个Pod均失败,Job达到重试上限)

在这里插入图片描述

查看Job的事件信息,确认是否达到重试上限:

kubectl describe job busybox

在这里插入图片描述

1.7 CronJob控制器

1.7.1 核心功能

CronJob控制器用于执行周期性任务,其配置方式类似Linux系统中的Crontab(通过Cron表达式定义任务执行周期)。CronJob会根据预设的调度规则自动创建Job,由Job来执行具体的任务。

1.7.2 应用场景

  • 定期备份:如每天凌晨2点备份数据库数据。
  • 定时通知:如每周一上午9点发送集群运行状态报告。
  • 日志清理:如每天凌晨3点清理30天前的日志文件。

1.7.3 配置案例(每分钟打印问候信息)

# 每分钟打印当前日期和问候信息
vim cronjob.yaml
apiVersion: batch/v1beta1  # 注:batch/v1beta1版本的CronJob已逐渐被batch/v1版本替代,推荐使用batch/v1
kind: CronJob
metadata:name: hello  # CronJob的名称
spec:schedule: "*/1 * * * *"  # Cron表达式,*/1 * * * *表示每分钟执行一次jobTemplate:  # Job模板,CronJob会根据该模板创建Jobspec:template:spec:containers:- name: hello  # 容器名称image: busybox  # 容器镜像args:  # 容器启动参数,等效于command- /bin/sh- -c- date; echo Hello from the Kubernetes cluster  # 执行的命令:打印当前日期→打印问候信息restartPolicy: OnFailure  # 重启策略,OnFailure表示只有容器失败时才重启

1.7.4 CronJob其他常用参数配置

除了上述核心配置外,CronJob还有一些常用参数可根据需求调整:

spec:concurrencyPolicy: Allow  # 并发执行策略,Allow表示允许并发执行(默认);Forbid表示禁止并发执行,若前一个Job未完成,后一个Job会被跳过;Replace表示若前一个Job未完成,用后一个Job替换schedule: '*/1 * * * *'  # 作业时间表,此处表示每分钟运行一次startingDeadlineSeconds: 15  # 任务启动超时时间,若Job在调度时间后15秒内未开始执行,则标记为失败successfulJobsHistoryLimit: 3  # 保留的成功完成的Job数量,默认值为3,超过数量的旧Job会被清理failedJobsHistoryLimit: 1  # 保留的失败的Job数量,默认值为1(原文档中未提及,补充此参数使配置更完整)terminationGracePeriodSeconds: 30  # Job的优雅终止时间,默认不设置为永久(实际默认值为30秒,此处按原文档保留说明)jobTemplate:  # 作业模板,与Job的配置一致

1.7.5 创建与验证CronJob

# 创建CronJob
kubectl create -f cronjob.yaml
# 查看CronJob状态
kubectl get cronjob
# 示例输出
NAME    SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   */1 * * * *   False     0        <none>          25s
# 等待几分钟后,查看创建的Pod(每个Pod对应一个Job执行的任务)
kubectl get pods
# 查看某个Pod的日志,确认任务执行结果
kubectl logs hello-1760541720-68w5s

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.7.6 常见问题解决(权限不足)

若执行kubectl logs命令时出现如下权限不足错误:

Error from server (Forbidden): Forbidden (user=system:anonymous, verb=get, resource=nodes, subresource=proxy) ( pods/log hello-1621587780-c7v54)

解决办法:为匿名用户绑定cluster-admin权限(仅用于测试环境,生产环境不建议这样配置,应遵循最小权限原则):

kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

1.8 常规Service与Headless Service对比

Service是Kubernetes中用于暴露Pod服务的资源,分为常规Service和Headless Service,两者的区别如下表所示:

类型是否有ClusterIP访问方式作用
Service(常规)负载均衡 + 服务发现为集群内的Pod提供统一的访问入口,通过负载均衡将请求分发到后端Pod,隐藏Pod的IP地址变化
Headless Service(无头服务)直接解析到Pod IP主要用于StatefulSet中,为Pod提供稳定的DNS名称,使客户端能直接访问到每个Pod,不进行负载均衡

1.9 附录:服务发现机制

Kubernetes通过内置的DNS服务实现服务发现,即Pod可以通过Service的名称或Pod的DNS名称访问其他Pod或Service,无需手动配置IP地址。

1.9.1 Kubernetes内置DNS服务的演进

  • 1.3版本以前:使用SkyDNS作为内置DNS服务。
  • 1.3 ~ 1.11版本:使用KubeDNS作为内置DNS服务,是SkyDNS的改进版本。
  • 1.11版本以后:使用CoreDNS作为内置DNS服务,CoreDNS功能更强大、配置更灵活,目前已成为Kubernetes的默认DNS服务。

1.9.2 Pod间通信的域名格式

在Kubernetes集群中,Pod之间通过以下域名格式进行通信:

(pod_name).(service_name).(namespace).svc.cluster.local
  • pod_name:Pod的名称,对于StatefulSet的Pod,名称是固定的;对于Deployment的Pod,名称是随机的。
  • service_name:Pod关联的Service名称(若为StatefulSet,通常是Headless Service名称)。
  • namespace:Pod和Service所属的命名空间,默认是default。
  • svc.cluster.local:Kubernetes集群的默认DNS域名后缀,可通过集群配置修改。

1.10 Pod控制器总结

控制器是否有状态功能简述
Deployment管理无状态应用,支持部署、滚动升级、回滚
ReplicaSet保证Pod副本数量,通常不直接使用,由Deployment管理
StatefulSet管理有状态应用,提供稳定的网络标识和专属存储
DaemonSet确保每个Node节点上运行一个Pod副本,用于运行守护进程
Job执行一次性任务,任务完成后Pod退出
CronJob执行周期性任务,基于Cron表达式调度

总结

本文围绕 Kubernetes Pod 控制器展开全面解析,从核心概念到实际应用,系统梳理了不同类型控制器的特性与价值,可总结为以下核心要点:

一、控制器的核心定位与共性
Pod 控制器的本质是 “状态协调者”,其核心职责是通过监控 Pod 的当前状态与用户定义的期望状态,自动消除差异 —— 无论是 Pod 异常退出后的重建、副本数量的动态调整,还是版本更新时的服务不中断,均依赖控制器的自动化能力实现,这也是 Kubernetes 声明式编排理念的核心体现。

二、核心控制器的特性与适用场景
无状态应用管理:Deployment 是首选方案,它通过管理 ReplicaSet 实现副本数量维持、滚动更新与版本回滚,适用于 Web 服务、API 接口等无状态场景;ReplicaSet 虽具备副本管理能力,但因缺乏更新与回滚机制,通常不直接使用,而是作为 Deployment 的底层依赖。
有状态应用管理:StatefulSet 是唯一选择,其通过 “稳定网络标识(固定 Pod 名称与 DNS)”“专属存储(基于 PVC 模板)”“有序部署 / 删除” 三大核心特性,解决了数据库(如 MySQL)、分布式集群(如 ZooKeeper)等有状态应用对身份、数据与顺序的依赖问题,且需与 Headless Service 配合实现 DNS 解析。
节点级守护任务:DaemonSet 确保集群中(或指定节点上)每个节点运行一个 Pod 副本,适用于日志收集(Fluentd)、节点监控(Prometheus Node Exporter)等系统级后台任务,无需手动在每个节点部署,实现任务的统一管理。
任务型负载处理:Job 用于执行一次性任务(如数据迁移、批处理),支持失败重试机制;CronJob 则基于 Cron 表达式扩展 Job 的周期性能力,适用于定时备份、日志清理等场景,两者均在任务完成后自动停止,避免资源浪费。

三、关键概念与对比
服务发现与网络标识:常规 Service 通过 ClusterIP 提供负载均衡与统一访问入口,隐藏 Pod IP 变化;Headless Service 无 ClusterIP,直接将 DNS 解析到 Pod IP,仅用于 StatefulSet 等需直接访问 Pod 的场景。
存储与应用类型匹配:无状态应用(Deployment)无需专属存储,可共享存储或使用临时存储;有状态应用(StatefulSet)通过 volumeClaimTemplates 为每个 Pod 分配独立 PVC,确保数据持久化与独立性。
DNS 服务演进:Kubernetes 内置 DNS 从早期的 SkyDNS、KubeDNS,逐步升级为当前默认的 CoreDNS,为 Pod 间通信提供稳定的域名解析能力,域名格式遵循 “Pod 名称。服务名称。命名空间.svc.cluster.local” 规则,无需依赖固定 IP。

四、实践启示
在实际集群管理中,控制器的选择需严格匹配应用特性:无状态应用优先用 Deployment,兼顾效率与灵活性;有状态应用必须用 StatefulSet,确保数据与身份稳定;节点级任务用 DaemonSet,任务型负载按需选择 Job 或 CronJob。同时,需关注配置细节(如 Deployment 的更新策略、StatefulSet 的 Headless Service 依赖、CronJob 的并发控制),避免因参数配置不当导致服务中断或资源浪费。

http://www.dtcms.com/a/485932.html

相关文章:

  • TypeScript前端架构与开发技巧深度解析:从工程化到性能优化的完整实践
  • 郴州做网站网站建设公司ejiew
  • LeetCode 将数组和减半的最少操作次数
  • OpenHarmony南向开发环境搭建 - 深入理解Ubuntu、DevEco Device Tool与HPM
  • QT-day1
  • Spec-Kit+Copilot打造AI规格驱动开发
  • Linux服务器编程实践30-TCP交互数据流:Nagle算法与延迟确认的作用
  • MATLAB一个基于Attention-LSTM的分类模型,构建Attention-LSTM深度学习模型,训练模型并进行分类预测
  • 杭州网站建设朗诵面朝网站建设策划内容
  • 手机网站开发模板南昌网站设计建设
  • Playwright中page的实现类深度解析-PageImpl 方法作用解析
  • 【完整源码+数据集+部署教程】 【运动的&足球】足球场上球检测系统源码&数据集全套:改进yolo11-DGCST
  • 无用知识研究:如何用decltype里的逗号表达式判断一个类里面有operator <号,并在编译时优雅给出提示,而不是一大堆不相干的模板信息
  • 人类知识体系分类
  • Java 大视界 -- Java 大数据在智能政务数字身份认证与数据安全共享中的应用
  • 《Foundation 图标参考手册》
  • 从 “坑“ 到 “通“:Spring AOP 通知执行顺序深度解密
  • 博途SCL语言仿真七段数码管
  • 关于网站建设的介绍本地搭建wordpress建站教程
  • 免费网站收录网站推广苏州网站建设推荐q479185700霸屏
  • 【LeetCode热题100(43/100)】验证二叉搜索树
  • 养殖场疫病预警新方案:小吉快检BL-08plus现场快速锁定病原
  • 【ADS-1】【python基础-3】函数封装与面向对象
  • 攻防世界-Web-baby_web
  • SQLite数据库基本操作
  • git创建分支,以及如何管理
  • Netty线程模型与Tomcat线程模型对比分析
  • STEMlab 125-14 Gen 2
  • 如何租用网站服务器寿光营销型网站建设
  • 云手机玩游戏卡顿的原因都有哪些