Kubernetes 核心控制器与 Service 资源学习笔记
·
第一章:DaemonSet 控制器
1.1 概述
1.1.1 核心定义
DaemonSet 是 Kubernetes 的一种工作负载控制器,确保集群中所有(或指定)节点上都运行一个副本 Pod。当节点加入集群时,自动在新节点创建 Pod;节点离开集群时,自动回收对应 Pod;删除 DaemonSet 时,其管理的所有 Pod 也会被同步删除。
1.1.2 工作原理
- 调度逻辑:DaemonSet Controller 会为每个节点创建一个 Pod,并通过节点亲和性(
nodeAffinity)规则,强制 Pod 调度到目标节点,无需依赖默认调度器。 - 污点容忍:默认情况下,控制节点带有
node-role.kubernetes.io/control-plane:NoSchedule污点,DaemonSet Pod 需配置tolerations才能调度到控制节点。 - 生命周期管理:Pod 与节点绑定,节点删除时 Pod 自动清理;Pod 异常重启后,仍会保留在原节点。
1.1.3 典型应用场景
DaemonSet 专门用于部署节点级守护进程,常见场景包括:
- 集群日志收集:Fluentd、Logstash,每个节点采集容器 / 节点日志
- 节点监控:Prometheus Node Exporter、Zabbix Agent,采集节点 CPU / 内存 / 磁盘指标
- 网络插件:Calico、Flannel,为每个节点提供网络代理功能
- 存储插件:Ceph、Rook 的节点代理组件,管理节点本地存储
- 安全组件:Trivy 节点漏洞扫描、Falco 运行时安全监控
1.1.4 DaemonSet vs Deployment 核心对比
表格
| 维度 | DaemonSet | Deployment |
|---|---|---|
| 调度目标 | 每个节点(或指定节点)运行 1 个 Pod | 集群中任意节点,按副本数调度 |
| 副本管理 | 副本数由节点数决定,不支持独立扩缩容 | 支持手动 / 自动扩缩容,副本数独立于节点数 |
| 更新策略 | 支持 RollingUpdate(滚动更新)和 OnDelete(删除后更新),按节点逐个更新 | 支持 RollingUpdate 和 Recreate,按副本数分批更新 |
| 适用场景 | 节点级守护进程 | 无状态服务(如 Web 服务、API 服务) |
| 网络与存储 | 常使用 hostPath 节点存储,共享节点网络 | 常使用 PVC 动态存储,依赖 Service 提供网络入口 |
1.2 DaemonSet 资源清单编写技巧
1.2.1 基础清单模板(以 Node Exporter 为例)
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: kube-system
labels:
k8s-app: node-exporter
spec:
selector:
matchLabels:
k8s-app: node-exporter
template:
metadata:
labels:
k8s-app: node-exporter
spec:
hostNetwork: true # 共享节点网络,直接监听节点端口
tolerations:
# 容忍控制节点污点,确保控制节点也运行 Pod
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule
containers:
- name: node-exporter
image: prom/node-exporter:v1.8.2
ports:
- containerPort: 9100
hostPort: 9100 # 直接暴露节点 9100 端口
name: metrics
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
# 滚动更新策略,更新时逐个节点替换 Pod
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 10% # 最大不可用节点比例,避免服务中断
1.2.2 关键配置项说明
spec.selector:必须与template.metadkubectl get pods -n kube-system -l k8s-app=node-exporter # 每个节点应运行 1 个 Podata.labels一致,用于匹配管理的 Podspec.template.spec.hostNetwork: true:共享节点网络栈,适用于需要监听节点端口的场景(如监控、网络插件)tolerations:容忍节点污点,确保控制节点(默认禁止普通 Pod 调度)也能运行 DaemonSet PodupdateStrategy:RollingUpdate为滚动更新(默认),OnDelete需手动删除旧 Pod 才会更新
1.3 使用案例:部署 Prometheus Node Exporter
1.将上述清单保存为 node-exporter.yaml,执行创建:
kubectl apply -f node-exporter.yaml
2.验证 DaemonSet 状态:
kubectl get daemonset -n kube-system
# 输出中 DESIRED/READY 数量应与集群节点数一致
3.验证 Pod 运行
kubectl get pods -n kube-system -l k8s-app=node-exporter
# 每个节点应运行 1 个 Pod
4.访问验证:在任意节点上访问 http://<节点IP>:9100/metrics,查看节点监控指标。
第二章:StatefulSet 控制器
2.1 概念与原理解读
2.1.1 有状态服务 vs 无状态服务
表格
| 维度 | 无状态服务(Deployment) | 有状态服务(StatefulSet) |
|---|---|---|
| 实例标识 | 无固定标识,Pod 重启 / 调度后标识变化 | 稳定唯一标识(如 web-0、web-1),重启后不变 |
| 网络访问 | 依赖 Service 负载均衡,无固定访问地址 | 依赖 Headless Service 提供稳定 DNS 域名,每个 Pod 有独立域名 |
| 数据存储 | 临时存储或共享存储,数据不持久化 | 绑定独立 PVC,数据持久化,Pod 重建后仍可挂载原存储 |
| 部署 / 扩缩容 | 并行部署 / 删除,无序 | 有序部署(从 0 到 N)、有序删除(从 N 到 0),扩缩容时逐个处理 |
| 典型场景 | Nginx、API 服务、微服务 | MySQL、Redis、ZooKeeper、Kafka 等分布式存储 / 中间件 |
2.1.2 StatefulSet 核心组成
- StatefulSet 控制器:管理 Pod 生命周期,确保有序部署、扩缩容、更新
- Headless Service:为每个 Pod 提供稳定 DNS 域名,无 ClusterIP,仅提供 DNS 解析
- VolumeClaimTemplates:动态为每个 Pod 创建独立 PVC,实现数据持久化(Pod 删除时 PVC 默认保留)
2.1.3 Headless Service 详解
- 定义:
clusterIP: None的特殊 Service,不提供负载均衡,仅实现 DNS 解析 - 域名格式:
<pod-name>.<service-name>.<namespace>.svc.cluster.local - 作用:为 StatefulSet 的每个 Pod 提供稳定网络标识,支持有状态服务的集群内部通信(如 MySQL 主从同步、Redis 集群节点通信)
2.2 StatefulSet 资源清单编写技巧
2.2.1 基础清单模板(部署有状态 Nginx 服务)
# 1. Headless Service 定义(为 Pod 提供稳定 DNS)
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
namespace: default
spec:
selector:
app: nginx-statefulset
ports:
- port: 80
name: web
clusterIP: None # 声明为 Headless Service
---
# 2. StatefulSet 定义
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-statefulset
namespace: default
spec:
serviceName: nginx-headless # 关联 Headless Service
replicas: 3 # 副本数,Pod 会按 0、1、2 编号创建
selector:
matchLabels:
app: nginx-statefulset
template:
metadata:
labels:
app: nginx-statefulset
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
# PVC 模板:为每个 Pod 动态创建独立 PVC
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard" # 需集群已配置对应存储类
resources:
requests:
storage: 1Gi
# 滚动更新策略,支持灰度发布
updateStrategy:
type: RollingUpdate
rollingUpdate:
partition: 0 # 仅更新序号 ≥ partition 的 Pod,可用于分阶段更新
2.2.2 关键配置项说明
spec.serviceName:必须关联一个 Headless Service,用于 Pod 的 DNS 解析spec.replicas:副本数,Pod 名称会按0~replicas-1编号(如nginx-statefulset-0)volumeClaimTemplates:动态 PVC 模板,每个 Pod 会自动创建一个名为www-<pod-name>的 PVC,Pod 删除时 PVC 不会自动删除,需手动清理updateStrategy.rollingUpdate.partition:指定滚动更新的起始序号,仅更新序号 ≥partition的 Pod,可实现灰度发布(如partition: 2表示仅更新序号 ≥ 2 的 Pod)
2.3 使用案例:部署有状态 Web 站点(Nginx)
1.将上述清单保存为 nginx-statefulset.yaml,执行创建:
kubectl apply -f nginx-statefulset.yaml
2.验证 Pod 有序创建:
kubectl get pods -l app=nginx-statefulset
# 输出中 Pod 名称应按 0、1、2 编号,且逐个启动
3.验证 PVC 创建:
kubectl get pvc
# 每个 Pod 对应一个独立 PVC(www-nginx-statefulset-0 等)
4.验证 DNS 解析:
# 在集群内任意 Pod 中执行 nslookup,解析 Pod 域名
nslookup nginx-statefulset-0.nginx-headless.default.svc.cluster.local
# 应解析到 nginx-statefulset-0 的 Pod IP
5.测试数据持久化:
- 进入
nginx-statefulset-0Pod,修改/usr/share/nginx/html/index.html内容 - 删除 Pod:
kubectl delete pod nginx-statefulset-0 - 新 Pod 重建后,访问页面验证修改内容仍存在(数据持久化)
第三章:Service 资源对象
3.1 概述
3.1.1 核心作用
Service 为一组 Pod 提供稳定的访问入口,实现负载均衡与服务发现,解耦客户端与 Pod 的生命周期(Pod IP 会动态变化,Service 提供固定 IP/DNS)。
3.1.2 工作机制
Service 通过标签选择器(selector)匹配后端 Pod,kube-proxy 组件在每个节点上实现 Service 的网络规则,将请求转发到后端 Pod。
3.2 kube-proxy 的三种工作模式详解
3.2.1 模式对比总览
表格
| 模式 | 实现原理 | 优缺点 | 适用场景 |
|---|---|---|---|
userspace | 监听节点端口,用户空间代理转发请求 | 兼容性好,性能差(用户态 / 内核态切换开销大),已弃用 | 早期 K8s 版本,不推荐生产使用 |
iptables | 通过 iptables 规则实现数据包转发,内核态直接处理 | 性能比 userspace 好,无用户态开销;但规则数量大时性能下降,仅支持随机负载均衡 | 中小规模集群,K8s 1.10-1.20 默认模式 |
ipvs | 基于 Linux IPVS 模块实现负载均衡,支持多种调度算法 | 性能高,支持大规模集群,调度算法丰富(rr、wrr、lc 等) | 大规模生产集群,K8s 1.11+ 推荐 |
3.2.2 各模式细节说明
userspace模式:kube-proxy 在用户空间监听节点端口,接收请求后通过代理转发到后端 Pod,存在两次上下文切换,性能差,K8s 1.10 后已逐步弃用。iptables模式:kube-proxy 在节点上生成大量 iptables NAT 规则,直接在内核态转发请求;但当集群中 Service 和 Pod 数量过多时,iptables 规则会非常庞大,匹配效率下降,且仅支持随机负载均衡。ipvs模式:kube-proxy 调用 Linux 内核的 IPVS 模块(高性能四层负载均衡模块),创建 IPVS 虚拟服务器,支持以下调度算法:rr(轮询):按顺序将请求分发到后端 Podwrr(加权轮询):根据 Pod 权重分发请求lc(最少连接):将请求分发到连接数最少的 Podwlc(加权最少连接):结合权重与连接数分发请求sh(源地址哈希):根据客户端 IP 哈希分发请求,实现会话保持dh(目标地址哈希):根据目标 IP 哈希分发请求
3.2.3 模式切换方法
修改 kube-proxy 配置文件的 --proxy-mode 参数(如设置为 ipvs),需确保节点内核已开启 IPVS 模块:
# 查看 kube-proxy 配置
kubectl get configmap kube-proxy -n kube-system -o yaml
# 修改 mode: "ipvs" 后,重启 kube-proxy Pod
kubectl rollout restart daemonset kube-proxy -n kube-system
3.3 Service 资源类型详解
3.3.1 常见 Service 类型对比
表格
| 类型 | 定义 | 访问方式 | 适用场景 |
|---|---|---|---|
ClusterIP | 默认类型,分配集群内部 IP,仅集群内可访问 | 集群内 DNS/ClusterIP:Port | 微服务间内部通信(如 API 服务、数据库) |
NodePort | 在每个节点上暴露一个端口(30000-32767),外部可通过节点 IP:NodePort 访问 | 节点 IP:NodePort | 开发 / 测试环境,临时对外暴露服务 |
LoadBalancer | 在 NodePort 基础上,结合云厂商负载均衡器,对外提供统一访问入口 | 云 LB IP:Port | 公有云环境,生产服务对外暴露 |
ExternalName | 将 Service 映射到外部域名,无后端 Pod,仅做 DNS 解析 | 集群内访问 ExternalName 域名 | 访问集群外部服务(如第三方 API) |
Headless Service | clusterIP: None 的特殊 Service,不提供负载均衡,仅 DNS 解析 | Pod 域名:Port | StatefulSet 有状态服务,Pod 间直接通信 |
3.3.2 各类型配置示例
ClusterIP Service(默认类型)
apiVersion: v1
kind: Service
metadata:
name: nginx-clusterip
spec:
selector:
app: nginx
ports:
- port: 80 # Service 端口
targetPort: 80 # 后端 Pod 端口
type: ClusterIP # 可省略,默认类型
NodePort Service
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 可选,不指定则随机分配 30000-32767 端口
type: NodePort
LoadBalancer Service(需云厂商支持)
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: LoadBalancer
ExternalName Service
apiVersion: v1
kind: Service
metadata:
name: external-api
spec:
type: ExternalName
externalName: api.example.com # 映射的外部域名
3.4 Service 核心特性补充
- 会话保持:通过
spec.sessionAffinity: ClientIP实现基于客户端 IP 的会话保持,适用于需要会话一致性的场景(如 Web 应用)。 - 多端口配置:一个 Service 可定义多个
ports,对应后端 Pod 的不同端口(如同时暴露 HTTP 80 端口和 HTTPS 443 端口)。 - 命名端口:支持为 Pod 端口命名,Service 可通过名称引用端口(如
targetPort: "web"),提高配置可读性。
核心总结
- DaemonSet:节点级守护进程的控制器,确保每个节点运行一个实例,适用于日志、监控、网络插件等场景。
- StatefulSet:有状态服务的控制器,提供稳定网络标识与持久化存储,支持有序部署与扩缩容,适用于分布式存储 / 中间件。
- Service:服务发现与负载均衡组件,为 Pod 提供稳定访问入口,依赖 kube-proxy 实现网络转发,支持多种类型与负载均衡模式。
更多推荐


所有评论(0)