整理关于k8s pod管理
Pod 是 Kubernetes 中最小的调度单元,也是应用运行的最小载体。理解 Pod 的生命周期、调度机制、健康检查和资源管理,是每个 K8s 使用者的必修课。本文将深入探讨 Pod 管理的关键技术与最佳实践。
Pod 的核心概念
Pod 由一个或多个容器组成,这些容器共享:
-
网络命名空间:共享 IP 和端口空间
-
存储卷(Volume):共享数据
-
IPC 命名空间:进程间通信
-
生命周期:同生共死
Pod 的调度机制
Pod 创建 → Scheduler 调度 → 节点绑定 → Kubelet 拉取镜像 → 容器启动 → Pod Running
调度器考虑的维度:
-
资源需求(CPU/内存)
-
节点亲和性/反亲和性
-
污点与容忍
-
拓扑分布约束
Pod 生命周期的五大阶段
| 阶段 | 说明 |
| Pending | Pod 已被创建,但尚未调度或镜像未拉取完成 |
| Running | 至少一个容器处于运行状态 |
| Succeeded | 所有容器成功退出(Job 场景) |
| Failed | 至少一个容器以非零状态退出 |
| Unknown | 节点失联,状态未知 |
容器状态与重启策略
容器状态
-
Waiting:等待拉取镜像或启动
-
Running:运行中
-
Terminated:已终止,包含退出码
重启策略
| Always | 始终重启 | 常驻服务(Deployment) |
| OnFailure | 失败时重启 | 批处理任务(Job) |
| Never | 从不重启 | 一次性任务 |
kubectl 命令总览与分类
资源创建:create
# 从 YAML/JSON 文件创建
kubectl create -f deployment.yaml
kubectl create -f https://example.com/remote-config.yaml
# 从目录创建(递归处理)
kubectl create -f ./manifests/
# 从多个文件创建
kubectl create -f pod.yaml -f service.yaml -f configmap.yaml
kubectl apply(声明式管理)
# 创建或更新(幂等操作)
kubectl apply -f deployment.yaml
# 首次创建:效果同 create
# 再次执行:对比差异,更新变更部分
kubectl edit
# 编辑 Deployment
kubectl edit deployment nginx
# 指定编辑器
KUBE_EDITOR="nano" kubectl edit pod my-pod
# 编辑所有匹配的资源
kubectl edit deployment -l app=web
kubectl patch(部分更新)
# 修改镜像
kubectl patch deployment nginx -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.25"}]}}}}'
# 添加标签
kubectl patch deployment nginx -p '{"metadata":{"labels":{"version":"v2"}}}'
kubectl replace
# 用新文件完全替换
kubectl replace -f updated-deployment.yaml
# 替换并强制(即使有冲突)
kubectl replace -f updated-deployment.yaml --force
# 从 stdin 替换
cat new-config.yaml | kubectl replace -f -
kubectl expose
# 为 Deployment 创建 Service(ClusterIP)
kubectl expose deployment nginx --port=80 --target-port=80
# 指定 Service 类型为 NodePort
kubectl expose deployment nginx \
--type=NodePort \
--port=80 \
--target-port=8080 \
--name=nginx-nodeport
# 创建 LoadBalancer
kubectl expose deployment web-app \
--type=LoadBalancer \
--port=443 \
--target-port=8443 \
--name=web-lb
# 指定 NodePort 端口号
kubectl expose deployment nginx \
--type=NodePort \
--port=80 \
--node-port=30080
容器重启规则
Always 无论什么原因都会从新运行pod
# API 版本,Pod 属于核心 v1 组
apiVersion: v1
# 资源类型为 Pod
kind: Pod
# 元数据,用于描述资源的基本信息
metadata:
# 标签,用于标识和筛选此 Pod
labels:
run: testpod # 标签键值对:run=testpod
# Pod 的名称,在命名空间内唯一
name: testpod
# Pod 的规格定义,描述期望状态
spec:
# 使用宿主机网络(关键配置)
hostNetwork: true # true 表示 Pod 直接使用宿主机的网络命名空间
# 效果:Pod 内的容器共享宿主机的 IP 和端口
# 无需端口映射,容器监听的端口直接在宿主机上生效
# 重启策略
restartPolicy: Always # 容器退出后总是自动重启
# 其他选项:OnFailure(失败时重启)、Never(从不重启)
# 容器列表
containers:
# ========== 容器:busybox ==========
- image: busybox:latest # 使用 busybox 最新版镜像(轻量级工具容器)
name: busybox # 容器名称
command: # 容器启动时执行的命令(覆盖镜像默认命令)
- /bin/sh # 使用 shell 解释器
- -c # 从后面的字符串参数中读取命令
- sleep 60 # 睡眠 60 秒
# 作用:容器启动后执行 sleep 60,保持运行 60 秒
# 60 秒后容器退出,由于 restartPolicy: Always,会自动重启
# 因此这个 Pod 会不断循环:运行 60 秒 → 退出 → 重启
OnFailure 非正常管关闭会从其pod
# API 版本,Pod 属于核心 v1 组
apiVersion: v1
# 资源类型为 Pod
kind: Pod
# 元数据,用于描述资源的基本信息
metadata:
# 标签,用于标识和筛选此 Pod
labels:
run: testpod # 标签键值对:run=testpod
# Pod 的名称,在命名空间内唯一
name: testpod
# Pod 的规格定义,描述期望状态
spec:
# 使用宿主机网络(关键配置)
hostNetwork: true # true 表示 Pod 直接使用宿主机的网络命名空间
# 效果:Pod 内的容器共享宿主机的 IP 和端口
# 无需端口映射,容器监听的端口直接在宿主机上生效
# 重启策略(与上一个配置的差异)
restartPolicy: OnFailure # 仅当容器失败退出(退出码非 0)时才重启
# 如果容器正常退出(退出码 0),不会重启
# 其他选项:Always(总是重启)、Never(从不重启)
# 容器列表
containers:
# ========== 容器:busybox ==========
- image: busybox:latest # 使用 busybox 最新版镜像(轻量级工具容器)
name: busybox # 容器名称
command: # 容器启动时执行的命令(覆盖镜像默认命令)
- /bin/sh # 使用 shell 解释器
- -c # 从后面的字符串参数中读取命令
- sleep 30 # 睡眠 30 秒
# 作用:容器启动后执行 sleep 30,保持运行 30 秒
# 30 秒后容器正常退出(退出码 0)
# 由于 restartPolicy: OnFailure,正常退出不会触发重启
# 因此这个 Pod 运行 30 秒后就会变为 Completed 状态
Never pod关闭后不重启
# API 版本,Pod 属于核心 v1 组
apiVersion: v1
# 资源类型为 Pod
kind: Pod
# 元数据
metadata:
# 标签:run=testpod
labels:
run: testpod
# Pod 名称
name: testpod
# Pod 规格定义
spec:
# 使用宿主机网络(关键配置)
hostNetwork: true # true 表示 Pod 直接使用宿主机的网络命名空间
# 效果:Pod 内的容器共享宿主机的 IP 地址和端口
# 无需端口映射,容器监听的端口直接在宿主机上生效
# 容器可以直接访问宿主机的网络接口
# 重启策略
restartPolicy: Never # 从不重启
# 容器退出后(无论成功或失败)都不会重启
# 其他选项:
# Always - 总是重启(默认)
# OnFailure - 失败时重启(退出码非 0)
# 容器列表
containers:
- image: busybox:latest # 使用 busybox 最新版镜像(轻量级工具容器)
name: busybox # 容器名称
command: # 容器启动时执行的命令
- /bin/sh # 使用 shell 解释器
- -c # 从后面的字符串参数中读取命令
- sleep 30 # 睡眠 30 秒
# 作用:容器启动后执行 sleep 30,保持运行 30 秒
# 30 秒后容器正常退出(退出码 0)
# 由于 restartPolicy: Never,容器不会重启
# Pod 最终状态为 Succeeded(Completed)
init容器
什么是 Init 容器
Init 容器是 Pod 中在应用容器启动之前运行的特殊容器,用于完成初始化工作。一个 Pod 可以包含多个 Init 容器,它们按顺序依次执行,全部成功完成后,应用容器才会启动。
# API 版本,Pod 属于核心 v1 组
apiVersion: v1
# 资源类型为 Pod
kind: Pod
# 元数据,用于描述资源的基本信息
metadata:
# 标签,用于标识和筛选此 Pod
labels:
run: webserver # 标签键值对:run=webserver
# Pod 的名称,在命名空间内唯一
name: webserver
# Pod 的规格定义,描述期望状态
spec:
# ========== Init 容器列表 ==========
initContainers:
- name: busybox # Init 容器名称
image: busybox:latest # 使用 busybox 最新版镜像
command: # 容器启动时执行的命令
- /bin/sh # 使用 shell 解释器
- -c # 从后面的字符串参数中读取命令
- "until test -e /testfile;do echo wating for myservice; sleep 2;done"
# 命令含义:
# until test -e /testfile:循环检查 /testfile 文件是否存在
# do echo wating for myservice:文件不存在时输出提示信息
# sleep 2:每 2 秒检查一次
# done:结束循环
# 作用:等待 /testfile 文件出现,文件存在后循环结束,Init 容器成功退出
# ========== 应用容器列表 ==========
containers:
- image: myapp:v1 # 使用 myapp:v1 镜像
name: webserver # 容器名称
# 注意:未定义 command,使用镜像默认启动命令
# 注意:未定义端口,未定义资源限制
# 重启策略
restartPolicy: Always # 容器退出后总是重启
# 其他选项:OnFailure(失败时重启)、Never(从不重启)
注意事项
-
Init 容器会一直等待,直到
/testfile文件出现 -
如果文件一直不出现,Pod 会一直处于
Init:0/1状态 -
Init 容器成功退出后,应用容器才会启动
-
restartPolicy: Always对 Init 容器同样生效,失败后会重启
Kubernetes Liveness 存活探针
什么是 Liveness 探针
Liveness 探针(存活探针)用于检测容器是否还活着。如果探针检测到容器已经"死亡"(应用崩溃、死锁等),Kubernetes 会自动重启该容器,尝试恢复服务。
apiVersion: v1
kind: Pod
metadata:
labels:
run: webserver
name: webserver
spec:
containers:
- image: myapp:v1
name: webserver
command: ["/bin/sh", "-c"]
args:
- |
nginx -g "daemon off;"
sleep 10000
# 添加 Liveness 探针
livenessProbe:
httpGet: # HTTP 方式检查
path: / # 检查根路径
port: 80 # 检查 80 端口
initialDelaySeconds: 10 # 启动后 10 秒开始检查
periodSeconds: 5 # 每 5 秒检查一次
timeoutSeconds: 3 # 超时时间 3 秒
failureThreshold: 3 # 连续失败 3 次后重启
restartPolicy: Always
Kubernetes Readiness 就绪探针
什么是 Readiness 探针
Readiness 探针(就绪探针)用于检测容器是否准备好接收流量。如果探针失败,Kubernetes 会将该 Pod 从 Service 的负载均衡中摘除,但不会重启容器。
# ========== 第一部分:Pod 定义 ==========
# API 版本,Pod 属于核心 v1 组
apiVersion: v1
# 资源类型为 Pod
kind: Pod
# 元数据,用于描述资源的基本信息
metadata:
# 标签,用于标识和筛选此 Pod
labels:
run: webserver # 标签键值对:run=webserver(关键,Service 通过此标签关联)
# Pod 的名称,在命名空间内唯一
name: webserver
# Pod 的规格定义,描述期望状态
spec:
# 容器列表
containers:
- image: myapp:v1 # 使用 myapp:v1 镜像
name: webserver # 容器名称
# 注意:未定义 ports,容器需自行监听端口
# 注意:未定义 readinessProbe,Pod 启动后立即就绪
# 重启策略
restartPolicy: Always # 容器退出后总是重启
---
# ========== 第二部分:Service 定义 ==========
# 分隔符,表示两个独立的 Kubernetes 资源
# API 版本,Service 属于核心 v1 组
apiVersion: v1
# 资源类型为 Service
kind: Service
# 元数据,用于描述资源的基本信息
metadata:
# 标签,用于标识此 Service
labels:
run: webserver # Service 自身的标签
# Service 的名称,在命名空间内唯一
name: webserver
# Service 的规格定义
spec:
# 端口配置列表
ports:
- port: 80 # Service 对外暴露的端口(集群内部访问用)
protocol: TCP # 使用 TCP 协议
targetPort: 80 # 转发到 Pod 的端口(Pod 内容器监听的端口)
# 选择器:关联标签为 run=webserver 的 Pod
selector:
run: webserver # 选中所有带有 run=webserver 标签的 Pod
-
注意事项
-
标签必须匹配
-
端口必须正确
-
缺少就绪探针
-
Service 默认只能内部访问
-
节点污点可能导致调度失败
Kubernetes 控制器
ReplicaSet 控制器
ReplicaSet 是 Kubernetes 中保证 Pod 副本数量的基础控制器,它确保在任何时刻都有指定数量的 Pod 副本在运行
创建 ReplicaSet
通过 kubectl create deployment 生成配置模板,再修改为 ReplicaSet 类型
apiVersion: apps/v1
kind: ReplicaSet
metadata:
labels:
app: webcluster
name: webcluster
spec:
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
动态伸缩
# 扩容到 4 个副本
kubectl scale replicaset webcluster --replicas 4
# 缩容到 2 个副本
kubectl scale replicaset webcluster --replicas 2
# 缩容到 0
kubectl scale replicaset webcluster --replicas 0
核心价值:当 Pod 因故障退出时,ReplicaSet 会自动创建新的 Pod 进行替换,实现了自愈能力。
Deployment 控制器
Deployment 是 ReplicaSet 的上层封装,提供了声明式更新、版本回滚、更新策略控制等高级功能,是生产环境中最常用的控制器。
创建 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: webcluster
name: webcluster
spec:
minReadySeconds: 5
replicas: 2
selector:
matchLabels:
app: webcluster
template:
metadata:
labels:
app: webcluster
spec:
containers:
- image: myapp:v1
name: myapp
关键参数说明:
-
minReadySeconds: 新 Pod 就绪后等待多久才视为可用 -
replicas: 期望的 Pod 副本数 -
selector: 标签选择器,用于关联 Pod
版本升级与回滚
升级到 v2 版本:
# 修改镜像版本并重新 apply
vim dep.yml # image: myapp:v2
kubectl apply -f dep.yml
curl <ClusterIP>:80 # Hello MyApp | Version: v2
回滚到 v1 版本:
vim dep.yml # image: myapp:v1
kubectl apply -f dep.yml
curl <ClusterIP>:80 # Hello MyApp | Version: v1
DaemonSet 控制器
DaemonSet 确保在每个节点上运行一个 Pod 副本,常用于日志收集、监控代理、网络插件等需要节点级部署的场景。
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: daemonset
name: daemonset
spec:
selector:
matchLabels:
app: daemonset
template:
metadata:
labels:
app: daemonset
spec:
containers:
- image: myapp:v1
name: myapp
节点自动扩展
当新节点加入集群时,DaemonSet 会自动在新节点上创建 Pod:
# 生成新节点加入 Token
kubeadm token create --print-join-command
# 新节点加入后,DaemonSet Pod 自动运行
kubectl get pods -o wide # 查看 Pod 分布
Job 控制器
创建 Job
apiVersion: batch/v1
kind: Job
metadata:
name: job
spec:
completions: 6 # 总任务数
parallelism: 2 # 并行执行数
backoffLimit: 4 # 失败重试次数
template:
spec:
containers:
- image: perl:5.34.0
name: job
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
-
completions: 总共需要成功完成的 Pod 数量 -
parallelism: 同时运行的 Pod 数量 -
backoffLimit: 失败重试次数上限
CronJob 控制器
CronJob 是 Job 的定时调度版本,类似 Linux 的 cron,用于周期性执行任务。
创建 CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: cronjob
spec:
schedule: '* * * * *' # 每分钟执行一次
jobTemplate:
metadata:
name: cronjob
spec:
template:
spec:
containers:
- image: busybox
name: cronjob
command:
- /bin/sh
- -c
- echo "hello timinglee"
restartPolicy: OnFailure
CronJob 常见用途:
-
定期数据库备份
-
定时清理过期数据
-
周期性报表生成
-
定时同步数据
实践建议
-
生产环境优先使用 Deployment,充分利用滚动更新和回滚能力
-
合理设置更新策略:
maxSurge: 1, maxUnavailable: 0实现零停机更新 -
使用
minReadySeconds确保新版本 Pod 稳定后再继续滚动更新 -
DaemonSet 用于节点级服务,如日志、监控、网络组件
-
Job/CronJob 设置合理的
backoffLimit,避免无限重试浪费资源 -
结合
kubectl rollout命令实现优雅的版本管理和发布控制
更多推荐

所有评论(0)