深入了解Pod
Salted Fish 1991/6/26 基础
# 1.什么是Pod
Pod是在Kubernetes系统中创建、调度和管理的最小单位。其他的大多数资源对象都是用于支撑和扩展Pod对象功能的,例如:
- 用于管控
Pod运行的StatefulSet和Deployment等控制器对象, - 用于暴露
Pod应用的Service和Ingress对象。 - 为
Pod提供存储的PersistentVolume存储资源对象。
# 2. Pod基本操作
# 2.1 创建
# nginx.pod 为资源配置清单
$ kubectl apply -f nginx-pod.yaml
1
2
2
# 2.2 查询
# 基本信息查询
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
test-nginx-pod 0/1 ContainerCreating 0 2s
# 查询更多信息 -o wide
[root@master k8s]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-nginx-pod 1/1 Running 0 52s 10.244.104.25 node2 <none> <none>
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 2.3 更多详情
$ kubectl describe pod test-nginx-pod
Name: test-nginx-pod
Namespace: default
Priority: 0
Node: node2/192.168.148.132
Start Time: Thu, 11 Aug 2022 18:28:19 +0800
Labels: <none>
Annotations: cni.projectcalico.org/containerID: 2840f0d0c113552022c24fd5b350c7f61d874f6fde75a8d6431e6a3317a4f832
cni.projectcalico.org/podIP: 10.244.104.25/32
cni.projectcalico.org/podIPs: 10.244.104.25/32
Status: Running
IP: 10.244.104.25
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 104s default-scheduler Successfully assigned default/test-nginx-pod to node2
Normal Pulling 103s kubelet Pulling image "nginx"
Normal Pulled 101s kubelet Successfully pulled image "nginx" in 2.268676575s
Normal Created 101s kubelet Created container test-containers
Normal Started 101s kubelet Started container test-containers
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2.4 删除
$ kubectl delete pod test-nginx-pod
pod "test-nginx-pod" deleted
1
2
2
# 3. Pod生命周期
# 3.1 周期示意图
Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期,典型的Pod生命周期是这样的:

- 用户定义一个
YAML格式的清单文件,并将其POST到API Server。一旦发送成功,清单文件中的内容就被作为一条意图记录(a record of intent)——即“期望状态”(desired)——持久化记录在集群存储中, - 然后
Pod被调度到一个健康的、有充足资源的节点上。一旦完成调度,就会进入等待状态(pending),此时节点会下载镜像并启动容器。 - 在所有资源就绪前,
Pod的状态都保持在等待状态。一切就绪后,Pod进入运行状态(running)。 - 在完成所有任务后,会停止并进入成功状态(
succeeded)。
# 3.2 状态说明
Pending(等待):API Server创建了Pod资源对象并已存入etcd中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中。Running(运行):Pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成。Succeeded(成功):Pod中的所有容器都已经成功终止并且不会被重启。Failed(失败): 所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态或已经被系统终止。Unknown(未知):API Server无法正常获取到Pod对象的状态信息,通常是由于其无法与所在工作节点的kubelet通信所致。
# 4. Pod创建和终止
# 4.1 Pod创建过程
Pod是Kubernetes的基础单元,理解它的创建过程对于了解系统运作大有裨益。下图描述了一个Pod资源对象的典型创建过程。

创建流程描述:
- 用户通过
kubectl或其他API客户端提交Pod Spec给API Server。 API Server尝试着将Pod对象的相关信息存入etcd中,待写入操作执行完成,API Server即会返回确认信息至客户端。API Server开始反映etcd中的状态变化。- 所有的
Kubernetes组件均使用watch机制来跟踪检查API Server上的相关的变动。 kube-scheduler(调度器)通过其watcher觉察到API Server创建了新的Pod对象但尚未绑定至任何工作节点。kube-scheduler为Pod对象挑选一个工作节点并将结果信息更新至API Server。- 调度结果信息由
API Server更新至etcd存储系统,而且API Server也开始反映此Pod对象的调度结果。 Pod所在工作节点上的kubelet尝试在调用Docker启动容器,并将容器的结果状态回送至API Server。API Server将Pod状态信息存入etcd系统中。- 在
etcd确认写入操作成功完成后,API Server将确认信息发送至相关的kubelet,事件将通过它被接受。
# 4.2 Pod的终止过程
Pod对象代表了在Kubernetes集群节点上运行的进程,它可能曾用于处理生产数据或向用户提供服务等,当Pod本身不再具有存在的价值时,如何将其优雅地终止呢?

终止流程描述:
- 用户发送删除
Pod对象的命令。 API Server中的Pod对象会随着时间的推移而更新,在宽限期内(默认为30秒)Pod被视为dead。- 将
Pod标记为Terminating状态。kubelet在监控到Pod对象转为Terminating状态的同时,启动Pod关闭过程。- 端点控制器监控到
Pod对象的关闭行为时,将其从所有匹配到此端点的Service资源的端点列表中移除。
- 如果当前
Pod对象定义了preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行;如若宽限期结束后,preStop仍未执行结束,则第2步会被重新执行并额外获取一个时长为2秒的小宽限期。 Pod对象中的容器进程收到TERM信号。- 宽限期结束后,若存在任何一个仍在运行的进程,那么
Pod对象即会收到SIGKILL信号。 Kubelet请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,它变得对用户不再可见。
默认情况下,所有删除操作的宽限期都是30秒,不过,
kubectl delete命令可以使用--grace-period=<seconds>选项自定义其时长,若使用0值则表示直接强制删除指定的资源,不过,此时需要同时为命令使用--force选项。
# 5. Pod主要配置说明
虽然配置清单(yaml)中的字段有很多,但并不是所有的都要写,循序渐进,慢慢熟悉~
# 5.1 配置清单
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #必选,Pod所属的命名空间
labels: #自定义标签
- name: string #自定义标签名字
annotations: #自定义注释列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略
ports: #需要暴露的端口库号列表
- name: string #端口号名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
....
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 5.2 imagePullPolicy(镜像获取策略)
容器的imagePullPolicy字段用于为其指定镜像获取策略,它的可用值包括如下几个:
Always: 镜像标签为latest或镜像不存在时总是从指定的仓库中获取镜像。Never: 禁止从仓库下载镜像,即仅使用本地镜像。IfNotPresent: 仅当本地镜像缺失时,才从目标仓库下载镜像
# 5.3 restartPolicy(Pod的重启策略)
Always: 表示容器失效时,由kubelet自动重启该容器。OnFailure: 表示容器终止运行且退出码不为0时,由kubelet自动重启该容器。Nerver:表示不论容器运行状态如何,kubelet都不会重启该容器。
需要注意的是,
restartPolicy适用于Pod对象中的所有容器,而且它仅用于控制在同一节点上重新启动Pod对象的相关容器。首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长依次为10秒、20秒、40秒、80秒、160秒和300秒,300秒是最大延迟时长。事实上,一旦绑定到一个节点,Pod对象将永远不会被重新绑定到另一个节点,它要么被重启,要么终止,直到节点发生故障或被删除。