当前位置:首页 > 技术 > 正文内容

Pod 详解:从生命周期到高级调度全解析

访客 技术 2026年6月11日 1

Pod 详解

一、Pod 生命周期:状态与阶段全解析

1.1 核心生命周期阶段

Pod 从创建到终止的完整流程涵盖多个关键阶段:

  1. 创建阶段:用户提交请求 → API Server 验证存储 → Scheduler 调度节点 → Kubelet 启动容器;
  2. 初始化阶段:运行初始化容器(Init Containers),为主容器准备依赖环境;
  3. 运行阶段:主容器启动,执行生命周期钩子(PostStart/PreStop)与健康探测(Liveness/Readiness Probe);
  4. 终止阶段:标记为 Terminating,执行 PreStop 钩子,优雅关闭或强制终止容器。

二、初始化容器(Init Containers):主容器的前置关卡

初始化容器是主容器启动前的"前置任务执行者",需按顺序执行且全部成功后,主容器才会启动。

2.1 核心特性

  • 必须按定义顺序执行,前一个失败则重启,直至成功;
  • 可为主容器预处理依赖(如等待数据库、生成配置文件)。

2.2 配置示例:等待 MySQL 和 Redis 就绪

# pod-initcontainer.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-initcontainer
  namespace: dev
spec:
  # 主容器:Nginx 服务
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80

  # 初始化容器:按顺序执行
  initContainers:
  # 第一个初始化容器:等待 MySQL 服务可达
  - name: test-mysql
    image: busybox:1.30
    command: ['sh', '-c', 'until ping 192.168.100.110 -c 1; do echo waiting for mysql...; sleep 2; done;']
  
  # 第二个初始化容器:等待 Redis 服务可达
  - name: test-redis
    image: busybox:1.30
    command: ['sh', '-c', 'until ping 192.168.100.120 -c 1; do echo waiting for redis...; sleep 2; done;']

执行效果

# 查看 Pod 状态(初始化阶段会显示 Init:0/2,完成后变为 Running)
kubectl get pod pod-initcontainer -n dev

三、生命周期钩子(Lifecycle Hooks):事件驱动的自定义逻辑

钩子函数允许在容器生命周期的关键节点执行自定义命令,支持 postStart(启动后)和 preStop(终止前)。

3.1 钩子类型与实现方式

钩子类型 触发时机 支持方式
postStart 容器创建后立即执行 Exec 命令、TCPSocket、HTTPGet
preStop 容器终止前同步执行 同上

3.2 配置示例:修改 Nginx 首页与优雅关闭

# pod-hook-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-hook-exec
  namespace: dev
spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    lifecycle:
      # 启动后钩子:修改 Nginx 首页内容
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo luoqi > /usr/share/nginx/html/index.html"]
      
      # 终止前钩子:优雅关闭 Nginx
      preStop:
        exec:
          command: ["/usr/sbin/nginx", "-s", "quit"]

验证效果

# 访问 Pod IP,确认首页内容
kubectl get pod pod-hook-exec -n dev -o wide  # 获取 Pod IP
curl <Pod IP>  # 输出:luoqi

四、容器探测:保障服务可用性的健康检查

容器探测通过探针(Probe)检测应用状态,支持 存活性探针(Liveness)就绪性探针(Readiness)

4.1 探针类型与作用

  • 存活性探针:检测容器是否正常运行,失败则重启容器;
  • 就绪性探针:检测容器是否可接收请求,失败则从 Service 移除。

4.2 三种探测方式配置示例

1. Exec 命令探测(检查文件是否存在)
# pod-liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-exec
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    livenessProbe:
      exec:
        command: ["/bin/cat", "/tmp/hello.txt"]  # 检查文件是否存在
      initialDelaySeconds: 5  # 启动后 5 秒首次探测
      periodSeconds: 10       # 每 10 秒探测一次

效果:若 /tmp/hello.txt 不存在,容器会反复重启(RESTARTS 递增)。

2. TCPSocket 探测(检查端口是否可连接)
# pod-liveness-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-tcpsocket
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    livenessProbe:
      tcpSocket:
        port: 8080  # 探测 8080 端口(Nginx 默认不监听,会失败)
      initialDelaySeconds: 3
      periodSeconds: 5

效果:8080 端口不可达,容器会反复重启。

3. HTTPGet 探测(检查 HTTP 接口状态)
# pod-liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-httpget
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    livenessProbe:
      httpGet:
        path: /test1    # 检查 /test1 路径
        port: 80        # 端口
        scheme: HTTP    # 协议
      initialDelaySeconds: 3
      periodSeconds: 5

效果:若 /test1 页面不存在(404),容器会反复重启。

五、重启策略:容器故障的自愈规则

重启策略定义容器故障时的处理逻辑,适用于 Pod 内所有容器。

5.1 三种策略对比

策略 触发条件 示例场景
Always 容器终止(无论成功/失败) 长期运行的 Web 服务
OnFailure 容器异常终止(退出码非 0) 批处理任务(失败后重试)
Never 永不重启 一次性任务(如日志收集)

5.2 配置示例:禁止重启(Never)

# pod-restartpolicy.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-restartpolicy
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    livenessProbe:
      httpGet:
        path: /test1  # 不存在的路径,探测会失败
        port: 80
  restartPolicy: Never  # 禁止重启

效果:容器探测失败后状态变为 FailedRESTARTS 始终为 0。

六、Pod 调度:控制 Pod 运行节点

Kubernetes 提供多种调度方式,从强制绑定到灵活亲和性,满足不同场景需求。

6.1 定向调度:强制绑定节点

1. NodeName(直接指定节点名称)
# pod-nodename.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node3  # 强制调度到 node3(若 node3 不存在,Pod 会失败)

2. NodeSelector(通过标签匹配节点)
# pod-nodeselector.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeSelector:
    env: dev  # 调度到标签为 env=dev 的节点

前提:需先为节点添加标签:

kubectl label nodes node1 env=dev  # 为 node1 添加 env=dev 标签

6.2 亲和性调度:灵活选择节点

1. NodeAffinity(节点亲和性)
# pod-nodeaffinity-required.yaml(硬限制)
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    nodeAffinity:
      # 硬限制:必须满足条件
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: app
            operator: In
            values: ["1", "2", "3"]  # 节点标签 app 必须为 1/2/3

2. PodAffinity(Pod 亲和性)
# 参照 Pod(已运行在 node1)
# pod-podaffinity-target.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-target
  namespace: dev
  labels:
    podenv: pro
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  nodeName: node1
---
# 新 Pod:与参照 Pod 同节点
# pod-podaffinity-required.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-podaffinity-required
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: podenv
            operator: In
            values: ["pro"]  # 与标签 podenv=pro 的 Pod 同节点
        topologyKey: kubernetes.io/hostname  # 按节点划分拓扑域

6.3 污点与容忍:节点的"黑白名单"

1. 为节点添加污点(拒绝 Pod 调度)
# 为 node1 添加污点:key=disk, value=ssd, effect=NoSchedule(禁止无容忍的 Pod 调度)
kubectl taint nodes node1 disk=ssd:NoSchedule

# 移除污点
kubectl taint nodes node1 disk:NoSchedule-

2. Pod 配置容忍(忽略节点污点)
# pod-toleration.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-toleration
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  tolerations:
  - key: "disk"          # 匹配污点的 key
    operator: "Equal"    # 匹配方式(Equal/Exists)
    value: "ssd"         # 匹配污点的 value
    effect: "NoSchedule" # 匹配污点的 effect

七、总结

Pod 是 Kubernetes 最小部署单元,其生命周期管理(初始化容器、钩子函数、健康探测)和调度策略(定向调度、亲和性、污点容忍)是保障服务稳定性的核心。通过合理配置,可实现服务的自愈、依赖管理和资源优化,为生产环境的微服务部署提供坚实基础。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。