kubernetes pod深度理解
- 什么是Pod
-
- 从使用的角度来看
- [从 Kubernetes 的角度来看](#从 Kubernetes 的角度来看)
-
- [Pod 两个特点:](#Pod 两个特点:)
- [Pod 的状态](#Pod 的状态)
- Pod探针
-
- [Pod 探针的实现方式](#Pod 探针的实现方式)
- pod探针类型
- Pod镜像拉取策略和重启策略
- 创建一个简单的Pod
-
- 编写一个简单的Pod
- 编写Pod配置文件frontend-localredis-pod.yaml
- pod文件语法
-
- (1)Pod文件的一级属性
- (2)spec(规格)属性
- [(3)通过kubectl explain命令来查看每种资源的可配置项](#(3)通过kubectl explain命令来查看每种资源的可配置项)
- [运行kubectl create命令创建此pod](#运行kubectl create命令创建此pod)
- 删除pod
- Pod的基本用法
- 静态pod
-
- 删除pod
- [pod 的启动过程包含的步骤](#pod 的启动过程包含的步骤)
-
- [(1)用户提交 Pod 定义](#(1)用户提交 Pod 定义)
- [(2)API Server 接收请求](#(2)API Server 接收请求)
- [(3)Scheduler 调度 Pod](#(3)Scheduler 调度 Pod)
- [(4)kubelet 创建 Pod](#(4)kubelet 创建 Pod)
- (5)容器运行时启动容器
- [(6)kubelet 更新 Pod 状态](#(6)kubelet 更新 Pod 状态)
- [(7)Pod 进入运行状态](#(7)Pod 进入运行状态)
- (8)探针检查(可选)
- [(9)Pod 可用](#(9)Pod 可用)
- (10)持续监控
- [Pod 的运行状态](#Pod 的运行状态)
- 故障排除步骤
-
- [1.查看 Pod 事状态](#1.查看 Pod 事状态)
- [2.查看 Pod 日志(Failed 状态下)](#2.查看 Pod 日志(Failed 状态下))
- [3.Pod 处于 Pending 状态](#3.Pod 处于 Pending 状态)
- [4.Pod 处于 ImagePullBackoff 状态](#4.Pod 处于 ImagePullBackoff 状态)
- [5.Pod 处于 crashLoopBackoff 状态](#5.Pod 处于 crashLoopBackoff 状态)
- [6.Pod 处于 ErrImagePull 状态](#6.Pod 处于 ErrImagePull 状态)
- [7.Pod 处于 containercreating 状态](#7.Pod 处于 containercreating 状态)
- 8:检查网络和存储
- 9.检查资源限制
什么是Pod
Pod 是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及运行规范。在 Pod 中,所有容器都被统一安排和调度。对于具体应用而言,Pod 是它们的逻辑主机,Pod 包含业务相关的多个应用容器。所以,Pod 是一组具有共享命名空间、IP地址和端口的容器的集合。
从使用的角度来看
在实际的使用时,单个容器是无法单独来支撑我们的应用的,往往需要很多微服务才能组成一个系统,并且还会存在A服务依赖B服务,B服务需要和C服务共用某个目录。另外,在使用裸容器时,很难实现对容器内进行健康检査以及横向扩容等操作,而Pod 可以轻松解决这些问题。
从 Kubernetes 的角度来看
Docker 只是容器 Runtime(运行时)的一种们还有很多容器 Runtime,比如 Rkt、CRI-0 等,而Kubernetes 作为目前最流行的容器编排工具,需要文持各个 Runtime 并且不依赖于底层 Runtime 的实现技术,于是就抽象出了 Pod 这个概念,用于管理多个紧密相连的符合 CRI 标准的容器。
Pod 可以简单的理解为一组、一个或多个容器,每个 Pod 还包含一个 Pause 容器,Pause 容器是 Pod的父容器,主要负责僵尸进程的回收管理。同时,通过 Pause 容器可以使同一个 Pod 里面的不同容器共享存储、网络、PID、IPC(进程间通信)等,容器之间可以使用 Localhost:Port 的方式相互访问,可以使用 volume 实现数据共享。根据 Docker 的构造,Pod 可以被创建为一组具有共享命名空间、IP 地址和端口的容器。
Pod 两个特点:
网络 :
每一个 Pod 都会被指派一个唯一的 Ip地址,在 Pod 中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个 Pod 中的容器可以同 localhost 进行互相通信。当 Pod 中的容器需要与Pod 外的实体进行通信时,则需要通过端口等共享的网络资源。
存储 :Pod 能够被指定共享存储卷的集合,在 Pod 中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个 Pod 持久化数据,以防止其中的容器需要被重启。
Pod 的状态
(1)kubectl命令创建pod

(2)查看pod

(3)显示pod的更多信息

(4)查看pod日志

查看日志

(5)以yaml格式显示pod详细信息

(6)显示资源的详细描述信息

kubectl get :常用于査看同一资源类型的一个或多个资源对象,可以使用 -o 参数自定义输出格式。
kubectl describe:侧重于描述指定资源的各方面的详细信息,不仅会返回节点信息,还会返回在其上运行的 Pod 的摘要、节点事件等信息。
(7)在pod的容器中执行命令

-c:指定Pod中容器的名字
(8)登录到Pod中的容器中

kubectl exec -it nginx-- bash如果登录的时候不指定容器,就登录到 Pod 中的第一个容器中。
(9)在线编辑运行中的资源对象

(10)将pod的端口映射到宿主机

其他主机访问curl ip:8080

此命令会在前台运行,此时就可以在其他客户端用该 k8s 主机的 IP 地址和 8080 的端口号进行访问了,Ctrl+c停止,但停止后就没有这个映射了。
(11)在宿主机和pod的容器之间拷贝文件
访问测试

(12)pod的状态

pod的状态不止有Running,常见的其他状态如表
状态 | 说明 |
---|---|
Pending(挂起) | Pod 已经被 Kubernetes 系统接收,但是仍有一个或多个容器未被创建,可以通过kubectl describe 查看处于Pending 状态的原因 |
Running(运行中) | Pod 已经被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个是运行的状态、正在启动或者重启,可以通过 kubectl logs 査看 Pod 的日志 |
Succeeded | 所有容器执行成功,并终止,并且不会再次重启,可以通过kubectl logs 査看 Pod 的日志 |
Failed(失败) | 所有容器都已终止,并且至少一个容器以失败的方式终止,也就是说这个容器要么以非零状态退出,要么被系统终止可以通过 logs 和 describe 査看 Pod 的日志和状态 |
Unknown(未知) | 通常是由于通信问题造成的无法获得 Pod 的状态 |
ImagePullBackOff ErrImagePull | 镜像拉取失败,一般是由于镜像不存在、网络不通或者需要登录认证引起的,可以使用 describe 命令查看具体的原因 |
CrashLoopBackOff | 容器启动失败,可以通过 logs 命令查看具体的原因,一般为启动命令不正确、健康检查不通过等原因 |
OOMKilled | 容器内存溢出,一般是容器的内存 Limit 设置的过小,或者程序本身有内存溢出,可以通过 logs 查看程序的启动日志 |
Terminating | Pod 正在被删除,可以通过 describe 查看状态 |
SysctlForbiden | Pod 自定义了内核配置,但 kubectl 没有添加内核配置或配置的内核参数不支持,可以通过 describe 查看具体原因 |
Completed | 容器内部主进程退出,一般计划任务执行结束会显示该该状态,此时可以通过 logs 查看容器日志 |
Containercreating | Pod 正在创建,一般正在下载镜像,或者有配置不当的地方,可以通过 describe 查看具体原因 |
(13)删除Pod

Pod探针
在生产环境中,进程正常启动并不代表应用能正常处理请求,所以合理的设计应用的健康检査尤其重要。在使用裸机或裸容器部署时,一般很难对应用做很完善的健康检査,而 Pod 提供的探针可以很方便的用来检测容器的应用是否正常。
Pod 探针的实现方式
目前探针有3种检测方式,可以根据不同的场景选择合适的健康检查方式,分别是ExecAction、TCPSocketAction 和 HTTPGetAction。具体实现方式如表
pod探诊的实现方式
实现方式 | 说明 |
---|---|
ExecAction | 在容器内执行一个指定的命令,如果命令返回值为 0,则认为容器健康 |
TCPSocketAction | 通过 TCP 连接检查容器指定的端口,如果端口开放,则认为容器健康 |
HTTPGetAction | 对指定的 URL 进行 Get 请求,如果状态码在 200 - 400 之间,则认为容器健康 |
容器状态
状态 | 说明 |
---|---|
Success(成功) | 容器通过检查 |
Failure(失败) | 容器检查失败 |
Unknown(未知) | 诊断失败,因此不采取任何措施 |
pod探针类型
Pod 探针有三类,分别是:livenessProbe(存活探针)、readinessProbe(就绪探针)、startupProbe(启动探针)。
(1)livenessProbe(存活探针)
它被用来知道一个容器是否在正常运行。如果容器未能通过存活探针的检查,则系统会认为该容器己经进入了一个必须被重启的状态,从而自动重启这个容器。这种机制可以确保容器在出现问题后能够自动恢复到可用状态。
存活探针支持以下几种类型:
HTTP GET 请求 - 通过发送 HTTP 请求到容器内的某个 URL 来检测容器是否处于健康状态。
Exec执行命令 -在容器内执行一个自定义命令或可执行文件,并根据其退出码判断容器是否健康。
TCP Socket - 尝试打开一个 TCP socket 连接到容器上的指定端口,如果连接成功则认为容器是健康的。
(2)readinessProbe(就绪探针)
判断容器是否能够进入 ready 状态,用于确定 Pod 中的容器是否已准备好接收流量。与livenessProbe 不同,readinessProbe 主要关注的是容器是否已经准备好为服务提供者处理请求。如果容器没有通过就绪探针的检査Kubernetes 将不会把任何新的网络流量路由到这个容器上。
当一个容器报告自己尚未准备好时,Kubernetes可能会采取以下行动:
服务(Service)不会将流量路由到未准备好的Pod。
如果 Pod 是副本集(Replicaset)、部署(Deployment)、状态集(statefulset)等的一部分,控制器会认为这个实例不可用。
对于使用 Pod 的滚动更新策略的情况,就绪探针可以帮助确保新版本的 Pod 在旧版本被终止之前就已经准备好了。
就像 livenessProbe 一样,readinessProbe 也支持多种类型的探测方法:
HTTP GET 请求 -发送 HTTP 请求到容器内的某个 URL
Exec执行命令 -在容器内执行一个自定义命令或可执行文件。
TCP Socket -尝试建立一个到容器上的指定端口的 TCP 连接。
(3)startupProbe(启动探针)
判断容器内的应用是否启动成功,在 success 状态前,其它探针都处于无效状态。它专门用于检测容器是否完成了初始化并进入了预期的运行状态。与livenessProbe(存活探针)和 readinessProbe(就绪探针)不同,startupProbe专注于容器启动阶段,并且仅在容器启动过程中使用。
startupProbe 的主要作用是在容器启动期间持续检査容器是否已经完成启动。一旦容器通过了startupProbe 的检查,Kubernetes 就会认为容器已经成功启动,并停止对该容器的启动探针检查。如果容器始终无法通过启动探针的检査,那么 Kubernetes 将会根据配置重试一定的次数,超过重试次数后可能会采取进一步的措施,如重启容器。
Pod镜像拉取策略和重启策略
镜像拉取策略
操作方式 | 说明 |
---|---|
Always | 总是拉取,无论镜像是否存在,总是拉取 |
Never | 无论是否存在都不会拉取 |
IfNotPresent | 镜像不存在时拉取镜像,是 k8s 默认的策略,但是如果 tag 为 latest,则总是拉取 |
指定拉取策略:

Pod重启策略
在 Kubernetes 中,Pod 的重启策略(Restart Policy)定义了当容器退出或失败时,kubelet 如何处理容器。重启策略是 Pod 级别的配置,适用于Pod 中的所有容器
在 Always 策略中,只要容器退出(无论退出码是什么),kubelet 都会自动重启容器。适用于需要持续运行的服务(如 Web 服务器、数据库等)。
在 OnFailure 策略中,只有当容器以非零退出码退出时,kubelet 才会重启容器,如果容器正常退出(退出码为 0),则不会重启。适用于任务型 Pod(如批处理任务),任务完成后不需要重启
在 Never 策略中,无论容器以何种方式退出,kubelet 都不会重启容器。适用于一次性任务,任务完成后不需要重启。
操作方式 | 说明 |
---|---|
Always | 容器退出即重启,适用于长期运行的服务 |
OnFailure | 容器失败时重启,适用于任务型工作负载 |
Never | 容器退出后不重启,适用于一次性任务 |
指定重启策略:

创建一个简单的Pod
编写一个简单的Pod

编写Pod配置文件frontend-localredis-pod.yaml

命令 | 含义 |
---|---|
apiVersion:v1 | 必选,版本号 |
kind: Pod | 必选,资源类型 |
metadata | 必选,元数据 |
name:redis-php | 必选,Pod 名称 |
labels | 自定义的 pod 标签列表 |
name:redis-php | 标签值 |
spec | 必选,Pod 中容器的详细信息 |
containers | 必选,Pod 中的容器列表 |
name:frontend | 必选,自定义的容器名称 |
image:kubeguide/guestbook-php-frontend:localredis | 必选,容器的镜像名称 |
imagePullPolicy:IfNotPresent | 镜像拉取策略 |
livenessProbe | 设置存活探针 |
tcpsocket | 测试某端口是否可以连接 |
port:80 | 指定要测试的端口 |
initialDelaySeconds:1 | 指定 kubelet 在执行第一次探测前应该等待1秒,即第一次探测是#在容器启动后的第2秒才开始执行。默认是8秒,最小值是0 |
periodseconds:3 | 指定了 kubelet 应该每 3 秒执行一次存活探测。默认是 10 秒。最小值是 1 |
timeoutseconds:1 | 当探测失败时,Kubernetes 在超时之前等待的时间。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃Pod 会被打上未就绪的标签。默认值是 3。最小值是 1 |
ports | 需要暴露的端口号列表 |
-containerPort:80 | 容器需要监听的端口号 |
- name:redis | 另一个容器的名字 |
image: kubeguide/redis-master | 另一个容器的镜像 |
ports | 需要暴露的另一个容器的端口列表 |
- containerPort:6379 | 容器需要监听的端口号 |
restartPolicy: onFailure | 重启策略 |
pod文件语法
(1)Pod文件的一级属性
一级属性主要包含5部分:
apiVersion <string> 版本,由 kubernetes 内部定义,版本号必须可以用 kubectl api-versions查询到
kind <string> 类型,由 kubernetes 内部定义,版本号必须可以用 kubectl api-resources 查询到
metadata <Object> 元数据,主要是资源标识和说明,常用的有 name、namespace、labels 等
spec <Obiect> 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述
status <0bject>状态信息,里面的内容不需要定义,由kubernetes 自动生成
(2)spec(规格)属性
在一级属性中,spec是研究的重点,它的常见子属性有:
containers <[ ]0bject> 容器列表,用于定义容器的详细信息
nodeName <string> 根据 nodeName 的值将 pod 调度到指定的 Node 节点上
nodeselector <map[ ]> 根据NodeSelector中定义的信息选择将该Pod调度到包含这些label
的 Node 上
hostNetwork <boolean> 是否使用主机网络模式,默认为 false,如果设置为 true,表示使用宿主机网络
volumes <[ ]0bject> 存储卷,用于定义 Pod 上面挂在的存储信息
restartPolicy <string>重启策略,表示 Pod 在遇到故障的时候的处理策略
(3)通过kubectl explain命令来查看每种资源的可配置项
kubectl explain pod
kubectl explain deployment
kubectl explain service
kubectl explain pod.metadata
kubectl explain pod.spec.containers
运行kubectl create命令创建此pod

删除pod
kubectl describe pod redis-php
kubectl delete -f frontend-localredis-pod.yaml
Pod的基本用法
编写pod文件,将两个容器放到同一个pod中

部署nginx的pod文件

暴露端口

查看端口映射
访问测试
删除pod

静态pod
静态 Pod 是由 kubelet 进行管理的仅存在于各个 Node 上的 Pod。他们不能通过 API Server 进行管理,无法于 Replicationcontroller、Deployment 或者 DaemonSet 进行关联,并且 kubelet 无法对他们进行健康检査。静态 Pod 总是由 kubelet 创建的,并且总在 kubelet 所在的 Node 上运行。

删除pod

备注:
不能用如下语句删除
kubectl delete pod static-web-k8s-master01这样删除,会让 pod 处于 pending 状态,但无法删除
pod 的启动过程包含的步骤
Pod 的启动过程是 Kubernetes 中一个关键的操作,涉及多个步骤和组件协同工作。以下是 Pod 启动的主要过程:
(1)用户提交 Pod 定义
用户通过 kubect1 或其他工具提交 Pod 的 YAML 或 JSON 定义文件到 Kubernetes API Server。
(2)API Server 接收请求
API Server 接收到 Pod 创建请求后,会进行身份验证和授权检査,确保请求合法。
通过检査后,API Server 将 Pod 的定义信息存储到 etcd 中。
(3)Scheduler 调度 Pod
Scheduler 监控 API Server,发现有待调度的 Pod。
Scheduler 根据 Pod 的资源需求、节点亲和性、污点容忍等策略,选择一个合适的节点。
Scheduler 将 Pod 与节点绑定,并将绑定信息更新到 etcd。
(4)kubelet 创建 Pod
目标节点上的 kubelet 监控 API Server,发现有新的 Pod 被调度到本节点。kubelet 根据 Pod 定义,调用容器运行时(如 Docker、containerd)创建容器kubelet 还会为 Pod 设置网络(通过 CNI 插件)和存储卷(如 emptyDir、hostPath 或持久卷)。
(5)容器运行时启动容器
容器运行时根据 kubelet 的指令,拉取镜像(如果本地没有)并启动容器。
容器启动后,运行时向 kubelet 报告容器状态。
(6)kubelet 更新 Pod 状态
kubelet 监控容器的运行状态,并将 Pod 的状态更新到 API Server。
API Server 将状态信息存储到 etcd。
(7)Pod 进入运行状态
当所有容器成功启动并运行后,Pod进入Running 状态如果容器启动失败,kubelet 会根据重启策略(如 Always、0nFailure)决定是否重启容器。
(8)探针检查(可选)
如果 Pod 定义了存活探针(Liveness Probe)或就绪探针(Readiness Probe),kubelet 会定期执行这些探针。
探针检查失败可能导致容器重启或Pod 从服务端点移除。
(9)Pod 可用
当 Pod 的所有容器正常运行并通过就绪探针检査后,Pod 被视为可用,可以接收流量或执行任务。
(10)持续监控
kubelet 持续监控 Pod 的状态,确保其健康运行。如果 Pod 或容器出现问题,kubelet 会根据配置采取相应措施(如重启容器)
Pod 的运行状态
(1)Pending
表示 APIServer 创建了 Pod 资源对象并已经存入了 etcd 中,但是它并未被调度完成(比如还没有调度到某台 node 上),或者仍然处于从仓库下载镜像的过程中
(2)Running
Pod 已经被调度到某节点之上,并且 Pod 中所有容器都已经被 kubelet 创建。至少有一个容器正在运行,或者正处于启动或者重启状态(也就是说 Running 状态下的 Pod 不一定能被正常访问)
(3)succeeded
有些 pod 不是长久运行的,比如 job、cronjob,一段时间后 Pod 中的所有容器都被成功终止,并且不会再重启。需要反馈任务执行的结果
(4)Failed
Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非。状态退出或者被系统终止,比如command 写的有问题
(5)Unknown
表示无法读取 Pod 状态,通常是 kube-controller-manager 无法与 Pod 通信
故障排除步骤
当一个 Pod 无法正常启动时,可能是由于多种原因导致的。以下是故障排除的详细步骤,帮助你定位和解决问题。
1.查看 Pod 事状态
kubectl logs <pod-name>-n <namespace>
2.查看 Pod 日志(Failed 状态下)
kubectl logs <pod-name>-n <namespace>
如果 Pod 中有多个容器,使用-c指定容器名称:
kubectl logs <pod-name>-n <namespace>-c <container-name>
如果容器不断重启,可以查看上一次崩溃的日志:
kubectl logs<pod-name>-n<namespace> --previous
3.Pod 处于 Pending 状态
可能原因:
资源不足(CPU、内存)
没有可用节点满足调度条件(如节点亲和性、污点容忍)。
持久卷声明(PVC)未绑定
排查方法:
检査节点资源:kubectl describe node <node-name>
检查 PVC 状态:kubectl get pvc -n <namespace>
查看调度器日志(如果启用了调度器日志)。
检查节点资源是否充足(CPU、内存)。
检査节点是否有污点(Taint)导致 Pod 无法调度。
检查节点是否处于 NotReady 状态。
4.Pod 处于 ImagePullBackoff 状态
可能原因:
镜像名称错误或镜像不存在,
私有镜像未配置正确的镜像拉取密钥(imagePullsecrets)
镜像仓库不可访问(网络问题或认证失败)。
排查方法:
检查镜像名称和标签是否正确。
确保 imagePullsecrets 配置正确。
手动尝试拉取镜像:docker pull <image-name>。
5.Pod 处于 crashLoopBackoff 状态
可能原因:
容器启动后立即崩溃(应用程序错误、配置错误)
资源限制过低(如内存不足导致 OOM)
依赖服务未就绪。
排查方法:
查看容器日志
检查资源限制:kubectl describe pod <pod-name> -n <namespace>
检查应用程序配置和依赖服务。
6.Pod 处于 ErrImagePull 状态
可能原因:
镜像拉取失败(镜像不存在或权限问题)
排查方法:
检查镜像名称和权限
确保镜像仓库可访问
7.Pod 处于 containercreating 状态
可能原因:
容器正在创建,但耗时较长。
可能由于网络问题(如CNI 插件未正确配置)或存储卷未准备好。
排查方法:
检查节点网络和CNI 插件状态
检查存储卷(PVC)是否已绑定。
8:检查网络和存储
网络问题:
检查CNI 插件是否正常运行。
检査 Pod 的 DNS 配置是否正确。
存储问题:
检査 PVC 是否已绑定:kubectl get pvc -n <namespace>
检查存储类(storageclass)配置是否正确。
9.检查资源限制
确保资源请求不超过节点可用资源。如果资源限制过低,可能导致容器崩溃(如 OOM)如果 Pod 因资源不足无法启动,检查资源请求和限制:
resources:
requests :
memory: "64Mi"
cpu: "250m'
limits:
memory:"128Mi"
cpu:"500m"
通过以上步骤,可以逐步定位 Pod 无法启动的原因。常见问题包括镜像拉取失败、资源不足、配置错误、网络或存储问题等。根据具体错误信息,结合日志和事件描述,可以快速解决问题。