前言:为什么 Pod 是 K8s 的灵魂

在 Kubernetes 的世界里,Pod 是最小的部署单元,也是绝大多数运维和开发人员最先接触的核心概念。如果把 K8s 集群比作一个操作系统,那么 Pod 就是运行在其中的“进程”——但它又不仅仅是容器,而是一组共享网络、存储和命名空间的容器集合。

本文基于真实的生产级操作文档,结合官方最佳实践,系统梳理了 Pod 管理的命令式操作声明式 YAML 配置控制器管理以及生命周期探针等核心知识。无论你是刚入门 K8s 的新手,还是希望夯实基础的老手,这篇文章都会让你对 Pod 的理解更上一层楼。

一、资源管理与三种操作模式

Kubernetes 将一切抽象为资源——Pod、Service、Deployment、Namespace 等都是资源。管理这些资源有三种主流方式,各有适用场景:

方式 适用环境 优点 缺点
命令式对象管理 测试、调试 简单直接,快速验证 无法审计、难以版本控制
命令式对象配置 开发环境 可审计、可追溯 配置文件多时操作繁琐
声明式对象配置 生产环境 支持目录操作、声明期望状态 意外情况下调试较复杂

生产环境强烈推荐声明式配置(kubectl apply -f,它能让你像管理代码一样管理基础设施。

二、命令式对象管理:快速上手

2.1 Namespace 管理

Namespace 是 K8s 中实现多租户隔离的基础资源:

# 查看所有命名空间
kubectl get namespaces

# 创建命名空间
kubectl create namespace timinglee

# 删除命名空间(会一并删除其下的所有资源)
kubectl delete namespace timinglee

2.2 Pod 的增删查改

# 查看 Pod(-o wide 显示 IP 和节点信息)
kubectl get pods -o wide

# 创建 Pod(run 命令快速启动)
kubectl run lee --image nginx:latest

# 查看 Pod 详细状态(排错利器)
kubectl describe pod error

# 删除 Pod
kubectl delete pod error
kubectl delete pods --all   # 删除当前 namespace 下所有 Pod

排错提示:当 Pod 处于 ImagePullBackOff 或 ErrImagePull 状态时,describe 命令会直接告诉你镜像拉取失败的原因,这是最常用的排错第一步。

三、kubectl 八大实操命令

3.1 create — 创建资源

# 创建 Deployment(控制器)
kubectl create deployment webcluster --replicas 2 --image myapp:v1

# 查看控制器和 Pod
kubectl get deployments.apps
kubectl get pods

3.2 edit — 在线编辑配置

# 直接编辑运行中的 Deployment
kubectl edit deployments.apps webcluster
# 修改 replicas: 2 后保存即生效

3.3 patch — 补丁式更新

# 无需编辑完整文件,只改一个字段
kubectl patch deployment webcluster -p '{"spec":{"replicas":1}}'

3.4 expose — 暴露服务

# 将 Deployment 暴露为 Service(ClusterIP 类型)
kubectl expose deployment webcluster --port 80 --target-port 80

# 查看服务及端点
kubectl get svc
kubectl describe svc webcluster

# 通过 ClusterIP 访问
curl 10.97.61.108/hostname.html

3.5 logs — 查看日志

# 查看 Pod 日志
kubectl logs pod/webcluster-77c87d9946-gh9v7

3.6 attach & exec — 进入容器

# 交互式运行(类似 docker run -it)
kubectl run -it testpod --image busybox:latest

# 附加到运行中的容器
kubectl attach pod/testpod -it

# 在容器中执行命令(最常用)
kubectl exec -it pod/testpod -- /bin/bash

3.7 cp — 文件拷贝

# 从 Pod 拷贝到宿主机
kubectl cp testpod:/usr/share/nginx/html/index.html /mnt/test

# 从宿主机拷贝到 Pod
kubectl cp /mnt/index.html testpod:/usr/share/nginx/html/index.html

3.8 rollout — 版本管理

# 查看滚动更新状态
kubectl rollout status deployment webcluster

# 重启 Deployment(滚动重启)
kubectl rollout restart deployment webcluster

# 查看历史版本
kubectl rollout history deployment webcluster

3.9 scale — 扩缩容

# 扩容到 4 个副本
kubectl scale deployment webcluster --replicas 4

# 缩容到 1 个副本
kubectl scale deployment webcluster --replicas 1

3.10 label — 标签管理

# 查看 Pod 标签
kubectl get pods --show-labels

# 添加标签
kubectl label pod webcluster-xxx app=webcluster

# 删除标签(key 后面加 -)
kubectl label pod webcluster-xxx app-

标签是 K8s 中服务发现和控制器关联的核心机制,Service 通过 selector 匹配 Pod 标签,Deployment 通过标签管理自己的 Pod 集合。

四、利用控制器实现版本更新与回滚

4.1 创建带版本的 Deployment

# 生成 YAML 模板(dry-run 模式)
kubectl create deployment webcluster --image myapp:v1 --replicas 2 \
  --dry-run=client -o yaml > webcluster.yml

# 应用配置
kubectl apply -f webcluster.yml

# 暴露为 NodePort 类型服务(外部可访问)
kubectl expose deployment webcluster --port 80 --target-port 80 --type NodePort

# 访问测试
curl http://172.25.254.100:30713/hostname.html

4.2 更新镜像版本

# 更新镜像到 v2
kubectl set image deployment webcluster myapp=myapp:v2

# 为此次更新添加变更记录(便于审计)
kubectl annotate deployment webcluster \
  kubernetes.io/change-cause="升级到 myapp:v2" --overwrite

# 验证版本
curl http://172.25.254.100:30713
# 输出:Hello MyApp | Version: v2

4.3 版本回滚

# 查看历史版本
kubectl rollout history deployment webcluster

# 回滚到指定版本
kubectl rollout undo deployment webcluster --to-revision 1

# 验证回滚结果
curl http://172.25.254.100:30713
# 输出:Hello MyApp | Version: v1

核心机制:Deployment 每次变更都会生成一个新的 ReplicaSet,旧的 ReplicaSet 保留(默认保留 10 个历史版本),从而实现秒级回滚

五、YAML 声明式配置:生产级的正确姿势

5.1 多容器 Pod

同一个 Pod 中的容器共享网络和 IPC 命名空间,可以通过 localhost 互相访问:

apiVersion: v1
kind: Pod
metadata:
  name: testpod
spec:
  containers:
  - image: myapp:v1
    name: myapp1
  - image: busyboxplus:latest
    name: busybox
    command: ["/bin/sh", "-c", "sleep 10000"]
# 验证网络互通
kubectl exec -it pod/testpod -c busybox -- curl localhost
# 返回 myapp:v1 的页面内容

注意:多容器 Pod 要避免端口冲突,否则会报 Address already in use

5.2 端口暴露(hostPort)

spec:
  containers:
  - image: myapp:v1
    name: myapp
    ports:
    - name: http
      containerPort: 80
      hostPort: 80      # 绑定到宿主机端口
      protocol: TCP

配置后可直接通过 节点 IP 访问服务,适用于调试或特定网络场景。

5.3 环境变量注入

spec:
  containers:
  - image: mysql:8.0
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "lee"

5.4 节点选择(nodeSelector)

spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node2
  containers:
  - image: myapp:v1
    name: myapp

5.5 共享宿主机网络(hostNetwork)

spec:
  hostNetwork: true
  containers:
  - image: busybox
    name: busybox
    command: ["/bin/sh", "-c", "sleep 10000"]

启用后 Pod 直接使用宿主机网络栈,ifconfig 看到的将是宿主机的网卡信息。

六、Pod 服务质量(QoS)等级

QoS 等级决定了资源紧张时 Pod 被驱逐的优先级

QoS 等级 条件 驱逐优先级
Guaranteed limits = requests(CPU 和内存都设置且相等) 最低(最安全)
Burstable 设置了 requests 和 limits,但不完全相等 中等
BestEffort 未设置任何资源限制 最高(最先被驱逐)
# Guaranteed 示例
resources:
  limits:
    cpu: 500m
    memory: 100M
  requests:
    cpu: 500m
    memory: 100M

# Burstable 示例
resources:
  limits:
    cpu: 700m
    memory: 200M
  requests:
    cpu: 500m
    memory: 100M

生产建议:关键业务 Pod 务必配置 Guaranteed 级别的资源限制。

七、Pod 生命周期与探针

7.1 Init 容器

Init 容器在应用容器启动之前顺序执行,且必须全部成功完成:

spec:
  initContainers:
  - name: init-check
    image: busybox
    command: ["sh", "-c", "until test -e /testfile; do sleep 2; done"]
  containers:
  - image: myapp:v1
    name: myapp

典型场景

  • 等待数据库就绪

  • 初始化配置文件

  • 执行数据迁移脚本

7.2 存活探针(livenessProbe)

检测容器是否活着,失败则重启容器:

livenessProbe:
  tcpSocket:
    port: 80
  initialDelaySeconds: 3
  periodSeconds: 1
  timeoutSeconds: 1

三种检测方式

  • tcpSocket:TCP 端口存活检测

  • httpGet:HTTP 请求,返回 200-399 为成功

  • exec:在容器内执行命令,返回 0 为成功

7.3 就绪探针(readinessProbe)

检测容器是否准备好接收流量,失败则从 Service 的 Endpoints 中摘除:

readinessProbe:
  httpGet:
    path: /index.html
    port: 80
  initialDelaySeconds: 3
  periodSeconds: 2
  timeoutSeconds: 1

实战验证

  1. 创建带 readinessProbe 的 Pod 并暴露 Service

  2. 删除 Pod 内的 index.html 文件

  3. 观察 Service 的 Endpoints 自动移除该 Pod IP

  4. 重新创建文件后,Pod 自动恢复流量接收

7.4 三种探针的启动顺序

Pod 启动 → startupProbe(如配置)→ 成功后 → livenessProbe + readinessProbe 并行工作
  • startupProbe:用于慢启动应用,成功之前禁用其他探针

  • livenessProbe:持续检查,失败则重启

  • readinessProbe:持续检查,失败则摘除流量

八、重启策略(restartPolicy)

策略 行为
Always 无论什么原因退出,都重启(默认)
OnFailure 仅当非正常退出(退出码非 0)时重启
Never 退出后不重启
spec:
  restartPolicy: OnFailure

总结与最佳实践

场景 推荐方式
快速测试 命令式 kubectl run
开发调试 命令式对象配置 kubectl create -f
生产部署 声明式 kubectl apply -f
服务暴露 Service(ClusterIP/NodePort/LoadBalancer)
版本管理 Deployment + 滚动更新
健康检查 配置 livenessProbe + readinessProbe
资源控制 设置 requests 和 limits(尽量 Guaranteed)
容器初始化 使用 Init 容器处理前置条件

Kubernetes Pod 管理看似繁杂,实则内核清晰:声明期望状态,让控制器自动调和。 掌握命令是入门,理解 YAML 是进阶,精通探针和生命周期管理才是真正驾驭 K8s 的标志。希望这篇博客能成为你 K8s 学习路上的一个实用路标。

文中所有示例均基于 Kubernetes v1.30+ 环境验证,Harbor 仓库镜像 myapp:v1/v2 可自行构建或替换为任意 Nginx 镜像测试。

延伸阅读

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐