1.什么是Pod?

Pod是在Kubernetes系统中创建、调度和管理的最小单位。其他的大多数资源对象都是用于支撑和扩展Pod对象功能的,例如:

  • 用于管控Pod运行的StatefulSetDeployment等控制器对象,
  • 用于暴露Pod应用的ServiceIngress对象。
  • Pod提供存储的PersistentVolume存储资源对象。

2. Pod基本操作

2.1 创建

# nginx.pod 为资源配置清单
$ kubectl apply -f nginx-pod.yaml

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>

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

2.4 删除

$ kubectl delete pod test-nginx-pod
pod "test-nginx-pod" deleted

3. Pod生命周期

3.1 周期示意图

Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期,典型的Pod生命周期是这样的:

  1. 用户定义一个YAML格式的清单文件,并将其POSTAPI Server。一旦发送成功,清单文件中的内容就被作为一条意图记录(a record of intent)——即“期望状态”(desired )——持久化记录在集群存储中,
  2. 然后Pod被调度到一个健康的、有充足资源的节点上。一旦完成调度,就会进入等待状态(pending ),此时节点会下载镜像并启动容器。
  3. 在所有资源就绪前,Pod的状态都保持在等待状态。一切就绪后,Pod进入运行状态(running )。
  4. 在完成所有任务后,会停止并进入成功状态(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创建过程

PodKubernetes的基础单元,理解它的创建过程对于了解系统运作大有裨益。下图描述了一个Pod资源对象的典型创建过程。

Pod创建过程

创建流程描述:

  1. 用户通过kubectl或其他API客户端提交Pod SpecAPI Server
  2. API Server尝试着将Pod对象的相关信息存入etcd中,待写入操作执行完成,API Server即会返回确认信息至客户端。
  3. API Server开始反映etcd中的状态变化。
  4. 所有的Kubernetes组件均使用watch机制来跟踪检查API Server上的相关的变动。
  5. kube-scheduler(调度器)通过其watcher觉察到API Server创建了新的Pod对象但尚未绑定至任何工作节点。
  6. kube-schedulerPod对象挑选一个工作节点并将结果信息更新至API Server
  7. 调度结果信息由API Server更新至etcd存储系统,而且API Server也开始反映此Pod对象的调度结果。
  8. Pod所在工作节点上的kubelet尝试在调用Docker启动容器,并将容器的结果状态回送至API Server
  9. API ServerPod状态信息存入etcd系统中。
  10. etcd确认写入操作成功完成后,API Server将确认信息发送至相关的kubelet,事件将通过它被接受。

4.2 Pod的终止过程

Pod对象代表了在Kubernetes集群节点上运行的进程,它可能曾用于处理生产数据或向用户提供服务等,当Pod本身不再具有存在的价值时,如何将其优雅地终止呢?

Pod终止过程

终止流程描述:

  1. 用户发送删除Pod对象的命令。

  2. API Server中的Pod对象会随着时间的推移而更新,在宽限期内(默认为30秒)Pod被视为dead

  3. Pod标记为Terminating状态。

    • kubelet在监控到Pod对象转为Terminating状态的同时,启动Pod关闭过程。

    • 端点控制器监控到Pod对象的关闭行为时,将其从所有匹配到此端点的Service资源的端点列表中移除。

  4. 如果当前Pod对象定义了preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行;如若宽限期结束后,preStop仍未执行结束,则第2步会被重新执行并额外获取一个时长为2秒的小宽限期。

  5. Pod对象中的容器进程收到TERM信号。

  6. 宽限期结束后,若存在任何一个仍在运行的进程,那么Pod对象即会收到SIGKILL信号。

  7. 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的重启策略
    ....

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对象将永远不会被重新绑定到另一个节点,它要么被重启,要么终止,直到节点发生故障或被删除。