工作节点组件详解:kubelet、kube-proxy 与容器运行时
摘要:深入了解 Kubernetes 工作节点(Worker Node)上运行的三大核心组件:kubelet、kube-proxy、容器运行时,以及它们如何协同工作。
一、Worker Node 组件全景
工作节点负责运行 Pod 中的容器,由 kubelet、kube-proxy 和容器运行时协同完成。kubelet 管理 Pod 生命周期,kube-proxy 维护网络规则,容器运行时负责实际创建和运行容器。
上图展示了工作节点上三大组件的职责划分:kubelet 作为节点代理与 API Server 通信并驱动容器运行时;kube-proxy 实现 Service 的流量转发;容器运行时通过 CRI 接口执行容器操作。
二、kubelet — 节点代理
2.1 核心职责
kubelet 是运行在每个节点上的代理程序(Agent),是 Worker Node 上最重要的组件。
kubelet 从 API Server 获取分配到本节点的 Pod 清单,调用容器运行时创建和启动容器,执行健康检查探针,并管理 Pod 所需的存储卷挂载。
2.2 工作流程
kubelet 通过 Watch API Server 获取 Pod 变更,收到本节点 Pod 后执行创建、启动、监控等操作。
kubelet 解析 Pod 规格后,先挂载 Volume,再通过 CRI 调用容器运行时拉取镜像并启动容器,最后持续执行健康检查并上报状态。
2.3 健康检查详解
kubelet 支持三种探针(Probe)来检查容器健康状态:
- Liveness Probe:检测容器是否存活,失败时 kubelet 杀死并重启容器。
- Readiness Probe:检测容器是否就绪接收流量,失败时从 Service 端点列表中移除,不重启。
- Startup Probe:检测容器是否启动完成,适用于 Java 等慢启动应用。
检查方式包括:HTTP GET(200-399 表示健康)、TCP Socket、Exec Command、gRPC。
配置示例:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
containers:
- name: app
image: my-app:v1
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
三、kube-proxy — 网络代理
3.1 职责
kube-proxy 运行在每个节点上,负责实现 Service 的网络规则,将访问 Service 的流量转发到后端 Pod。
当 Service 或 Endpoints 变更时,kube-proxy 更新本节点的 iptables 或 IPVS 规则,将 ClusterIP 流量转发到实际 Pod IP。
3.2 代理模式
kube-proxy 支持三种代理模式,不同模式在性能和功能上有所差异。
- iptables 模式:默认模式,通过内核 iptables 规则转发,性能较好,规则过多时可能影响性能。
- IPVS 模式:使用内核 IPVS 模块,支持多种负载均衡算法(rr、lc、dh、sh、sed、nq),适合大规模集群。
- nftables 模式:Kubernetes 1.31+ 新增,使用 nftables 替代 iptables,更易维护。
3.3 流量转发流程(iptables 模式)
客户端 Pod 访问 Service 时,请求经 kube-proxy 配置的 DNAT 规则转发到后端 Pod。
kube-proxy 为每个 Service 配置 DNAT 规则,将 ClusterIP:port 映射到多个 Pod IP:targetPort,流量按配置的算法随机或轮询转发。
四、Container Runtime — 容器运行时
4.1 演进历史
Kubernetes 1.24 起移除 dockershim,kubelet 直接通过 CRI 对接 containerd 或 CRI-O。
dockershim 已废弃,推荐使用 containerd(通用)或 CRI-O(专为 K8s 设计,常见于 OpenShift)。
4.2 CRI(Container Runtime Interface)
CRI 是 Kubernetes 定义的标准接口,使 kubelet 可对接多种容器运行时实现。
通过 CRI,Kubernetes 不依赖特定容器运行时,只需实现 RuntimeService 和 ImageService 即可接入。
4.3 containerd vs CRI-O
| 特性 | containerd | CRI-O |
|---|---|---|
| 来源 | Docker 项目拆分 | Red Hat 主导 |
| 用户 | 最广泛 | OpenShift |
| 功能范围 | 通用容器运行时 | 专为 K8s 设计 |
| 生态 | Docker 生态兼容 | OCI 标准兼容 |
五、 Pod 创建流程
在工作节点上,kubelet 创建 Pod 的完整流程如下:
kubelet 先创建 Pod Sandbox(网络命名空间、pause 容器),再通过 CNI 分配 Pod IP,拉取镜像后依次启动 Init 容器和主容器,执行 postStart Hook 并开始健康检查,最后将 Pod 状态更新为 Running。
六、节点资源管理
kubelet 将节点资源划分为系统预留、K8s 预留、驱逐阈值和可分配部分,可分配资源用于运行 Pod。
Allocatable = Total - SystemReserved - KubeReserved - EvictionThreshold。资源不足时,kubelet 会根据驱逐策略驱逐部分 Pod。
七、常用 kubectl 命令
# 查看所有节点
kubectl get nodes
# 查看节点详情
kubectl describe node <node-name>
# 查看节点资源
kubectl get nodes -o custom-columns='NAME:.metadata.name,CPU:.status.capacity.cpu,MEMORY:.status.capacity.memory'
# 污点节点(禁止调度)
kubectl taint nodes node1 key=value:NoSchedule
# 取消污点
kubectl taint nodes node1 key:NoSchedule-
kubectl describe node 输出包括 Conditions(Ready、MemoryPressure、DiskPressure、PIDPressure)、Capacity、Allocatable 等关键信息。
八、常见问题
Q1:如何切换 kube-proxy 为 IPVS 模式?
修改 kube-proxy DaemonSet,设置 --proxy-mode=ipvs 并确保加载 ip_vs 等内核模块。部分发行版需额外安装 ipvsadm。
Q2:kubelet 启动失败常见原因?
常见原因包括:证书过期、kubeconfig 配置错误、容器运行时未就绪、磁盘空间不足、cgroup 驱动不匹配等。可通过 journalctl -u kubelet 查看日志。
Q3:如何配置节点资源预留?
在 kubelet 启动参数中设置 --system-reserved、--kube-reserved、--eviction-hard 等。例如:--system-reserved=cpu=500m,memory=1Gi。
九、总结
| 组件 | 职责 |
|---|---|
| kubelet | 节点代理,管理 Pod 生命周期、汇报状态、执行健康检查 |
| kube-proxy | 维护网络规则,实现 Service 负载均衡与流量转发 |
| Container Runtime | 通过 CRI 拉取镜像、创建和运行容器 |
所有组件仅与 API Server 通信,不直接访问 etcd。CRI 使 Kubernetes 不依赖特定容器运行时。
更多推荐
所有评论(0)