CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Kubernetes 入门/课时/Pod
RawBlame
课时目录12 节

Kubernetes 入门

  1. 01Kubernetes 是什么
  2. 02核心概念与架构
  3. 03本地集群与 kubectl
  4. 04Pod
  5. 05Deployment 与滚动更新
  6. 06Service 与网络
  7. 07ConfigMap 与 Secret
  8. 08存储卷
  9. 09Ingress 入口
  10. 10资源配额与 HPA
  11. 11RBAC 与安全基础
  12. 12综合练习:部署 backend

Pod

最小调度单元、多容器 Pod、探针入门。

30 分钟

Pod

这一课你将能做到

  1. 手写一份合法的 Pod YAML 并 apply,用 get/describe/logs 观察它的完整生命周期
  2. 说清「K8s 调度的是 Pod 而非容器」的原因,并演示多容器 Pod 共享 localhost
  3. 正确配置 liveness/readiness 探针,亲手制造一次「探针失败 → 容器重启」与「未就绪 → 不接流量」

为什么要学

Pod 是集群里最小调度单元:一组共享网络与存储的容器。生产中你几乎不会手搓裸 Pod,但 Deployment 的 template 字段本质上就是一份 Pod 模板——Pod 不懂,后面每一课都是空中楼阁。

面试必考「Pod 生命周期」「三种探针的区别」。对本站:Spring Boot backend 打进镜像后,靠什么告诉 K8s「我启动好了」「我挂了」?答案就是 Actuator 的 /actuator/health + K8s 探针,这是 backend 能被滚动发布、被自动摘流的前提。

先建立图像

Pod(逻辑主机)
 ├─ 共享 network namespace → 容器间 127.0.0.1 互访、共享端口空间
 ├─ 可共享存储卷(volume)
 └─ 一起调度、一起生死(通常)

对照 Docker 心智:
 docker run 一个容器     ≈ 单容器 Pod
 Compose 里多个服务      ≈ 多个 Pod(再靠 Service 串起来)
 一个 Pod 塞前后端 + DB  ✗ 错误模型——该拆成三个 Pod

生命周期相位(面试要背):

阶段含义常见原因
Pending已创建未运行调度不下去 / 拉镜像中
Running主进程运行中正常运行 / 即将崩溃
Succeeded全部容器成功退出Job 跑完
Failed容器失败退出应用崩溃
Unknown状态失联节点失联

跟着做

步骤 1:写最小 Pod 并 apply

pod-hello.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: hello
  labels:
    app: hello
spec:
  containers:
    - name: web
      image: nginx:1.27-alpine
      ports:
        - containerPort: 80
kubectl apply -f pod-hello.yaml
kubectl get pod hello -o wide
kubectl describe pod hello

注意:containerPort 只是信息性声明,不是 Docker 的 -p,不会把端口映射到宿主机。

步骤 2:观察生命周期与事件

kubectl get pods -w     # 另开终端盯着状态变化

状态迁移:Pending(拉镜像/调度)→ ContainerCreating → Running。describe 的 Events 段记录每一步的时间戳——这就是以后排错的主战场。

步骤 3:验证裸 Pod「删了就没了」

kubectl delete pod hello
kubectl get pods

删掉后不会重生——没有任何控制器管它。这就是「生产用 Deployment 管副本」的第一层理由(第二层是滚动更新,下一课)。

步骤 4:liveness 探针实验(制造一次自愈)

pod-probe.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: probe-demo
  labels:
    app: probe
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["/bin/sh", "-c", "touch /tmp/healthy; while true; do sleep 30; done"]
      livenessProbe:
        exec:
          command: ["sh", "-c", "test -f /tmp/healthy"]
        initialDelaySeconds: 5
        periodSeconds: 5
kubectl apply -f pod-probe.yaml
kubectl get pods -w

Ready 之后删掉健康标记文件,模拟进程「僵死」:

kubectl exec probe-demo -- rm /tmp/healthy

约 10-15 秒内观察:探针失败 → 容器被重启 → RESTARTS 列 +1,且新容器里文件重新生成(启动命令会重建它)。这就是 K8s 的「进程级自愈」。

步骤 5:readiness 探针实验(制造一次摘流)

pod-ready.yaml(给 nginx 打一个不存在的路径):

apiVersion: v1
kind: Pod
metadata:
  name: ready-demo
spec:
  containers:
    - name: web
      image: nginx:1.27-alpine
      readinessProbe:
        httpGet:
          path: /not-exist
          port: 80
        periodSeconds: 5
kubectl apply -f pod-ready.yaml
kubectl get pods

看到 READY 0/1 且 STATUS 仍是 Running——进程活着,但不接客。若它属于某个 Service,此刻 Endpoints 里不会有它。把 path 改成 / 再 apply,READY 变 1/1。

这解释了本站 backend 探针为何指向 /actuator/health:Spring 还在初始化(连 MySQL/Redis)时,readiness 失败能挡住流量,避免用户打到「半死」实例。

步骤 6:多容器 Pod 验证共享 localhost

pod-two.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: two
spec:
  containers:
    - name: web
      image: nginx:1.27-alpine
    - name: sidecar
      image: busybox:1.36
      command: ["/bin/sh", "-c", "sleep 3600"]
kubectl apply -f pod-two.yaml
kubectl exec -it two -c sidecar -- wget -qO- 127.0.0.1:80 | head -3

sidecar 容器里通过 127.0.0.1 访问到了 nginx——同一 Pod 的容器共享网络命名空间。收尾清理:

kubectl delete pod probe-demo ready-demo two

讲清楚要点

  1. 调度单位是 Pod:同 Pod 容器天然同网络、可共享卷、同调度同生死。sidecar(日志收集、服务网格代理)都建立在这个模型上。
  2. 裸 Pod 没有自愈与发布能力:删了不重建、改镜像要删了重跑。一切常驻工作负载都应交给 Deployment / StatefulSet / Job 管理。
  3. restartPolicy 作用于 Pod 内容器:默认 Always(容器退出就重启);Job 场景用 OnFailure / Never。注意它是「重启容器」,不是「重建 Pod」。
  4. 三种探针分工:liveness 失败 → 重启容器(治僵死);readiness 失败 → 摘出 Service 流量(保护发布与未就绪实例);startup 失败 → 先别启动前两者(给慢启动应用如 JVM 缓冲)。
  5. 探针过严是事故源:initialDelaySeconds 不足会把「正在启动」误判为「已僵死」,制造重启风暴。本站 Spring Boot 启动慢,务必给足延迟或用 startupProbe。
  6. 镜像问题都会显形在 Pod 事件里:imagePullSecrets 缺失、架构不匹配(arm/amd64)、仓库网络不通,报错全在 describe 的 Events 里。

你可能会懵的地方

  • 一个 Pod 里跑多个容器 = 多副本吗? 完全不是。多副本 = 多个 Pod(水平扩);同 Pod 多容器 = 强耦合的「主程序 + 帮手」。把前后端塞一个 Pod 是经典错误——它们要独立扩缩与发布。

  • Pod 的 IP 是什么?能直接用吗? 是集群虚拟网络里的地址,Pod 之间可直接互通。但它随重建而变,任何配置里都不要写死 Pod IP,一律用 Service 名。

  • CrashLoopBackOff 怎么定位? 退避重启循环。kubectl logs <pod> --previous 看崩溃现场;常见原因:启动命令错、环境变量缺、连不上 MySQL/Redis、liveness 探针太严。

  • K8s 有没有类似 Compose depends_on 的启动顺序保证? 没有。K8s 的哲学是「不保证顺序,但保证最终可用」:依赖没好时 readiness 失败自动摘流,应用自己重试连接。你的 Spring Boot 应容忍依赖晚到(连接池重试),而不是启动即退出。

  • Pod 和容器的区别,一句话版? 容器是进程隔离技术,Pod 是「一组共生容器的调度与网络封装」——K8s 世界里的「逻辑主机」,容器只是里面跑的进程。

错法对照

错法问题正解
生产环境手建大量裸 Pod无自愈、无发布策略一律交给 Deployment 托管
只配 liveness 不配 readiness启动期流量打到未就绪实例两探针分工配置
探针路径写错(打 404)被重启/摘流,看起来像故障先 curl 通再写进 YAML
一个 Pod 塞 frontend+backend+DB无法独立扩缩,一损俱损按服务拆 Pod
不设 initialDelaySeconds慢启动应用被误杀重启给足延迟或用 startupProbe

卡点急救

  1. ImagePullBackOff:describe 看 Events——镜像名拼写、tag 是否存在、私有仓库凭证(imagePullSecrets)。本地镜像先 minikube image load。
  2. CrashLoopBackOff:logs --previous 看崩溃输出;逐项排查 command/args、必需环境变量、依赖可达性、探针配置。
  3. Pod 一直 Pending:describe 的 Events 会点名原因——Insufficient cpu/memory(资源不够,第 10 课讲 requests)、节点污点、PVC 未绑定,对号入座。

面试常问

  • 讲讲 Pod 的生命周期。 创建后先 Pending(调度 + 拉镜像),容器全部启动进入 Running,readiness 通过进入 Ready 才接流量;正常退出到 Succeeded、失败到 Failed(Job 类)、失联为 Unknown。生命周期内的关键机制:initContainers 串行跑完才起主容器;探针(liveness 失败重启容器、readiness 失败摘流量);优雅终止(SIGTERM + terminationGracePeriodSeconds,默认 30 秒)。

  • liveness、readiness、startup 探针的区别? liveness:失败重启容器,处理进程僵死;readiness:失败把 Pod 从 Service Endpoints 摘除(不重启),处理「活着但没能力服务」;startup:启动期独占探针,成功后 liveness/readiness 才接管,解决慢启动(大堆 JVM)被误杀的问题。生产标配:readiness 必配,liveness 阈值放宽谨慎配,慢应用加 startupProbe。

  • 为什么 Pod 内容器共享网络?有什么用? 同 Pod 共享一个 network namespace:同一个 IP 与端口空间,容器间 127.0.0.1 直接互访。用途:sidecar 模式——日志代理、网格 envoy、辅助进程与主容器零开销通信;也解释了为什么同 Pod 内端口不能冲突。

自测三问

  1. 删掉一个 Pod 后它又出现了——这说明什么?去哪找「真凶」?
  2. Pod 显示 Running 但 Service 访问不通,第一个查什么?
  3. 本站 backend 启动要 40 秒(要连 MySQL/Redis),探针应该怎么配?

小结一句话

Pod 是共享网络与存储的最小调度单元,生命周期由相位与探针共同刻画:liveness 管死活、readiness 管接客——下一课把 Pod 交给 Deployment,获得副本自愈与滚动发布能力。

延伸

  • Pods
  • Configure Liveness, Readiness and Startup Probes
  • 下一课预告:Deployment——声明副本数、验证自愈、完成一次滚动更新并回滚。
加载本节练习…
← 上一课本地集群与 kubectl下一课 →Deployment 与滚动更新