一、Pod 到底是什么?(最核心定义)

Pod = Kubernetes 中最小的调度 / 运行单元

  • 不是容器,是一层包裹容器的 “逻辑组”
  • 一个 Pod 里可以放 1 个或多个紧密相关的容器
  • K8s 永远不会直接调度容器,只会调度 Pod

大白话比喻

  • 容器 = 一个独立的小盒子
  • Pod = 一组共享 “房间、网络、柜子” 的小盒子组合
  • K8s = 只按 “房间(Pod)” 分配机器,不按 “盒子(容器)” 分配

二、Pod 的 2 个核心共享特性(必须懂)

同一个 Pod 里的所有容器,完全共享两样东西

1. 共享网络(同一个 IP)

  • 整个 Pod 只有 1 个 IP
  • 容器之间用 localhost 就能互相访问
  • 端口不能冲突

2. 共享存储(Volume)

  • 可以挂同一个目录 / 磁盘
  • 容器 A 写的文件,容器 B 能直接读

这就是为什么日志容器、监控容器、业务容器适合放同一个 Pod


三、Pod 内部结构(你部署时卡在这里过)

一个标准 Pod 由三部分组成:

1. 基础设施容器:pause(最关键!)

就是你之前报错拉取不到的:

plaintext

registry.k8s.io/pause:3.8

作用:

  • 给整个 Pod 提供网络命名空间
  • 分配 Pod IP
  • 所有业务容器共享它的网络
  • 只要 Pod 存在,pause 就存在

2. 业务容器(App Container)

  • 真正跑服务的容器(Nginx、MySQL、Java、Calico、apiserver)
  • 你看到的 Running/Crash 都是指它们

3. Init 容器(初始化容器)

  • 在业务容器之前运行
  • 用于初始化:等待依赖、拉配置、建表、预热
  • 你看到的状态:

    plaintext

    Init:ImagePullBackOff
    Init:0/1
    
    就是它在拉镜像或执行初始化

四、Pod 的生命周期(运行流程)

  1. Pending:正在调度、拉镜像、初始化
  2. ContainerCreating:创建容器
  3. Running:正常运行
  4. Succeeded:正常退出(一次性任务)
  5. Failed:异常退出
  6. Unknown:失联(节点挂了)

五、你最常遇到的 Pod 状态(全是你踩过的坑)

1. Pending

  • 还没分配到节点
  • 或资源不足
  • 或依赖没准备好

2. ContainerCreating

  • 正在拉镜像 / 创建容器

3. ImagePullBackOff

  • 镜像拉不到(网络、仓库、权限、tag 错)
  • 你装 Calico 时遇到的就是这个

4. CrashLoopBackOff

  • 容器启动后立刻崩溃
  • K8s 反复重启
  • 常见:配置错、端口被占、启动命令错

5. Running

  • 正常运行

6. Completed

  • 一次性任务执行完退出(Job)

六、静态 Pod vs 普通 Pod(你 Master 上全是静态 Pod)

1. 静态 Pod(Static Pod)

  • kubelet 直接管理
  • 配置文件放在:

    plaintext

    /etc/kubernetes/manifests/
    
  • 不受控制器管理
  • 你 Master 上的核心组件全是:
    • kube-apiserver
    • etcd
    • kube-controller-manager
    • kube-scheduler

2. 普通 Pod

  • 由 Deployment、DaemonSet、StatefulSet 管理
  • 比如 Nginx、Calico、业务应用

七、最常用的 Pod 操作命令(你马上能用)

bash

运行

# 查看所有 Pod
kubectl get pods

# 查看指定命名空间(Calico、apiserver 都在这里)
kubectl get pods -n kube-system

# 看详细信息(排查错误神器)
kubectl describe pod <pod名> -n kube-system

# 看容器日志
kubectl logs <pod名> -n kube-system

# 实时日志
kubectl logs -f <pod名> -n kube-system

# 进入 Pod 内部
kubectl exec -it <pod名> -- /bin/bash

# 删除 Pod(控制器会自动重建)
kubectl delete pod <pod名>

八、Pod 的重要特点(生产 / 面试都考)

  1. Pod 是临时的:删了就没了,IP 会变
  2. 不能直接用裸 Pod:必须用 Deployment/DaemonSet 管理
  3. 不能跨节点扩容:一个 Pod 只在一台节点上
  4. 自愈靠控制器:Pod 自己不会自愈,是 Deployment 帮它重启
  5. 网络必须靠 CNI:没装 Calico/Flannel,Pod 没有 IP,节点永远 NotReady

九、给你总结成一句最关键的话

Pod = K8s 最小运行单位,里面一定有一个 pause 沙箱容器 + 业务容器,共享网络和存储,所有调度、自愈、网络、存储都围绕 Pod 展开。

你之前部署 K8s 遇到的几乎所有问题:

  • pause 镜像拉取失败
  • Calico 启动不了
  • apiserver 起不来
  • 节点 NotReady
  • ImagePullBackOff

本质全是 Pod 启动失败。

第一步:先看 Pod 基础状态(10 秒定位异常类型)

先执行最基础的命令,快速判断 Pod 异常的 “大方向”,避免盲目排查:

# 查看目标命名空间的Pod(比如kube-system,你的Calico/apiserver都在这)
kubectl get pods -n kube-system -o wide

# 若想只看异常Pod,用grep过滤(排除Running/Completed)
kubectl get pods -n kube-system | grep -v -E "Running|Completed"

关键状态解读(对应你踩过的坑)

状态 核心原因(快速判断) 你遇到的场景
Pending Pod 未调度到节点(资源不足 / 调度规则冲突) Calico-kube-controllers Pending
Init:ImagePullBackOff 初始化容器拉取镜像失败 Calico-node 启动失败
ImagePullBackOff 业务容器拉取镜像失败 任何 Pod 都可能遇到(国内网络)
CrashLoopBackOff 容器启动后立刻崩溃(配置 / 命令 / 依赖错) apiserver/etcd 异常重启
ContainerCreating 容器正在创建(拉镜像 / 挂载存储) 刚部署 Pod 时的过渡状态
Unknown 节点失联(kubelet 挂了 / 节点宕机) 若节点 NotReady 可能出现

示例:你之前的calico-node-79nm9 0/1 Init:ImagePullBackOff,一眼就能判断是 “初始化容器拉镜像失败”,不用再查其他。


第二步:查 Pod 详细描述(找核心错误信息,最关键)

kubectl describe是排查 Pod 异常的 “神器”,能看到 Pod 从创建到现在的所有事件、资源配置、容器状态,重点看Events部分(K8s 会记录 Pod 的每一步操作和错误)。

# 查异常Pod的详细信息(替换<Pod名>为实际名称,比如calico-node-79nm9)
kubectl describe pod <Pod名> -n kube-system

重点看这 3 个部分(按优先级)

1. 最关键:Events(事件日志)

K8s 会把 Pod 的 “调度、拉镜像、启动容器” 等所有操作记录在这里,错误信息直接显示:

# 你之前遇到的ImagePullBackOff,Events里会显示:
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  10m               default-scheduler  Successfully assigned kube-system/calico-node-79nm9 to k8s-master
  Warning  Failed     8m (x4 over 9m)   kubelet            Failed to pull image "calico/node:v3.25.1": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/calico/node:v3.25.1": failed to resolve reference "docker.io/calico/node:v3.25.1": failed to do request: Head "https://registry-1.docker.io/v2/calico/node/manifests/v3.25.1": dial tcp 140.82.112.20:443: connect: connection refused
  Warning  Failed     8m (x4 over 9m)   kubelet            Error: ErrImagePull
  Normal   BackOff    8m (x6 over 9m)   kubelet            Back-off pulling image "calico/node:v3.25.1"
  Warning  Failed     7m (x7 over 9m)   kubelet            Error: ImagePullBackOff

一眼就能看出:拉取 docker.io 的 calico 镜像失败,原因是国内网络连不上

2. 次关键:Init Containers(初始化容器状态)

如果是Init:开头的异常,看这里的StateLast State,会显示初始化容器的失败原因:

Init Containers:
  install-cni:
    Container ID:  
    Image:         calico/cni:v3.25.1
    Image ID:      
    State:         Waiting
      Reason:      ImagePullBackOff
    Last State:    Terminated
      Reason:      Error
      Exit Code:   1
3. 补充:Containers(业务容器状态)

看业务容器的Image(镜像地址是否正确)、Command(启动命令是否错)、Resources(资源限制是否不够)。


第三步:查容器日志(定位运行时错误)

如果 Pod 已经创建了容器(哪怕崩溃了),查日志能看到容器启动 / 运行时的具体错误,比如 apiserver 连不上 etcd、配置文件错误等。

1. 查普通运行中 / 崩溃容器的日志

# 查业务容器日志(替换<Pod名>,比如kube-apiserver-k8s-master)
kubectl logs <Pod名> -n kube-system

# 实时跟踪日志(排查动态错误,比如apiserver超时)
kubectl logs -f <Pod名> -n kube-system

# 若Pod里有多个容器,指定容器名(比如calico-node里的calico-node容器)
kubectl logs <Pod名> -n kube-system -c <容器名>

# 查崩溃容器的上一次日志(关键!容器重启后,用--previous看上次错误)
kubectl logs <Pod名> -n kube-system --previous

2. 查 Init 容器(初始化容器)的日志

# 查Init容器日志(指定-init容器名,比如install-cni)
kubectl logs <Pod名> -n kube-system -c <Init容器名>

示例:你之前 apiserver 超时,查日志会看到:

E0210 18:03:56.831778   46508 kubelet_node_status.go:92] "Unable to register node with API server" err="Post \"https://192.168.200.10:6443/api/v1/nodes\": dial tcp 192.168.200.10:6443: connect: connection refused" node="k8s-master"

直接定位:apiserver 还没就绪,kubelet 注册节点失败。


第四步:针对性解决常见 Pod 异常(对应你的坑)

根据前 3 步的排查结果,对应解决最常见的 5 类异常:

场景 1:ImagePullBackOff(你最常遇到)

  • 根因:镜像源不可达(国外仓库)、镜像 tag 错误、镜像仓库权限问题
  • 解决方法
    1. 换国内镜像源(腾讯云 / 阿里云):比如把calico/node:v3.25.1换成mirror.ccs.tencentyun.com/calico/node:v3.25.1
    2. 手动拉取镜像并打 tag(兜底):
      sudo ctr -n k8s.io images pull mirror.ccs.tencentyun.com/calico/node:v3.25.1
      sudo ctr -n k8s.io images tag mirror.ccs.tencentyun.com/calico/node:v3.25.1 calico/node:v3.25.1
      
    3. 检查镜像 tag 是否正确(比如 v3.25.1 写成 3.25)。

场景 2:CrashLoopBackOff

  • 根因:启动命令错误、配置文件错误、端口被占用、资源不足
  • 解决方法
    1. kubectl logs <Pod名> --previous看崩溃原因;
    2. 检查 Pod 的启动命令(Command/Args)是否正确;
    3. 调整资源限制(比如给 apiserver 加内存):
      resources:
        requests:
          cpu: 100m
          memory: 256Mi
        limits:
          cpu: 1000m
          memory: 1Gi
      

场景 3:Pending

  • 根因:节点资源不足(CPU / 内存不够)、调度规则冲突、节点污点(NoSchedule)
  • 解决方法
    1. kubectl describe pod <Pod名>的 Events,看是否有 “Insufficient cpu/memory”;
    2. 查看节点资源:kubectl top node
    3. 移除节点污点(如果是 Master 节点被标记为不可调度):
      kubectl taint nodes k8s-master node-role.kubernetes.io/control-plane:NoSchedule-
      

场景 4:Init:Error(初始化容器失败)

  • 根因:初始化容器执行命令失败、依赖服务未就绪(比如等 etcd 启动)
  • 解决方法
    1. 查 Init 容器日志:kubectl logs <Pod名> -c <Init容器名>
    2. 等待依赖服务就绪(比如等 apiserver/etcd 启动);
    3. 重新执行初始化容器:删除 Pod 让控制器重建(kubectl delete pod <Pod名> -n kube-system)。

场景 5:Pod 运行正常但节点 NotReady

  • 根因:CNI 网络插件未就绪(Calico/Flannel Pod 异常)、kube-proxy 未运行
  • 解决方法
    1. 查 Calico Pod 状态:kubectl get pods -n kube-system | grep calico
    2. 确保 Calico Pod 全部 Running;
    3. 检查节点网络:ip a看是否有 calico 相关网卡(calixxx)。

兜底排查(以上都没用时)

如果按上面步骤还没解决,查集群底层组件:

# 1. 检查节点状态
kubectl get nodes

# 2. 检查kubelet状态(Pod的“管理者”)
sudo systemctl status kubelet

# 3. 检查containerd状态(容器运行时)
sudo systemctl status containerd

# 4. 查看kubelet实时日志(找底层错误)
sudo journalctl -u kubelet -f --no-pager
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐