目录
什么是Pod?
Pod 是 Kubernetes(K8s)中的核心概念,是集群中最小的可部署和可管理的计算单元。它封装了一个或多个紧密相关的容器(如应用容器和辅助容器),共享网络、存储和运行环境,旨在简化容器化应用的部署和管理;Pod是一组具有命名空间、IP地址和端口的容器的集合。
Pod 的核心特性
- 容器组
- 一个 Pod 可以包含 1 个或多个容器(通常建议每个 Pod 只运行一个主容器,其他为辅助容器,如日志收集器)。
- 容器共享 Pod 的网络命名空间(IP 地址、端口范围)、存储卷(Volume)和进程间通信(IPC)。
- 共享资源
- 网络:Pod 内所有容器共享同一个 IP 和端口空间,可通过
localhost直接通信。 - 存储:Pod 可以挂载共享存储卷(如 ConfigMap、Secret、持久化卷),供所有容器访问。
- 生命周期:Pod 内的容器同步启动/终止,共同面对调度、重启等操作。
- 网络:Pod 内所有容器共享同一个 IP 和端口空间,可通过
- 临时性(Ephemeral)
- Pod 是短暂存在的,可能因节点故障、资源不足或手动删除而终止。Kubernetes 通过控制器(如 Deployment、StatefulSet)管理 Pod 的生命周期,确保应用高可用。
为什么需要 Pod?
- 简化复杂应用部署:例如,一个 Web 应用可能需要主容器(Nginx)和边车容器(日志代理、监控代理),Pod 将它们绑定为一个逻辑单元。
- 统一资源管理:共享网络和存储减少了配置复杂度,避免容器间通过外部服务通信的开销。
- 支持多容器协作:某些场景需要多个容器紧密配合(如主从架构、数据预处理),Pod 提供了天然的协作环境。
Pod 与 Kubernetes 生态的协同
- 与控制器的协作
- Pod 通常通过控制器(如 Deployment、StatefulSet)间接管理,而非直接操作。例如:
- Deployment:管理无状态应用,支持滚动更新和回滚。
- StatefulSet:管理有状态应用(如数据库),确保 Pod 名称和存储的稳定性。
- Pod 通常通过控制器(如 Deployment、StatefulSet)间接管理,而非直接操作。例如:
- 与服务(Service)的集成
- Service 为 Pod 提供稳定的网络访问入口,通过标签选择器匹配 Pod,实现负载均衡和服务发现。
- 与存储(Volume)的集成
- Pod 可挂载多种类型的存储卷(如
emptyDir、hostPath、PersistentVolumeClaim),满足临时存储或持久化需求。
- Pod 可挂载多种类型的存储卷(如
创建 Pod
- 执行命令:直接创建(不推荐生产环境):
实例:kubectl run <Pod名> --image=<镜像名> --port=<端口>kubectl run nginx --image=nginx --port=80 - 通过 YAML 文件创建(推荐):
示例 YAML 文件(kubectl apply -f <YAML文件路径>pod.yaml):
执行命令:apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
kubectl apply -f pod.yaml
删除 Pod
删除单个 Pod:
kubectl delete pod <Pod名>
强制删除卡住的 Pod(慎用):
kubectl delete pod <Pod名> --grace-period=0 --force
删除所有 Pod(按命名空间):
kubectl delete pods --all -n <命名空间>
查看 Pod 状态与信息
查看所有 Pod
当前命名空间:
kubectl get pods
所有命名空间:
kubectl get pods -A
详细信息(含 IP 和节点):
kubectl get pods -o wide
查看 Pod 详情
kubectl describe pod <Pod名>
实时监控 Pod 状态
kubectl get pods -w
Pod 日志与调试
查看日志
查看主容器日志:
kubectl logs <Pod名>
实时跟踪日志:
kubectl logs -f <Pod名>
查看指定容器日志(多容器 Pod):
kubectl logs <Pod名> -c <容器名>
查看最近 N 行日志:
kubectl logs --tail=100 <Pod名>
进入 Pod 容器
交互式 Shell(Alpine 用 /bin/sh,Ubuntu 用 /bin/bash):
kubectl exec -it <Pod名> -- /bin/sh
在容器内执行命令:
kubectl exec <Pod名> -- ls /
在宿主机和pod容器之间拷贝文件
kubectl cp nginx:etc/fstab /opt/aaa.txt
kubectl cp /opt/aaa.txt nginx:etc
Pod 的核心状态字段
phase(阶段)
- 作用:概括 Pod 的整体生命周期阶段。
- 常见值:
Pending:Pod 已创建,但尚未调度到节点(如等待镜像拉取、资源不足)。Running:Pod 已调度到节点,且至少一个容器正在运行。Succeeded:所有容器均成功退出(适用于一次性任务,如 Job)。Failed:至少一个容器以非零状态退出(可能因错误终止)。CrashLoopBackOff:容器反复崩溃并重启(非标准phase,但常见于Running阶段的异常)。Unknown:Pod 状态无法获取(如与 kubelet 通信中断)。
- 示例:
yaml status: phase: Running
onditions(条件)
- 作用:细化描述 Pod 的健康状态和就绪情况。
- 常见条件:
Initialized:所有 Init 容器是否成功完成。Ready:Pod 是否能接收流量(由readinessProbe决定)。ContainersReady:所有主容器是否就绪。PodScheduled:Pod 是否已成功调度到节点。PodCompleted(仅适用于 Job):Pod 是否已完成所有任务。
- 字段结构:
yaml conditions: - type: Ready status: "True" # 或 "False", "Unknown" lastProbeTime: null lastTransitionTime: "2023-10-01T12:00:00Z" reason: "ContainersReady" message: "All containers are ready"
containerStatuses(容器状态)
- 作用:列出 Pod 中每个容器的详细状态。
- 关键字段:
name:容器名称。state:容器当前状态(running、waiting、terminated)。ready:容器是否就绪(true/false)。restartCount:容器重启次数。image:容器使用的镜像。imageID:镜像的唯一标识。
- 示例:
yaml containerStatuses: - name: nginx state: running: startedAt: "2023-10-01T12:00:00Z" ready: true restartCount: 0 image: nginx:latest imageID: "docker-pullable://nginx@sha256:...
hostIP 和 podIP
hostIP:Pod 所在节点的 IP 地址。podIP:Pod 的内部 IP 地址(集群内通信使用)。示例:
yaml status: hostIP: "192.168.1.100" podIP: "10.244.0.5"
startTime
- 作用:Pod 的启动时间(UTC 格式)。
- 示例:
yaml startTime: "2023-10-01T12:00:00Z" - Pod 状态的完整示例
yaml
status:
phase: Running
conditions:
- type: Initialized
status: "True"
reason: "PodCompleted"
- type: Ready
status: "True"
reason: "ContainersReady"
- type: ContainersReady
status: "True"
reason: "ContainersReady"
- type: PodScheduled
status: "True"
reason: "Scheduled"
containerStatuses:
- name: nginx
state:
running:
startedAt: "2023-10-01T12:00:00Z"
ready: true
restartCount: 0
image: nginx:latest
imageID: "docker-pullable://nginx@sha256:..."
hostIP: "192.168.1.100"
podIP: "10.244.0.5"
startTime: "2023-10-01T12:00:00Z"
常见状态组合与排查
1. Pending 状态
- 原因:
- 资源不足(CPU/内存)。
- 镜像拉取失败(如镜像不存在或网络问题)。
- 未满足节点选择器(NodeSelector)或亲和性规则。
- 排查命令:
kubectl describe pod <Pod名> | grep -A 10 "Events"
2. CrashLoopBackOff
- 原因:
- 容器启动后立即退出(如应用崩溃、配置错误)。
- 缺少依赖服务(如数据库未就绪)。
- 排查步骤:
- 查看日志:
kubectl logs <Pod名> --previous - 检查就绪探针(
readinessProbe)是否配置合理。
- 查看日志:
3. ImagePullBackOff
- 原因:镜像拉取失败(如镜像名称错误、私有仓库未授权)。
- 解决方案:
- 检查镜像名称和标签是否正确。
- 配置镜像拉取密钥(
imagePullSecrets)。
4. NotReady(Ready 条件为 False)
- 原因:
- 就绪探针失败(如服务未启动完成)。
- 容器未通过健康检查。
- 排查命令:
kubectl describe pod <Pod名> | grep -i ready
关键命令总结
| 命令 | 作用 |
|---|---|
kubectl get pod <Pod名> -o yaml |
查看 Pod 的完整状态和配置 |
kubectl describe pod <Pod名> |
查看 Pod 事件和详细状态 |
kubectl logs <Pod名> |
查看容器日志 |
kubectl top pod <Pod名> |
查看资源使用情况 |
kubectl get pod <Pod名> -o wide |
查看 Pod 的 IP 和节点信息 |
最佳实践
- 监控 Pod 状态:
使用kubectl get pods -w实时跟踪状态变化。 - 配置合理的探针:
通过livenessProbe和readinessProbe确保容器健康。 - 资源限制:
在 YAML 中设置resources.requests和resources.limits,避免资源争抢。 - 日志聚合:
将 Pod 日志集中到 ELK 或 Loki 等系统,便于排查问题。
Pod探针
在 Kubernetes 中,Pod 探针是用于监控容器健康状态的关键机制,主要包括 存活探针(Liveness Probe)、就绪探针(Readiness Probe) 和 启动探针(Startup Probe) 三种类型。它们通过不同的探测方式(HTTP GET、TCP Socket、Exec 命令)定期检查容器状态,并根据结果触发相应操作(如重启容器、控制流量路由)。
探针类型及作用
- 存活探针(Liveness Probe)
- 作用:检测容器是否正常运行。若探测失败,kubelet 会重启容器。
- 适用场景:应用崩溃、死锁或进入不可恢复状态时自动恢复服务。
- 示例:
livenessProbe:httpGet:path: /healthzport: 8080initialDelaySeconds: 30 # 容器启动后延迟30秒开始探测periodSeconds: 10 # 每10秒探测一次failureThreshold: 3 # 连续失败3次后重启容器
- 就绪探针(Readiness Probe)
- 作用:检测容器是否准备好接收流量。若探测失败,Pod 会被从 Service 的端点列表中移除,避免无效请求。
- 适用场景:应用启动慢、依赖外部服务(如数据库)或需要加载大量数据时,确保流量仅路由到就绪的 Pod。
- 示例:
readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 5failureThreshold: 3
- 启动探针(Startup Probe)
- 作用:检测容器内的应用是否启动完成。在启动探针成功前,其他探针(Liveness/Readiness)会被禁用,避免误判。
- 适用场景:启动时间较长或初始化复杂的容器(如 Java 应用加载大量数据)。
- 示例:
startupProbe:exec:command:- cat- /tmp/healthyinitialDelaySeconds: 10periodSeconds: 5failureThreshold: 30 # 允许最多30次失败(总时间=10+5*29=155秒)
探针探测方式
- HTTP GET
- 向容器指定端口和路径发送 HTTP 请求,返回状态码在 200-399 范围内视为成功。
- 适用场景:Web 服务健康检查。
- 示例:
httpGet:path: /healthport: 80
- TCP Socket
- 尝试与容器指定端口建立 TCP 连接,成功则视为健康。
- 适用场景:数据库、缓存等无 HTTP 接口的服务。
- 示例:
tcpSocket:port: 6379 # Redis 默认端口
- Exec 命令
- 在容器内执行命令,返回 0 视为成功。
- 适用场景:自定义健康检查逻辑(如检查进程是否存在)。
- 示例:
exec:command:- pgrep- nginx
探针配置参数
| 参数 | 说明 | 默认值 | 最小值 |
|---|---|---|---|
initialDelaySeconds |
容器启动后延迟多少秒开始第一次探测 | 0 | 0 |
periodSeconds |
探测间隔时间(秒) | 10 | 1 |
timeoutSeconds |
探测超时时间(秒) | 1 | 1 |
successThreshold |
连续成功次数(仅 Liveness/Readiness) | 1 | 1 |
failureThreshold |
连续失败次数(触发重启或移除) | 3 | 1 |
最佳实践
- 合理设置
initialDelaySeconds- 避免因应用启动未完成导致误判。例如,Java 应用可能需要 2-5 分钟初始化,可设置为
initialDelaySeconds: 300。
- 避免因应用启动未完成导致误判。例如,Java 应用可能需要 2-5 分钟初始化,可设置为
- 区分 Liveness 和 Readiness 探针
- Liveness:用于重启不可恢复的容器(如应用崩溃)。
- Readiness:用于控制流量路由(如应用暂时过载)。
- 避免共用探针:Liveness 和 Readiness 应检查不同端点或逻辑,防止因网络抖动导致不必要的重启。
- 优先使用 HTTP GET
- HTTP 方式更灵活,可返回详细状态信息(如
{"status": "healthy"}),便于调试。
- HTTP 方式更灵活,可返回详细状态信息(如
- 监控探针日志
- 通过
kubectl describe pod <Pod名>查看探针事件,快速定位问题。
- 通过
- 结合资源限制
- 在 YAML 中配置
resources.requests和resources.limits,避免容器因资源不足导致探针失败。
- 在 YAML 中配置
示例 YAML 配置
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp-container
image: my-app-image
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
exec:
command:
- cat
- /tmp/initialized
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30
Pod镜像拉取策略和重启策略
镜像拉取策略
作用
定义 Kubernetes 如何从镜像仓库拉取容器镜像,避免不必要的网络请求或镜像更新问题。
Always- 行为:每次创建 Pod 时都从镜像仓库拉取最新镜像(即使本地已存在同名镜像)。
- 适用场景:
- 需要强制使用最新镜像(如开发环境频繁更新)。
- 镜像标签为
latest(默认策略为Always)。
- 示例:
containers:- name: nginximage: nginx:latestimagePullPolicy: Always # 显式声明(默认行为)
IfNotPresent- 行为:仅当本地不存在指定镜像时才从仓库拉取。
- 适用场景:
- 生产环境希望使用稳定版本,避免意外更新。
- 镜像标签为具体版本号(如
nginx:1.25.3)。
- 示例:
containers:- name: nginximage: nginx:1.25.3imagePullPolicy: IfNotPresent # 显式声明(推荐生产环境使用)
Never- 行为:完全不从仓库拉取镜像,仅使用本地镜像。若本地不存在,则 Pod 启动失败。
- 适用场景:
- 离线环境或完全信任本地镜像。
- 测试镜像构建流程。
-
containers:- name: nginximage: nginx:1.25.3imagePullPolicy: Never # 强制使用本地镜像
默认策略
- 如果镜像标签为
latest,默认策略为Always。 - 其他标签(如
1.25.3)默认策略为IfNotPresent。
注意事项
- 镜像标签建议:生产环境应使用具体版本号(如
1.25.3)而非latest,避免不可预测的更新。 - 私有仓库配置:若使用私有镜像仓库,需通过
imagePullSecrets配置认证信息:spec:imagePullSecrets:- name: my-registry-secret
镜像重启策略
作用
定义 Pod 中容器退出后,Kubernetes 是否自动重启容器,以及重启的行为方式。
可选值
Always- 行为:无论容器因何种原因退出(成功或失败),kubelet 都会自动重启容器。
- 适用场景:
- 长运行服务(如 Web 服务器、数据库)。
- 默认策略(除非显式指定其他值)。
- 示例:
spec:restartPolicy: Always # 显式声明(默认行为)
OnFailure- 行为:仅当容器以非零状态退出(失败)时重启容器;若容器正常退出(状态码 0),则不重启。
- 适用场景:
- 一次性任务(如批处理作业),希望成功完成后不重启。
- 需结合
Job控制器使用(Pod 通常由更高层控制器管理)。
- 示例:
spec:restartPolicy: OnFailure
Never- 行为:无论容器如何退出,都不重启容器。
- 适用场景:
- 一次性任务(如初始化脚本),退出后无需恢复。
- 调试时手动控制容器生命周期。
- 示例:
spec:restartPolicy: Never
默认策略
- Pod 级别:默认策略为
Always(但 Pod 通常由控制器管理,实际行为由控制器决定)。 - 控制器覆盖:
- Deployment/StatefulSet:强制使用
Always(忽略 Pod 的restartPolicy)。 - Job:强制使用
OnFailure或Never(根据任务类型)。 - DaemonSet:强制使用
Always。
- Deployment/StatefulSet:强制使用
关键区别
| 策略 | 容器退出状态 | 重启行为 |
|---|---|---|
Always |
任意 | 总是重启 |
OnFailure |
非零 | 仅失败时重启 |
Never |
任意 | 不重启 |
注意事项
- Pod 与控制器的关系:
- 直接创建的 Pod(无控制器)会严格遵循
restartPolicy。 - 通过控制器(如 Deployment)创建的 Pod,重启策略由控制器决定(例如 Deployment 始终重启失败的 Pod)。
- 直接创建的 Pod(无控制器)会严格遵循
- 重启次数限制:
- kubelet 会记录容器重启次数,但不会无限重启(受节点资源或集群策略限制)。
- 可通过
kubectl describe pod <Pod名>查看restartCount字段。