目录

一、Node:K8s 集群的 “工作节点”​

1.1 在 K8s 集群中,Node 分为哪两种角色:?

1.2 一个完整的 Node 必须具备哪些核心组件,否则无法加入集群并正常工作?

(1)Kubernetes 核心节点组件(负责管理 Pod 和节点)

(2)容器运行时(负责实际运行容器)

1.3 Node上除核心组件外,还有什么?

二、Pod:K8s 最小的 “部署单元”​

2.1 为什么 K8s 要设计 Pod 这一层,而非直接调度容器?

2.2 Pod 的核心特性​

2.3 pod内部包含什么?

 (1)容器(Containers)

(2)存储卷(Volumes)

(3)网络配置

(4)资源限制(Resources)

(5)初始化容器(Init Containers)

2.4 层级关系

三、Node和Pod的关系:Pod 运行在 Node 上

四、Node与Pod如何协作

4.1 Pod 的调度逻辑:从 “待分配” 到 “运行中”​

(1)提交请求

(2)调度决策

(3)绑定 Node

(4)启动 Pod

4.2 Node 对 Pod 的 “管理职责”​

五、Node和Pod的生命周期

5.1 Pod 的生命周期

5.2 Node 的生命周

六、 Node 与 Pod 的常用命令

6.1 Node 相关操作

6.2 Pod 相关操作

七、可以认为 “运行在 Node 上的工作组件也是 Pod 吗?”

八、常见问题与解决方案​

8.1 Node 常见问题​

问题 1:Node 状态显示 “NotReady”​

问题 2:Pod 无法调度到 Node 上​

8.2 Pod 常见问题​

问题 1:Pod 状态显示 “Pending”​

问题 2:Pod 状态显示 “CrashLoopBackOff”​

问题 3:Pod 内容器之间无法通信​


ps:建议与【Kubernetes】2-2 k8s集群架构 结合进行理解

一、Node:K8s 集群的 “工作节点”​

Node 是 K8s 集群中的工作节点,可以理解为集群的 “硬件载体”—— 它本质上是一台物理机或虚拟机,负责承载 Pod 的运行。

1.1 在 K8s 集群中,Node 分为哪两种角色:?

  • Worker Node(工作节点):主要承担 Pod 的调度、运行任务,是集群中实际 “干活” 的节点,包含容器运行时(如 Docker、containerd)、kubelet、kube-proxy 等核心组件;​
  • Master Node(控制节点,现多称为 Control Plane):负责集群的管理与控制(如 Pod 调度、节点管理、资源监控等),早期版本中 Master 也可运行 Pod,但现代 K8s 集群通常会通过 “污点容忍” 设置,让 Master 仅专注于控制功能,避免业务 Pod 占用其资源。​

1.2 一个完整的 Node 必须具备哪些核心组件,否则无法加入集群并正常工作?

(1)Kubernetes 核心节点组件(负责管理 Pod 和节点)

这类组件是 k8s 控制 Node 并运行 Pod 的基础,核心包括:

  • kubelet
    • 作用:每个 Node 必须运行的 “管家” 组件,负责监听 k8s 集群(API Server)下发的 Pod 调度指令,然后调用容器运行时启动 / 停止 Pod 中的容器,同时监控 Pod 健康状态(如重启异常容器)、上报 Node 资源使用情况。
    • 运行形式:非 Pod,通常是 Node 操作系统的系统服务(如 Linux 下的 systemd 服务)。
    • 关键原因:kubelet 负责启动 Pod,若它自身是 Pod,会陷入 “先有鸡还是先有蛋” 的依赖问题(需要 Pod 被启动,但启动 Pod 又需要 kubelet),因此必须以系统服务形式先于所有 Pod 启动。
  • kube-proxy
    • 作用:实现 k8s 的 “Service 网络代理” 功能,负责将 Service 的虚拟 IP(VIP)流量转发到后端对应的 Pod,同时维护 Node 上的网络规则(如 iptables 或 ipvs 规则),确保 Pod 间、外部与 Pod 间的网络通信。
    • 运行形式:多数情况下是 Pod(由 k8s 的 DaemonSet 控制器管理,会在每个 Node 上自动部署一个 kube-proxy Pod);早期 k8s 版本中曾是系统服务,现在主流版本(1.14+)均为 Pod 形式。

(2)容器运行时(负责实际运行容器)

Pod 的本质是 “容器组”,Pod 中的容器需要依赖 容器运行时 才能启动和管理,这类组件也是 Node 的核心部分:

  • 常见组件:containerd(目前 k8s 默认推荐)、CRI-O、Docker(需配合 cri-dockerd 适配 CRI 接口)。
  • 作用:接收 kubelet 的指令(通过 CRI 接口),负责容器的创建、销毁、资源隔离(CPU / 内存限制)、镜像拉取等底层操作。
  • 运行形式:非 Pod,通常是 Linux 下的 systemd 服务(如 containerd.service),直接与操作系统内核交互(如通过 runc 运行容器)。

1.3 Node上除核心组件外,还有什么?

(1)Node 自身的系统进程(支撑节点基础运行)

除了 k8s 相关组件,Node 作为一台独立的服务器(物理机 / 虚拟机),还运行着操作系统自身的进程,这些是节点能正常工作的基础:

  • 示例:systemd(系统初始化进程,管理所有系统服务)、sshd(远程登录服务)、rsyslogd/journald(日志收集进程)、chronyd(时间同步进程)、内核进程(如 kworker、ksoftirqd)等。
  • 运行形式:非 Pod,是操作系统原生进程,与 k8s 无关,但直接影响 Node 的稳定性(如时间同步异常会导致 Pod 日志时间错乱、证书验证失败)。

(2)可选的插件组件(增强 Node 能力)

根据集群需求,Node 上还可能运行一些插件类组件,这些组件通常以 Pod 形式部署(通过 DaemonSet):

  • 网络插件:如 Calico 的 calico-node Pod、Flannel 的 flannel Pod,负责为 Pod 分配 IP 地址、实现跨 Node Pod 通信。
  • 存储插件:如 CSI(容器存储接口)的 Node 端插件(如 csi-node-driver-registrar),负责将 Node 本地存储或分布式存储挂载到 Pod 中。
  • 监控插件:如 node-exporter(Prometheus 生态组件),以 Pod 形式运行,采集 Node 的 CPU、内存、磁盘等硬件指标。


二、Pod:K8s 最小的 “部署单元”​

Pod 是 K8s 中最小的部署和调度单元,而非容器 —— 很多新手会误以为 Pod 等同于容器,实际上 Pod 是 “容器的集合”,它可以包含一个或多个紧密关联的容器(如业务容器 + 日志收集容器),这些容器共享 Pod 的网络命名空间(IP 地址、端口)和存储卷(Volume)。​

2.1 为什么 K8s 要设计 Pod 这一层,而非直接调度容器?

       核心原因是 紧耦合容器的协同需求:有些容器之间必须紧密协作(如业务容器需要日志容器 实时收集日志,或监控容器实时采集指标),它们需要共享网络(可通过localhost通信)和存储(可共享数据文件),而 Pod 恰好为这些容器提供了 “统一的运行环境”,确保它们始终在同一 Node 上调度、启动和停止。​

2.2 Pod 的核心特性​

  • 共享网络:一个 Pod 内的所有容器共享同一个 IP 地址和端口范围,容器之间可通过localhost直接通信,外部访问 Pod 需通过 Pod 的 IP + 容器端口;​
  • 共享存储:Pod 可定义 Volume(存储卷),挂载到内部的多个容器中,实现容器间的数据共享;​
  • 生命周期一致:Pod 内的所有容器 “同生共死”—— 当 Pod 被删除、重启或调度到其他 Node 时,内部所有容器会同时停止并重新启动;​
  • 不可自愈性:Pod 本身是 “脆弱” 的,一旦出现故障(如容器崩溃、Node 宕机),Pod 不会自动恢复,需依赖 K8s 的控制器(如 Deployment、StatefulSet)实现自愈(重新创建 Pod)

2.3 pod内部包含什么?

 (1)容器(Containers

  • 主容器(Main Container:承载核心业务逻辑(如运行 nginx 提供 Web 服务、运行 mysql 提供数据库服务)。
  • Sidecar 容器:为主容器提供辅助功能(如日志收集、流量代理):
    • 日志收集:如 fluentd 容器,收集主容器日志并转发到 Elasticsearch。
    • 服务网格代理:如 envoy 容器,实现流量劫持、灰度发布、链路追踪。

(2)存储卷(Volumes

Pod 可挂载多种存储卷,实现容器间数据共享或持久化存储:

  • emptyDir:临时存储(Pod 重启后数据丢失),用于容器间临时共享数据。
  • hostPath:挂载节点本地路径(如 /var/log),适合日志收集等场景。
  • PersistentVolumeClaim (PVC):挂载持久化存储(如云硬盘、NFS),适合数据库等有状态服务。

(3)网络配置

  • Pod IP:每个 Pod 分配一个集群内唯一的 IP 地址,Pod 内所有容器共享该 IP
  • 端口(Ports:容器暴露的端口(如 containerPort: 80),可通过 Service 对外暴露。

(4)资源限制(Resources

为 Pod 内的容器设置 CPU / 内存的请求(requests)和限制(limits),避免资源过度占用:

resources:
  requests:
    cpu: "100m"  # 至少需要 0.1 核 CPU
    memory: "256Mi"  # 至少需要 256MB 内存
  limits:
    cpu: "1"  # 最多允许使用 1 核 CPU
    memory: "512Mi"  # 最多允许使用 512MB 内存

(5)初始化容器(Init Containers

在主容器启动前运行的容器,用于完成前置任务(如数据库迁移、等待依赖服务就绪):

initContainers:
- name: init-mysql
  image: mysql:8.0
  command: ["sh", "-c", "until mysql -h mysql-service -u root -p${PASSWORD} -e 'SELECT 1'; do echo 'Waiting for MySQL...'; sleep 5; done"]

2.4 层级关系


三、Node和Pod的关系:Pod 运行在 Node 上

  • Pod 必须依赖 Node 存在:Pod 不能脱离 Node 独立运行,它的生命周期完全依赖于所在的 Node。Kubernetes 通过 “调度器(Scheduler)” 将 Pod 分配到合适的 Node 上,然后由 Node 上的 kubelet 组件负责启动、监控和管理 Pod 中的容器。
  • 一个 Node 可以运行多个 Pod:Node 的资源(CPU、内存等)决定了能运行的 Pod 数量。Kubernetes 会根据 Pod 的资源需求(requests)和 Node 的可用资源进行调度,避免单个 Node 负载过高。
  • Pod 与 Node 的绑定是动态的
    • 当 Node 故障(如宕机、网络断开)时,Kubernetes 会将该 Node 上的 Pod 标记为 “不可用”,并在其他健康的 Node 上重新创建这些 Pod(前提是 Pod 由 Deployment 等控制器管理)。
    • 当 Node 资源不足时,新的 Pod 不会被调度到该 Node 上,直到资源释放(如旧 Pod 被删除)。


四、Node与Pod如何协作

4.1 Pod 的调度逻辑:从 “待分配” 到 “运行中”​

当我们通过kubectl apply -f pod.yaml创建 Pod 时,K8s 会经历以下调度流程,将 Pod 分配到合适的 Node 上:​

(1)提交请求

用户或控制器(如 Deployment)向 K8s API Server 提交 Pod 创建请求,API Server 将 Pod 信息存入 etcd(K8s 的数据库);​

(2)调度决策

K8s 的调度器(Scheduler)监听 API Server,发现 “待调度” 的 Pod 后,会根据以下规则筛选合适的 Node:​

        硬性约束(Node Selector/Affinity):如 Pod 要求 Node 必须具备 “环境 = 生产”“CPU 架构 = amd64” 等标签,不满足约束的 Node 会被直接排除;​

        资源需求:Pod 会声明 CPU、内存等资源需求(requests),调度器会筛选出资源充足(剩余 CPU / 内存≥Pod 需求)的 Node;​

        软性偏好(Node Affinity):如优先将 Pod 调度到 “负载较低” 或 “同区域” 的 Node 上(非强制约束,仅作为调度参考);​

(3)绑定 Node

调度器确定合适的 Node 后,会通过 API Server 将 Pod 与 Node “绑定”(更新 etcd 中的 Pod 绑定信息);​

(4)启动 Pod

目标 Node 上的 kubelet 监听 API Server,发现 “绑定到本 Node” 的 Pod 后,会通过容器运行时创建 Pod 内的容器,最终将 Pod 状态更新为 “Running”。​

4.2 Node 对 Pod 的 “管理职责”​

当 Pod 调度到 Node 后,Node 会通过 kubelet 和容器运行时,承担起 Pod 的全生命周期管理,主要包括:​

  • 启动管理:根据 PodSpec 的配置,拉取容器镜像、创建共享 Volume、配置网络,确保容器按预期启动;​
  • 状态监控:kubelet 会定期检查 Pod 内容器的健康状态(通过 liveness probe 存活探针、readiness probe 就绪探针),若容器崩溃,会根据 Pod 的重启策略(RestartPolicy)决定是否重启容器;​
  • 资源限制:根据 PodSpec 中声明的资源限制(limits),限制容器的 CPU 和内存使用 —— 若容器超出内存限制,会被直接终止;若超出 CPU 限制,会被限制 CPU 使用率(不会终止);​
  • 销毁管理:当 Pod 需要删除(如执行kubectl delete pod <pod-name>)时,kubelet 会先向容器发送终止信号(SIGTERM),等待 grace period(默认 30 秒)后,若容器仍未退出,则强制终止(SIGKILL),最后清理 Pod 的网络和存储资源。


五、Node和Pod的生命周期

5.1 Pod 的生命周期

Pod 是 Kubernetes 中最小的部署单元,其生命周期分为 4 个核心阶段,并通过控制器(如 Deployment、StatefulSet)实现高可用:

  • Pending(待调度)
    Pod 已被创建,但尚未调度到具体 Node。此时 Kubernetes 调度器正在筛选合适的 Node(需满足资源请求、亲和性、污点等条件)。
  • Running(运行中)
    Pod 已调度到 Node,且至少一个容器正常启动。若容器重启(如崩溃),kubelet 会根据重启策略(RestartPolicy)重试(默认指数退避延迟:10 秒→20 秒→40 秒… 上限 5 分钟,若容器稳定运行 10 分钟则重置延迟)。
  • Succeeded(成功结束)
    Pod 中所有容器以0 状态码正常退出,且不会再重启(如一次性任务 Job)。
  • Failed(失败终止)
    Pod 中至少一个容器以非 0 状态码退出,或被系统强制终止(如资源耗尽)。若重启策略为 Never,Pod 会直接进入此阶段;若为 Always,容器会持续重启,但 Pod 阶段仍为 Running。

5.2 Node 的生命周期

Node 是 Pod 的运行载体,其生命周期围绕 “注册→健康运行→下线” 展开,核心状态由 Kubernetes 自动维护:

  • 注册阶段
    新 Node 启动后,kubelet 向 API Server 发起注册请求,提交节点 IP、资源容量(CPU / 内存 / 磁盘)、标签等信息。若配置了云服务商(如 AWS、GKE),Node 名称由云厂商分配;否则使用主机名(可通过 --hostname-override 覆盖)。
  • 健康运行阶段
    • 心跳机制:kubelet 每 10 秒向 API Server 上报节点状态(Ready/NotReady),并在 kube-node-lease 命名空间维护一个 lease 对象(每 10 秒更新,默认超时 40 秒)。
    • 状态监控:node-controller(控制器管理器组件)持续检查节点心跳。若节点失联超过 --node-monitor-grace-period(默认 40 秒,v1.32+ 为 50 秒),则标记为 Unknown,并添加污点(node.kubernetes.io/unreachable)防止新 Pod 调度。
  • 下线阶段
    • 主动维护:通过 kubectl drain 节点名 安全驱逐 Pod(先标记节点为 NoSchedule,再优雅终止 Pod,最后标记为 NotReady)。
    • 被动故障:若节点宕机或资源耗尽(如内存 / 磁盘压力触发 MemoryPressure/DiskPressure),node-controller 会在等待 5 分钟后强制驱逐 Pod,并将节点标记为 Failed。


六、 Node 与 Pod 的常用命令

6.1 Node 相关操作

操作目的

命令示例

说明

查看所有 Node 状态

kubectl get nodes

输出 Node 名称、状态(Ready/NotReady)、角色等

查看 Node 详细信息

kubectl describe node <node-name>

查看 Node 的资源使用、标签、污点、已调度的 Pod 等

给 Node 打标签

kubectl label node <node-name> env=prod

用于 Pod 的 Node Selector/Affinity 调度

给 Node 添加污点

kubectl taint node <node-name> key=value:NoSchedule

阻止新 Pod 调度到该 Node(常用于 Master 节点)

移除 Node 的污点

kubectl taint node <node-name> key:NoSchedule-

允许 Pod 重新调度到该 Node

cordon(封锁)Node

kubectl cordon <node-name>

标记 Node 为 “不可调度”,已运行的 Pod 不受影响

drain(排空)Node

kubectl drain <node-name> --ignore-daemonsets

驱逐 Node 上的所有 Pod(用于 Node 维护)

6.2 Pod 相关操作

操作目的

命令示例

说明

查看所有 Pod 状态

kubectl get pods -n <namespace>

-n指定命名空间,默认是default

查看 Pod 详细信息

kubectl describe pod <pod-name> -n <namespace>

查看 Pod 的调度情况、容器日志、事件等

创建 Pod

kubectl apply -f pod.yaml

通过 YAML 文件创建 Pod(推荐方式)

删除 Pod

kubectl delete pod <pod-name> -n <namespace>

强制删除可加--force --grace-period=0

查看 Pod 日志

kubectl logs <pod-name> -n <namespace>

查看指定 Pod 的日志,加-f可实时跟踪

查看 Pod 内指定容器日志

kubectl logs <pod-name> -c <container-name> -n <namespace>

当 Pod 有多个容器时需指定容器名

进入 Pod 内的容器

kubectl exec -it <pod-name> -c <container-name> -n <namespace> -- /bin/bash

交互式进入容器(类似docker exec

查看 Pod 的资源使用

kubectl top pod <pod-name> -n <namespace>

需先部署 metrics-server 组件


      七、可以认为 “运行在 Node 上的工作组件也是 Pod 吗?”

      不可以一概而论,需根据组件的 “功能定位” 和 “启动依赖” 区分:

      组件类型

      是否为 Pod

      典型例子

      关键原因

      k8s 核心管理组件

      部分是

      kubelet(非)、kube-proxy(是)

      kubelet 需先于 Pod 启动,不能是 Pod;kube-proxy 用 DaemonSet 管理更易维护

      容器运行时

      containerd、CRI-O

      需直接与内核交互,且为 kubelet 提供容器启动能力,不能依赖 Pod 形式

      Node 操作系统原生进程

      systemd、sshd、内核进程

      是节点底层基础,与 k8s 无关,不属于 k8s 资源范畴

      网络 / 存储 / 监控插件

      calico-node、node-exporter

      需随 Node 动态部署(DaemonSet),用 Pod 形式便于统一调度和版本管理

      Node 上除了 Pod,还包含 kubelet、容器运行时、系统原生进程 等核心组件,以及可选的插件 Pod;   

      运行在 Node 上的 “工作组件” 不全是 Pod:

              核心管理组件(如 kubelet)、容器运行时、系统进程 不是 Pod(因启动依赖或底层交互需求);

              网络 / 代理 / 监控类插件(如 kube-proxy、calico-node) Pod(通过 DaemonSet 统一管理,更灵活)。

      区分的关键是:是否依赖 Pod 启动机制(如 kubelet 不能依赖 Pod)、是否需要 k8s 调度管理(如插件需要 DaemonSet 调度)。


      八、常见问题与解决方案​

      以下是高频问题的排查思路和解决方案

      8.1 Node 常见问题​

      问题 1:Node 状态显示 “NotReady”​

      排查步骤:​

      ① 执行kubectl describe node <node-name>,查看 “Conditions” 部分的错误信息(如 NetworkUnavailable、KubeletNotReady);​

      ② 登录 Node 服务器,检查核心组件状态:​

              容器运行时:systemctl status docker(或containerd),若未启动则执行systemctl start docker;​

              kubelet:systemctl status kubelet,查看日志journalctl -u kubelet -f,常见原因是 kubelet 配置错误或与 API Server 通信失败;​

      ③ 检查 Node 网络:确保 Node 能访问 API Server 的地址和端口(如 6443),防火墙规则未阻止 K8s 相关流量。​

      问题 2:Pod 无法调度到 Node 上​

      常见原因与解决方案:​

      • 资源不足:Node 剩余 CPU / 内存不足,执行kubectl top node <node-name>查看资源使用,可删除 Node 上无用 Pod 或扩容 Node;​
      • Node 有污点:Node 存在NoSchedule污点,执行kubectl describe node <node-name>查看污点,若需调度 Pod,可移除污点或给 Pod 添加对应的容忍(Toleration);​
      • Pod 的 Node Selector 不匹配:Pod 指定了 Node 标签,但目标 Node 无该标签,执行kubectl get node --show-labels查看 Node 标签,给 Node 添加对应标签或修改 Pod 的 Node Selector。​

      8.2 Pod 常见问题​

      问题 1:Pod 状态显示 “Pending”​

      原因:Pod 未被调度到 Node 上,执行kubectl describe pod <pod-name>查看 “Events” 部分,常见原因包括:​

      • 资源不足、Node 污点、Node Selector 不匹配(解决方案同上);​
      • 镜像拉取失败:Events 显示 “Failed to pull image”,检查镜像地址是否正确、镜像仓库是否可访问(如私有仓库需配置 imagePullSecrets)。​

      问题 2:Pod 状态显示 “CrashLoopBackOff”​

      原因:Pod 内的容器启动后立即崩溃,反复重启,排查步骤:​

      ① 执行kubectl logs <pod-name> -p(-p查看上一次启动的日志),查看容器崩溃的具体原因(如配置文件错误、端口被占用、程序报错);​

      ② 检查 Pod 的重启策略(RestartPolicy),若设置为Never,容器崩溃后不会重启,需根据业务需求修改为Always或OnFailure;​

      ③ 检查容器的资源限制,若内存限制过低,程序可能因 OOM(内存溢出)崩溃,需适当提高resources.limits.memory。​

      问题 3:Pod 内容器之间无法通信​

      原因:Pod 内容器共享网络,正常情况下可通过localhost通信,若通信失败,排查步骤:​

      ① 执行kubectl exec <pod-name> -c <container1> -- ping localhost:<container2-port>,检查端口是否监听;​

      ② 查看容器是否正常运行:kubectl get pods <pod-name> -o jsonpath='{.status.containerStatuses[*].ready}',确保所有容器处于 “Ready” 状态;​

      ③ 检查 Pod 的网络配置,若使用了网络插件(如 Calico、Flannel),确保网络插件正常运行(kubectl get pods -n kube-system查看网络插件 Pod 状态)。

      Logo

      码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

      更多推荐