目录
什么是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: /healthz
port: 8080
initialDelaySeconds: 30 # 容器启动后延迟30秒开始探测
periodSeconds: 10 # 每10秒探测一次
failureThreshold: 3 # 连续失败3次后重启容器
- 就绪探针(Readiness Probe)
- 作用:检测容器是否准备好接收流量。若探测失败,Pod 会被从 Service 的端点列表中移除,避免无效请求。
- 适用场景:应用启动慢、依赖外部服务(如数据库)或需要加载大量数据时,确保流量仅路由到就绪的 Pod。
- 示例:
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 3
- 启动探针(Startup Probe)
- 作用:检测容器内的应用是否启动完成。在启动探针成功前,其他探针(Liveness/Readiness)会被禁用,避免误判。
- 适用场景:启动时间较长或初始化复杂的容器(如 Java 应用加载大量数据)。
- 示例:
startupProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 30 # 允许最多30次失败(总时间=10+5*29=155秒)
探针探测方式
- HTTP GET
- 向容器指定端口和路径发送 HTTP 请求,返回状态码在 200-399 范围内视为成功。
- 适用场景:Web 服务健康检查。
- 示例:
httpGet:
path: /health
port: 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: nginx
image: nginx:latest
imagePullPolicy: Always # 显式声明(默认行为)
IfNotPresent
- 行为:仅当本地不存在指定镜像时才从仓库拉取。
- 适用场景:
- 生产环境希望使用稳定版本,避免意外更新。
- 镜像标签为具体版本号(如
nginx:1.25.3
)。
- 示例:
containers:
- name: nginx
image: nginx:1.25.3
imagePullPolicy: IfNotPresent # 显式声明(推荐生产环境使用)
Never
- 行为:完全不从仓库拉取镜像,仅使用本地镜像。若本地不存在,则 Pod 启动失败。
- 适用场景:
- 离线环境或完全信任本地镜像。
- 测试镜像构建流程。
-
containers:
- name: nginx
image: nginx:1.25.3
imagePullPolicy: 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
字段。