【云原生技术】node pod 容器 镜像的关系
# K8s 中 Node、Pod、容器、镜像的关系## 一图看懂(层级与共享)```Cluster└─ Node(物理机/虚机)├─ kubelet + 容器运行时(containerd / CRI-O)└─ Pod(调度最小单位,可有多个)├─ [基础设施容器 pause:承载 Pod 的网络/IPC 命名空间]├─ 共享网络栈(同一 Pod 内容器共享同一 IP、localhost)├─ 共享
·
K8s 中 Node、Pod、容器、镜像的关系
一图看懂(层级与共享)
Cluster
└─ Node(物理机/虚机)
├─ kubelet + 容器运行时(containerd / CRI-O)
└─ Pod(调度最小单位,可有多个)
├─ [基础设施容器 pause:承载 Pod 的网络/IPC 命名空间]
├─ 共享网络栈(同一 Pod 内容器共享同一 IP、localhost)
├─ 共享 Volume(同一 Pod 内可挂载并共享)
└─ 容器(一个或多个)
└─ 来自“一个镜像”(registry/repo:tag 或 @sha256:digest)
- 直白总结
- Node 上运行很多 Pod
- 一个 Pod 内可以有多个 容器
- 每个 容器 只能来源于 一个镜像
- 一个 镜像 可以被很多容器复用(跨 Pod/Node)
核心对比表
概念 | 作用 | 关键属性 | 生命周期管理 | 资源/隔离 | 常用命令 |
---|---|---|---|---|---|
Node | 工作节点,承载 Pod | CPU/内存/磁盘/网络、标签/污点 | 集群与节点运维 | 节点级 cgroups/内核隔离 | kubectl get nodes -o wide |
Pod | 调度与网络最小单位 | IP、Volume、标签、注解 | K8s 控制面(调度器、kubelet) | Pod 内共享网络/IPC;与其他 Pod 隔离 | kubectl get/describe pod |
容器 (Container) | 运行进程的封装 | 镜像、命令、env、探针、资源限额 | kubelet 通过 CRI 调用运行时 | cgroup/namespace 级资源隔离 | kubectl logs/exec |
镜像 (Image) | 不可变运行时文件系统与元数据 | repo:tag 或 @digest、多层 | 仓库存储与节点缓存 | 只读层 + 容器可写层 | kubectl describe pod 中看镜像;节点用 crictl/nerdctl 查看缓存 |
基数与约束(Cardinality)
- (1) Node ↔ (N) Pods(一个节点可运行很多 Pod;一个 Pod 任何时刻只在一个节点上)
- (1) Pod ↔ (N) Containers(≥1 个业务容器,可含
initContainers
、临时容器) - (1) Container ↔ (1) Image(容器只能由一个镜像创建)
- (1) Image ↔ (0…N) Containers(同一镜像可被重复使用)
- (1) Pod ↔ (1) IP(Pod 内所有容器共享该 IP 和端口空间)
- Pod 内可挂载多个 Volume 并在容器间共享
调度与拉镜像流程(简化)
- 你提交 Pod/Deployment(API Server 接收)
- 调度器为 Pod 选定合适的 Node(看资源、亲和/污点等)
- 目标 Node 上的 kubelet
- 解析容器的
image
引用(registry/repo:tag
或@digest
) - 按顺序尝试
imagePullSecrets
进行认证并拉镜像(节点有缓存则复用) - 为 Pod 创建网络命名空间(由 pause/沙箱容器持有)
- 顺序运行
initContainers
→ 再启动业务容器 - 等待
readinessProbe
就绪,将 Pod 加入 Service Endpoints
- 解析容器的
- 期间失败则见
ErrImagePull/ImagePullBackOff/CrashLoopBackOff
等事件
镜像要点(命名、拉取、缓存)
- 名称结构:
[registry/][namespace/]name[:tag]
或name@sha256:<digest>
- 未写 registry 通常默认为
docker.io
(内部实际为index.docker.io/v1/
) - 用
@digest
可确保版本不可变,避免 tag 漂移
- 未写 registry 通常默认为
- 镜像是多层只读层的组合;容器运行时会叠加一个可写层
- 节点会缓存已拉取的镜像层;不同镜像若共享层可复用,加速拉取
- 多个
imagePullSecrets
可并存;kubelet会按顺序尝试,先成功先用,不存在“被覆盖”
常见误区澄清
- “一个容器能否用多个镜像?”——不能。一个容器只能来自一个镜像
- “Pod 就是容器吗?”——不等同。常见是 1 Pod 1 容器,但 Pod 可包含多个容器(如 sidecar)
- “容器端口与 Pod IP 的关系?”——Pod 只有一个 IP,容器共享端口空间;
containerPort
仅作元数据 - “Node IP 就是 Pod IP 吗?”——不是。Pod IP 来自 CNI 网段;Node IP 是节点网卡地址
- “拉镜像一定需要凭据吗?”——公共镜像可匿名拉取;私有仓库需
imagePullSecrets
典型示例
一个 Pod,两个业务容器 + 一个 init 容器
apiVersion: v1
kind: Pod
metadata:
name: app-with-sidecar
spec:
imagePullSecrets:
- name: reg-harbor
initContainers:
- name: init-db
image: busybox:1.36
command: ["sh", "-c", "until nc -zv db 5432; do sleep 1; done"]
containers:
- name: app
image: registry.local/team/app:v2
ports:
- containerPort: 8080
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
- name: sidecar-proxy
image: registry.local/mesh/proxy:1.0
args: ["--upstream=localhost:8080"]
volumes:
- name: shared
emptyDir: {}
- 两个业务容器共享 Pod 的 IP、
emptyDir
卷与环境 - 每个容器各自来自一个镜像;Pod 内并不存在“一个容器用多个镜像”的情况
观察与排查常用命令
- 查看层级与位置
kubectl get nodes -o wide
kubectl get pod -o wide
kubectl describe pod <name>
(看调度、镜像拉取事件、探针)
- 节点侧(需要登录节点)
crictl images
/crictl ps
(CRI 通用)- 或
nerdctl images
(containerd 友好)
- 网络与服务
kubectl get endpoints <svc>
kubectl exec <pod> -- netstat -tnlp
(检查端口)
何时用多容器(Sidecar)而不是合并到一个镜像
- 适合 Sidecar:代理/日志收集/文件同步/服务网格注入,和主进程解耦、独立演进
- 适合合并:强耦合的小工具仅在构建期生成产物(用 Docker 多阶段构建),保持运行时只有一个干净镜像
更多推荐
所有评论(0)