Kubernetes 工作节点包含哪些组件?各自负责什么?
Kubernetes 工作节点是实际运行 Pod 的机器,核心组件通常包括 kubelet、容器运行时、kube-proxy,再加上 CNI、CSI、日志和监控代理等配套组件。控制平面负责“决定应该是什么状态”,工作节点负责“把这个状态跑出来并持续汇报”。如果一个节点 NotReady,排查也通常围绕这几件事展开:kubelet 有没有连上 API Server,容器运行时能不能创建容器,网络插件是否正常,磁盘、内存、PID 是否触发压力状态。
kubelet 负责什么?
kubelet 是节点上的主代理,它从 API Server 获取分配到本节点的 Pod 规范,然后通过 CRI 调用 containerd 或 CRI-O 创建容器。它还负责挂载卷、执行探针、上报 Node 和 Pod 状态,并在容器异常退出时根据 restartPolicy 做处理。可以用下面的命令看 kubelet 和节点状态:
bashkubectl describe node <node-name> journalctl -u kubelet -n 100 --no-pager crictl ps -a crictl logs <container-id>
kubelet 的边界也要说清楚:它不负责为 Pod 选择节点,那是 scheduler 的工作;它也不直接实现 Service 负载均衡,那主要由 kube-proxy 或 eBPF 数据面完成。很多人看到 Pod 起不来就重启 kubelet,但如果根因是镜像拉取失败、PVC 挂载失败或 CNI 没准备好,重启只会掩盖现场。
容器运行时和 kube-proxy 各做什么?
容器运行时负责真正创建容器、拉镜像、管理容器生命周期。现在主流选择是 containerd 或 CRI-O,Docker 的 dockershim 在 Kubernetes 1.24 之后已经移除;如果还用 Docker,也通常是通过额外适配层接入。kube-proxy 负责根据 Service 和 EndpointSlice 维护节点上的转发规则,常见模式有 iptables 和 IPVS,有些集群会用 Cilium 等 eBPF 方案替代它的部分职责。
yamlapiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: "ipvs" ipvs: scheduler: "rr"
iptables 模式简单、兼容性好;IPVS 在大规模 Service 场景下性能和算法选择更好,但需要内核模块支持。取舍不是“哪个更高级”,而是集群规模、内核能力、运维熟悉度和网络插件支持是否匹配。
追问
Node Ready 由什么决定?
Node Ready 主要由 kubelet 上报,背后包含 kubelet 自身健康、容器运行时可用性、网络是否就绪以及节点压力状态等信息。你可以用 kubectl describe node 看 Conditions,包括 Ready、MemoryPressure、DiskPressure、PIDPressure、NetworkUnavailable。边界是 Ready=True 只表示节点可参与调度,不代表节点上的每个 Pod 都健康;Pod 是否对外服务还要看 readinessProbe 和 Service 后端。生产排障时要把 Node 条件、Pod 事件和容器日志放在一起看。
cordon 和 drain 有什么区别?
cordon 只是把节点标记为不可调度,新 Pod 不会再放到这个节点,已有 Pod 不受影响。drain 会驱逐普通 Pod,常用于节点维护或下线:
bashkubectl cordon <node-name> kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data kubectl uncordon <node-name>
取舍点在于你是否要立刻迁走工作负载;只做内核参数检查可能 cordon 就够了,重启机器或换盘通常需要 drain。踩坑是 DaemonSet 不会被 drain 删除,带本地 emptyDir 的 Pod 可能丢临时数据,所以命令参数要看清楚。
kube-proxy 出问题会表现成什么?
典型表现是 Pod 本身正常,但通过 Service 访问失败,或者只有部分节点访问 Service 异常。可以检查 kube-proxy 日志、Service 后端和节点转发规则:
bashkubectl get svc,endpointslices -A kubectl logs -n kube-system -l k8s-app=kube-proxy --tail=100 iptables-save | grep KUBE-SVC | head
如果集群使用 IPVS,还要看 ipvsadm -Ln。边界是 DNS 解析失败不一定是 kube-proxy,CoreDNS、NetworkPolicy、CNI 路由同样可能导致服务不可达。不要一上来就删除 kube-proxy Pod,先确认是所有节点异常还是单节点异常。
节点压力状态会怎样影响 Pod?
MemoryPressure、DiskPressure、PIDPressure 触发后,节点可能拒绝新 Pod 调度,严重时 kubelet 会按 QoS 和驱逐阈值清理 Pod。BestEffort Pod 最容易被驱逐,Guaranteed Pod 相对更稳,但也不是绝对免死。实际取舍是给关键服务设置合理 requests/limits,同时给系统和 kubelet 预留资源。一个常见坑是日志撑爆磁盘导致 DiskPressure,应用没改一行代码,却出现镜像拉取失败、容器创建失败和 Pod 被驱逐。
工作节点需要哪些日常巡检?
至少要巡检 kubelet、containerd、CNI、磁盘、内存、节点证书和系统时间。常用命令包括:
bashkubectl get nodes -o wide kubectl top nodes systemctl status kubelet containerd journalctl -u containerd -n 50 --no-pager
巡检的边界是不要只看 Kubernetes 对象,底层内核、磁盘 inode、conntrack 表、时间同步都会影响节点稳定性。对于生产集群,建议把节点 NotReady、DiskPressure、kubelet 证书过期、容器运行时重启次数纳入告警。节点问题越早在系统层发现,越不容易演变成业务层故障。