目录
Replication Controller(RC)
概念
关键字段
Replica Set(RS)
概念
关键字段
RC 与 RS 的区别
无状态应用管理Deployment
无状态应用(Stateless Application)
什么是无状态?
无状态服务的特点
典型无状态应用
Kubernetes Deployment 管理无状态应用
实例:用 Deployment 部署 Nginx
有状态应用(Stateful Application)
什么是有状态?
有状态服务的特点
典型有状态应用
Kubernetes StatefulSet 管理有状态应用
实例:用 StatefulSet 部署 MySQL
无状态 vs 有状态:关键区别
守护进程集DaemonSet
DaemonSet 的核心概念
什么是 DaemonSet?
DaemonSet 的工作原理
DaemonSet 的典型应用场景
日志收集
监控代理
网络插件
存储插件
DaemonSet 的关键配置
节点选择(Node Selector)
污点容忍(Tolerations)
更新策略(Update Strategy)
资源限制
DaemonSet vs Deployment vs StatefulSet区别
CronJob 的核心概念
什么是 CronJob?
CronJob 的工作原理
CronJob 的关键组成部分
Cron 表达式
Job 模板
并发策略
历史记录保留
CronJob 的典型应用场景
定时备份数据库
定期清理日志
定时发送通知
CronJob 的常见问题与排查
任务未执行
任务并发冲突
任务失败重试
CronJob vs Deployment vs DaemonSet区别
在 Kubernetes 中,Replication Controller(RC,复制控制器)和Replica Set(RS,复制集)是用于管理 Pod 副本数量的核心控制器,它们确保集群中始终运行指定数量的 Pod 副本,实现应用的高可用性和弹性伸缩。
Replication Controller(RC)
概念
- 核心功能:确保在任何时刻都有指定数量的 Pod 副本运行。如果实际 Pod 数量少于期望值,RC 会自动创建新的 Pod;如果多于期望值,RC 会终止多余的 Pod。
- 适用场景:适用于需要长期运行的服务(如 Web 服务器),确保服务始终可用。
- 历史地位:RC 是 Kubernetes 早期版本中管理 Pod 副本的主要方式,现已逐渐被 Deployment 取代,但在旧版本或简单场景中仍可能使用。
关键字段
replicas
:期望的 Pod 副本数量。selector
:通过标签选择器匹配需要管理的 Pod。template
:定义 Pod 的模板,包括容器镜像、端口等。
实例
RC实例,确保始终运行 3 个 nginx
Pod
apiVersion: v1
kind: ReplicationController
metadata:name: nginx-rc
spec:replicas: 3selector:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80
操作步骤:
创建 RC:kubectl apply -f rc.yaml
查看 RC 状态:kubectl get rc
查看 Pod:kubectl get pods --selector=app=nginx
验证高可用性:
- 手动删除一个 Pod:
kubectl delete pod <pod-name>
- 观察 RC 是否自动创建新的 Pod 以维持 3 个副本。
Replica Set(RS)
概念
- 核心功能:与 RC 类似,但支持更灵活的标签选择器(基于集合的匹配规则),是 RC 的升级版。
- 适用场景:通常与 Deployment 配合使用,实现 Pod 的滚动更新和回滚。
- 现状:RS 是 Kubernetes 推荐的管理 Pod 副本的方式,但直接使用 RS 的场景较少,更多是通过 Deployment 间接使用。
关键字段
replicas
:期望的 Pod 副本数量。selector
:支持基于集合的标签选择器(如matchLabels
或matchExpressions
)。template
:定义 Pod 的模板。
实例
RS实例,确保始终运行 3 个 nginx
Pod
apiVersion: apps/v1
kind: ReplicaSet
metadata:name: nginx-rs
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80
操作步骤:
创建 RS:kubectl apply -f rs.yaml
查看 RS 状态:kubectl get rs
查看 Pod:kubectl get pods --selector=app=nginx
验证高可用性:
- 手动删除一个 Pod:
kubectl delete pod <pod-name>
- 观察 RS 是否自动创建新的 Pod 以维持 3 个副本。
RC 与 RS 的区别
特性 | Replication Controller(RC) | Replica Set(RS) |
---|---|---|
标签选择器 | 基于等式的简单选择器(如 app=nginx ) | 支持基于集合的选择器(如 matchLabels 、matchExpressions ) |
灵活性 | 较低 | 更高,支持更复杂的标签匹配规则 |
推荐使用场景 | 旧版本或简单场景 | 推荐与 Deployment 配合使用 |
API 版本 | v1 | apps/v1 |
无状态应用管理Deployment
在 Kubernetes 中,无状态应用和有状态应用的管理方式不同,Deployment 是管理无状态应用的核心控制器,而 StatefulSet 则用于有状态应用。
无状态应用(Stateless Application)
什么是无状态?
无状态应用是指不依赖本地存储或持久化数据的应用,每个请求的处理不依赖于之前的请求或会话状态。所有实例(Pod)都是完全相同的,可以随时被替换或扩展。
无状态服务的特点
- 可扩展性:可以随意增加或减少实例数量,不影响服务逻辑。
- 高可用性:单个实例崩溃不会影响整体服务,其他实例可以继续处理请求。
- 无持久化需求:数据通常存储在外部数据库(如 MySQL、Redis)或对象存储(如 S3)中,而非本地磁盘。
- 无顺序依赖:实例之间没有固定的启动顺序或依赖关系。
- 水平扩展简单:通过增加副本(Replica)即可提升处理能力。
典型无状态应用
- Web 服务器(如 Nginx、Apache)
- API 服务(如 RESTful 服务)
- 微服务(如用户认证服务、订单服务)
- 计算任务(如批处理、数据处理)
Kubernetes Deployment 管理无状态应用
Deployment 是 Kubernetes 中管理无状态应用的标准方式,它通过 ReplicaSet 控制 Pod 副本数量,支持滚动更新、回滚和自动扩缩容。
实例:用 Deployment 部署 Nginx
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 3 # 3 个副本selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80
操作步骤:
创建 Deployment:kubectl apply -f nginx-deployment.yaml
查看 Pod:kubectl get pods -l app=nginx
扩展副本:kubectl scale deployment nginx-deployment --replicas=5
滚动更新:修改镜像版本后执行 kubectl rollout restart deployment/nginx-deployment
有状态应用(Stateful Application)
什么是有状态?
有状态应用是指依赖本地存储或持久化数据的应用,每个实例(Pod)可能有唯一的身份标识,并且数据、状态或配置不能随意丢失或替换。
有状态服务的特点
- 持久化存储:数据通常存储在本地磁盘(如 PV/PVC),且需要保证数据不丢失。
- 固定身份标识:每个实例有唯一的名称或 ID(如
pod-0
、pod-1
),不能随意替换。 - 启动顺序依赖:实例之间可能有固定的启动顺序(如主从架构)。
- 水平扩展复杂:不能简单增加副本,需要考虑数据同步和一致性。
- 高可用性挑战:单个实例崩溃可能导致数据不一致或服务中断。
典型有状态应用
- 数据库(如 MySQL、PostgreSQL、MongoDB)
- 分布式存储(如 Ceph、GlusterFS)
- 消息队列(如 Kafka、RabbitMQ)
- 分布式计算框架(如 Spark、Flink)
Kubernetes StatefulSet 管理有状态应用
StatefulSet 是 Kubernetes 中管理有状态应用的核心控制器,它提供以下功能:
- 稳定的网络标识:每个 Pod 有唯一的 DNS 名称(如
pod-0.nginx.default.svc.cluster.local
)。 - 持久化存储:通过 PVC(PersistentVolumeClaim) 绑定存储卷,确保数据不丢失。
- 有序部署和扩展:按顺序启动或终止 Pod(如
pod-0
→pod-1
→pod-2
)。 - 有序滚动更新:支持分批更新,确保数据一致性。
实例:用 StatefulSet 部署 MySQL
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql
spec:serviceName: "mysql" # 用于 DNS 发现replicas: 3selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: "password"ports:- containerPort: 3306volumeMounts:- name: mysql-datamountPath: /var/lib/mysqlvolumeClaimTemplates: # 自动创建 PVC- metadata:name: mysql-dataspec:accessModes: [ "ReadWriteOnce" ]resources:requests:storage: 10Gi
操作步骤:
创建 StatefulSet:kubectl apply -f mysql-statefulset.yaml
查看 Pod:kubectl get pods -l app=mysql
(会看到 mysql-0
、mysql-1
、mysql-2
)
查看 PVC:kubectl get pvc
(会自动创建 3 个 PVC)
测试数据持久化:删除 Pod 后,数据仍然存在(因为 PVC 绑定到 PV)。
无状态 vs 有状态:关键区别
数据存储 | 数据存储在外部(数据库、对象存储) | 数据存储在本地(PV/PVC) |
实例标识 | 所有实例相同,可随意替换 | 每个实例有唯一标识(如 pod-0 ) |
启动顺序 | 无顺序依赖 | 可能有固定启动顺序(如主从) |
扩展方式 | 直接增加副本 | 需要考虑数据同步和一致性 |
Kubernetes 控制器 | Deployment | StatefulSet |
典型用例 | Web 服务、API 服务 | 数据库、分布式存储、消息队列 |
守护进程集DaemonSet
DaemonSet 是 Kubernetes 中的一种核心控制器,用于在集群中的每个节点(Node)上运行一个指定的 Pod 副本(或特定节点上运行)。它确保所有(或部分)节点都运行一个特定的守护进程(如日志收集、监控代理、网络插件等),通常用于管理节点级别的服务
DaemonSet 的核心概念
什么是 DaemonSet?
- 定义:DaemonSet 是一种 Kubernetes 工作负载资源,用于在集群中的每个节点(或符合条件的节点)上部署并运行一个 Pod 副本。
- 用途:运行节点级别的守护进程,例如:
- 日志收集(如 Fluentd、Filebeat)
- 监控代理(如 Prometheus Node Exporter、Datadog Agent)
- 网络插件(如 Calico、Flannel、Cilium)
- 存储插件(如 Ceph、NFS 客户端)
- 设备管理(如 GPU 驱动、特殊硬件代理)
DaemonSet 的工作原理
- 自动部署:当新节点加入集群时,DaemonSet 会自动在该节点上创建对应的 Pod。
- 自动清理:当节点被移除时,DaemonSet 会自动删除该节点上的 Pod。
- 节点选择:可以通过
nodeSelector
或tolerations
控制 DaemonSet 在哪些节点上运行(例如,仅在特定标签的节点上运行)。 - 更新策略:支持滚动更新(
RollingUpdate
)或静态更新(OnDelete
)。
DaemonSet 的典型应用场景
日志收集
- 需求:每个节点上的容器日志需要集中收集到日志系统(如 ELK、Loki)。
- 实现:使用 DaemonSet 部署 Fluentd 或 Filebeat,确保每个节点都有一个日志收集器。
- 实例:
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluentd
spec:selector:matchLabels:name: fluentdtemplate:metadata:labels:name: fluentdspec:containers:- name: fluentdimage: fluent/fluentd:latestvolumeMounts:- name: varlogmountPath: /var/logvolumes:- name: varloghostPath:path: /var/log # 挂载节点本地目录
监控代理
- 需求:收集每个节点的资源指标(CPU、内存、磁盘等)。
- 实现:使用 DaemonSet 部署 Prometheus Node Exporter 或 Datadog Agent。
- 示例:
apiVersion: apps/v1
kind: DaemonSet
metadata:name: node-exporter
spec:selector:matchLabels:app: node-exportertemplate:metadata:labels:app: node-exporterspec:containers:- name: node-exporterimage: prom/node-exporter:latestports:- containerPort: 9100
网络插件
- 需求:为每个节点提供网络功能(如 CNI 插件)。
- 实现:Calico、Flannel、Cilium 等网络插件通常以 DaemonSet 形式部署。
- 示例(Calico):
apiVersion: apps/v1
kind: DaemonSet
metadata:name: calico-node
spec:selector:matchLabels:k8s-app: calico-nodetemplate:metadata:labels:k8s-app: calico-nodespec:containers:- name: calico-nodeimage: calico/node:latestenv:- name: CALICO_NETWORKING_BACKENDvalue: "bird"
存储插件
- 需求:为节点提供本地存储或分布式存储访问能力。
- 实现:Ceph CSI、NFS Client Provisioner 等存储插件通常以 DaemonSet 形式部署。
- 示例(NFS Client):
apiVersion: apps/v1
kind: DaemonSet
metadata:name: nfs-client
spec:selector:matchLabels:app: nfs-clienttemplate:metadata:labels:app: nfs-clientspec:containers:- name: nfs-clientimage: quay.io/external_storage/nfs-client-provisioner:latestvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesvolumes:- name: nfs-client-rootnfs:server: nfs-server.example.compath: /exports
DaemonSet 的关键配置
节点选择(Node Selector)
- 通过
nodeSelector
指定 DaemonSet 在哪些节点上运行
spec:template:spec:nodeSelector:disktype: ssd # 仅在标签为 disktype=ssd 的节点上运行
污点容忍(Tolerations)
- 如果节点有污点(Taint),DaemonSet 需要配置
tolerations
才能运行:
spec:template:spec:tolerations:- key: "node-role.kubernetes.io/master"operator: "Exists"effect: "NoSchedule" # 允许在 Master 节点上运行
更新策略(Update Strategy)
- RollingUpdate(默认):自动滚动更新 Pod(逐个节点更新)。
- OnDelete:仅在手动删除 Pod 后更新(适用于需要严格控制更新的场景)。
spec:updateStrategy:type: RollingUpdate # 或 OnDelete
资源限制
- 为 DaemonSet 的 Pod 设置 CPU/内存限制:
spec:template:spec:containers:- name: fluentdimage: fluent/fluentd:latestresources:limits:cpu: "500m"memory: "512Mi"
DaemonSet vs Deployment vs StatefulSet区别
特性 | DaemonSet | Deployment | StatefulSet |
---|---|---|---|
部署目标 | 每个节点运行一个 Pod | 任意数量的 Pod(可扩展) | 每个 Pod 有唯一标识和持久化存储 |
典型用例 | 日志收集、监控代理、网络插件 | Web 服务、API 服务 | 数据库、分布式存储、消息队列 |
节点绑定 | 强制绑定到节点 | 不绑定节点 | 不绑定节点(除非配合 PVC) |
更新策略 | RollingUpdate 或 OnDelete | RollingUpdate 或 Recreate | RollingUpdate(有序更新) |
扩展方式 | 不能直接扩展(每个节点一个) | 可随意扩展副本数 | 可扩展,但需考虑数据一致性 |
- DaemonSet 适用于:需要在每个节点上运行一个守护进程的场景(如日志、监控、网络、存储)。
- 与 Deployment 的区别:DaemonSet 强制在每个节点运行一个 Pod,而 Deployment 可以任意扩展副本数。
- 与 StatefulSet 的区别:DaemonSet 不关心 Pod 的唯一标识或持久化存储,而 StatefulSet 会为每个 Pod 分配唯一名称并绑定 PVC。
CronJob 的核心概念
CronJob 是 Kubernetes 中的一种控制器资源,用于在预定的时间或周期性地运行任务(如备份、数据清理、日志轮转等)。它基于 Unix/Linux 的 cron
定时任务机制,但扩展到了 Kubernetes 集群环境中,支持容器化任务的调度。
什么是 CronJob?
- 定义:CronJob 是 Kubernetes 中用于管理定时任务的资源,它会在指定的时间或周期性触发 Job(一次性任务),进而运行一个或多个 Pod。
- 用途:
- 定时备份数据库(如每天凌晨 3 点执行)。
- 定期清理临时文件或日志。
- 定时发送通知或报告。
- 执行批处理任务(如数据聚合、ETL)。
CronJob 的工作原理
Cron 表达式:定义任务的执行时间(如 0 3 * * *
表示每天凌晨 3 点)。
Job 创建:CronJob 根据 Cron 表达式创建 Job,Job 再创建 Pod 执行任务。
历史记录:默认保留最近 3 次成功的 Job(可配置)。
并发控制:支持禁止并发执行(避免上次任务未完成时新任务启动)。
CronJob 的关键组成部分
Cron 表达式
- 格式:
分钟 小时 日 月 星期
(共 5 个字段,用空格分隔)。 - 示例:
0 3 * * *
:每天凌晨 3 点执行。*/15 * * * *
:每 15 分钟执行一次。0 0 * * 0
:每周日午夜执行。0 2 1 * *
:每月 1 日凌晨 2 点执行。
- 时区支持:Kubernetes 1.25+ 支持通过
spec.timeZone
指定时区(如Asia/Shanghai
)。
Job 模板
- CronJob 通过
spec.jobTemplate
定义要运行的 Job 配置,包括:- Pod 模板(镜像、命令、环境变量等)。
- 重启策略(默认
Never
,即任务失败不重试)。 - 资源限制(CPU/内存)。
并发策略
- Allow(默认):允许并发执行(上次任务未完成时新任务仍会启动)。
- Forbid:禁止并发执行(上次任务未完成时跳过新任务)。
- Replace:替换当前任务(取消上次任务并启动新任务)。
历史记录保留
successfulJobsHistoryLimit
:保留成功的 Job 数量(默认 3)。failedJobsHistoryLimit
:保留失败的 Job 数量(默认 1)。
CronJob 的典型应用场景
定时备份数据库
apiVersion: batch/v1
kind: CronJob
metadata:name: mysql-backup
spec:schedule: "0 3 * * *" # 每天凌晨 3 点jobTemplate:spec:template:spec:containers:- name: backupimage: mysql:5.7command: ["/bin/sh", "-c"]args: ["mysqldump -u root -ppassword mydb > /backup/mydb-$(date +\\%Y\\%m\\%d).sql"]volumeMounts:- name: backup-storagemountPath: /backupvolumes:- name: backup-storagepersistentVolumeClaim:claimName: backup-pvc # 绑定到 PVCrestartPolicy: Never # 任务失败不重试
定期清理日志
apiVersion: batch/v1
kind: CronJob
metadata:name: clean-logs
spec:schedule: "0 0 * * *" # 每天午夜jobTemplate:spec:template:spec:containers:- name: cleanerimage: busyboxcommand: ["/bin/sh", "-c"]args: ["find /var/log -name '*.log' -mtime +7 -delete"]volumeMounts:- name: varlogmountPath: /var/logvolumes:- name: varloghostPath:path: /var/log # 挂载节点本地日志目录restartPolicy: Never
定时发送通知
apiVersion: batch/v1
kind: CronJob
metadata:name: send-report
spec:schedule: "0 9 * * 1" # 每周一上午 9 点jobTemplate:spec:template:spec:containers:- name: senderimage: curlimages/curlcommand: ["/bin/sh", "-c"]args: ["curl -X POST -H 'Content-Type: application/json' -d '{\"message\":\"Weekly report\"}' https://api.example.com/notify"]restartPolicy: Never
CronJob 的常见问题与排查
任务未执行
- 检查 Cron 表达式:确认时间格式正确(如
0 3 * * *
不是3 0 * * *
)。 - 检查时区:Kubernetes 1.25+ 支持
spec.timeZone
,旧版本使用 UTC 时间。 - 检查 Job 历史:
kubectl get jobs --sort-by='.metadata.creationTimestamp'
。
任务并发冲突
- 如果任务执行时间超过间隔周期,需设置
concurrencyPolicy: Forbid
或Replace
。
任务失败重试
- CronJob 默认不重试失败任务(
restartPolicy: Never
),如需重试需在 Job 模板中配置:
backoffLimit: 3 # 失败后重试 3 次
查看任务日志
# 获取最近一次 Job 的名称
JOB_NAME=$(kubectl get jobs -l cronjob-name=hourly-task --sort-by='.metadata.creationTimestamp' -o jsonpath='{.items[-1].metadata.name}')# 查看 Pod 日志
kubectl logs -l job-name=$JOB_NAME
CronJob vs Deployment vs DaemonSet区别
特性 | CronJob | Deployment | DaemonSet |
---|---|---|---|
用途 | 定时任务(如备份、清理) | 长运行服务(如 Web 服务) | 节点级守护进程(如日志收集) |
执行方式 | 周期性创建 Job → Pod | 直接运行 Pod | 每个节点运行一个 Pod |
生命周期 | 任务完成后 Pod 终止 | Pod 持续运行 | Pod 持续运行 |
并发控制 | 支持禁止并发(Forbid ) | 无并发控制(可扩展副本) | 无并发控制(每个节点一个) |
典型用例 | 数据库备份、日志轮转 | API 服务、微服务 | Fluentd、Node Exporter |
- CronJob 适用于:需要在固定时间或周期性执行的任务(如备份、清理、通知)。
- 与 Deployment 的区别:CronJob 是临时任务,而 Deployment 是长期运行的服务。
- 与 DaemonSet 的区别:CronJob 是定时任务,而 DaemonSet 是节点级守护进程。