【Kubernetes】(二)k8s基础——Node和Pod
目录
1.2 一个完整的 Node 必须具备哪些核心组件,否则无法加入集群并正常工作?
(1)Kubernetes 核心节点组件(负责管理 Pod 和节点)
2.1 为什么 K8s 要设计 Pod 这一层,而非直接调度容器?
4.1 Pod 的调度逻辑:从 “待分配” 到 “运行中”
七、可以认为 “运行在 Node 上的工作组件也是 Pod 吗?”
问题 2:Pod 状态显示 “CrashLoopBackOff”
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 可定义 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 状态)。
更多推荐


所有评论(0)