删掉一个 Pod 后,谁把它补回来?

前言: 上一篇把容器、Pod 和 Node 的关系捋了一遍,我随手想到一个更贴近日常维护的问题:图片预览接口已经跑在 Pod 里,如果这个 Pod 没了,接口该怎么办?正常情况是补出一个同样的实例,我第一反应却是"容器不是会自动重启吗"。翻了 Kubernetes 官方关于 Pod 的说明才发现,我把"同一个 Pod 里的容器重启"和"整个 Pod 被替换"混成了一件事。于是我想弄明白:

text 复制代码
1. 没有管理对象时,我们怎么保证 Pod 还在?
2. 用了 Deployment 以后,为什么还不能直接把它当成服务已经可用了?

这篇只围绕"少了一个 Pod 怎么补"来聊,先不展开滚动更新和调度策略。下面的图片预览接口是示意场景;示例清单核对了官方文档,但我没有连接集群执行它。

一. 一个 Pod 消失后,事情不一定像我想的那样

  1. 假设我们有个图片预览接口,每次上传图片后,页面会请求它生成一张缩略图。前一篇说过,应用容器可以放在 Pod 里运行。开发时手动创建一个 Pod,接口能响应,看起来已经完成部署了。

  2. 现在想象这台机器要维护,或者有人把那个 Pod 删掉了。我最初以为"自动重启"会把它救回来。可容器重启处理的是 Pod 内部的容器进程;Pod 本身被删掉时,单独创建的 Pod 没有一个上层对象负责按原样重建。官方也建议,长期运行的工作负载通常通过控制器创建和管理 Pod。

  3. 这就像店里只有一位值班员:人临时离开座位,可以叫他回来;岗位本身从排班表里被删掉,就没人知道还需要补一个人。这里的"排班表",后面正是我们要找的东西。

图里重点看右侧:容器重启的边界在 Pod 内,不能替代"重建一个 Pod"的职责。

二. 我先试着把"补人"这件事交给自己

  1. 最粗暴的办法是发现接口不通,就手动再执行一次创建命令。它能救急,但值班的人得一直盯着;夜里出问题时,手工补救的速度也不可控。

  2. 稍微好一点,可以写个脚本定期检查 Pod 数量,不足就重建。我也会这么想,但脚本很快就得处理重复创建、并发执行、模板变更以及"旧 Pod 正在退出"这类细节。它开始像一个简化版控制器了,维护成本却落在自己身上。

做法 谁判断少了一个 少了以后怎么办
手动创建 Pod 值班的人 再敲一次创建命令
自写巡检脚本 定时脚本 自己处理计数、重复与重试
声明工作负载 集群控制器 按声明的模板和数量调整
  1. 对图片预览这种要持续提供服务的应用,我们真正想表达的不是"现在创建一个",而是"以后应该一直有一个"。这句话听起来只改了几个字,责任却从一次性操作变成了持续维护。

图里蓝色路径需要人反复介入;绿色路径保留一份持续生效的目标。

三. Deployment 写下的是"以后都要这样"

  1. 到这里再引入 Deployment 就顺了。官方 Deployment 文档把它描述为声明式更新 Pod 和 ReplicaSet 的工作负载对象。我们给它一份 Pod 模板和想要的数量,它负责让实际情况朝这个目标靠近。

  2. 先只要一份图片预览服务。下面清单的 replicas: 1 是期望数量;template 是以后补新 Pod 时使用的模板。selector.matchLabels 与模板里的 labels 必须对得上。镜像名只是示例,实际使用时要换成你能拉取且会启动服务的镜像。

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: preview-api
spec:
  replicas: 1 # !!! 注意:希望持续保留一份 Pod
  selector:
    matchLabels:
      app: preview-api
  template:
    metadata:
      labels:
        app: preview-api
    spec:
      containers:
        - name: preview-api
          image: registry.example.com/preview-api:v1 # 换成可拉取的实际镜像
  1. 如果它管理的 Pod 消失,Deployment 不是亲自去运行容器。它管理 ReplicaSet ,后者按模板维护指定数量的 Pod 。为了先建立认知,可以记成一条关系:Deployment → ReplicaSet → Pod → 容器。具体控制循环暂时不用背。

图里重点看箭头的管理关系:声明写在 Deployment ,实际运行的仍是 Pod 里的容器。

四. 排班表有了,还得看人有没有到岗

  1. 继续沿用排班的比方:Deployment 像"这个岗位长期需要一人"的排班要求,ReplicaSet 像照着排班表补人的执行环节,Pod 是到岗的那个人。人换了,岗位要求还在;所以新 Pod 可能有新名字,它不是原来那一个复活了。

  2. 如果手边有可用集群,可以把上面的清单保存为 preview.yaml,换好真实镜像后观察这三层对象。命令来自官方的 kubectl apply 用法;下面只给出观察路径,不把输出写成实测结果。

bash 复制代码
kubectl apply -f preview.yaml
kubectl get deployment preview-api
kubectl get replicaset -l app=preview-api
kubectl get pods -l app=preview-api
  1. 看 kubectl get deployment 时,先比较期望数量和就绪数量。假如期望是 1,实际还没准备好,不要急着断言控制器失效:它可能还在拉镜像、等待调度,或者应用本身启动失败。这时再看 Pod 的状态和事件,才知道卡在"没创建""没跑起来"还是"没准备好"。

图里重点看三个检查点,别把"目标写了 1"直接读成"接口已能服务"。

五. 用了 Deployment,也不能把它当成万能保活

  1. Deployment 能维护工作负载的目标数量,但不保证每次调整都立刻成功。如果镜像拉不到、节点资源不足,新的 Pod 可能迟迟不能运行;如果程序启动后还没准备好接请求,"有一个 Pod"也不等于接口已经可用。

  2. 还有一个常见误会:把 replicas: 1 改成 2,只说明希望有两份 Pod ,并不自动解决客户端该访问谁的问题。稳定入口需要后面要讲的 Service 。这也是为什么我不想把 Deployment 解释成"部署完就什么都好了"。

  3. 真排查时,先分清是哪一层出了问题:Deployment 有没有声明正确的目标;ReplicaSet 是否在创建 Pod ;Pod 是否运行并就绪;应用是否真的能处理请求。这样问比看到接口不通就重启所有东西更有方向。

图里橙色的两道关口提醒我们:补出对象只是第一步,还需要检查运行和访问。

六. 总结:下次少一个 Pod,先找谁在管它

  1. 回到开头的图片预览接口。如果只是手动创建一个 Pod ,它消失后不能指望"容器自动重启"把整个 Pod 带回来。长期运行的服务需要把期望写给上层工作负载对象;常见的无状态服务可以从 Deployment 开始。
text 复制代码
先看 Pod 有没有上层管理者
再看 Deployment 的目标数量与就绪数量
接着沿 ReplicaSet、Pod 查到具体卡点
最后单独确认应用和访问入口是否可用
  1. 这篇先记住 Deployment → ReplicaSet → Pod 这条管理链就够了。下次再看到"明明写了两份,为什么请求还是打不到服务",就知道要把"维持实例"和"给请求一个稳定入口"拆开;下一篇我们正好从 Service 继续。

图里从左到右是一条排查路线:先确认谁负责补,再确认补出来的实例能否真正服务。

相关推荐
Gopher_HBo1 小时前
grpc客户端调用链
后端
时间海8711 小时前
对象键清洗之前,先拦住重名
javascript·后端
歌谣1 小时前
07|【30岁前端转型全栈】前后端遇到报错怎么处理?当然是console.log和System.out.println?
后端
对象存储与RustFS1 小时前
HelixDB 上手:Agent 记忆新方案,基于 RustFS 对象存储,附完整 docker-compose 部署示例
后端·rust·开源
深入云栈1 小时前
Netty 4.2.x 源码深度解析 (十八):ChannelOutboundBuffer 写缓冲区 —— 发送队列与流量控制
java·后端·架构
谢亮_vipxieliang1 小时前
Go gRPC基础与实战
开发语言·后端·golang
god_cvz1 小时前
第二章:5、RAG进阶优化
后端·ai编程
今年下半年1 小时前
【低成本埋点统计】Spring Boot+vue2前后端分离项目统计系统访问、使用、登录次数
spring boot·后端·状态模式
codigger1 小时前
Java 26 深度解析:一次“性能兑现 + 契约收紧”的版本
java·后端·编程·编程语言