Kubernetes的基本调度单元称为Pod,一个Pod包含一个或多个容器,这样可以保证同一个Pod内的容器运行在同一个宿主机上,并且可以共享资源,这些容器使用相同的网络命名空间、IP地址和端口。Kubernetes中的每个Pod都被分配一个唯一的IP地址,这样就可以允许应用程序使用端口而不会有冲突的风险。

1. pod使用

1.1 pod配置清单详解

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#获取镜像的策略
    command: [string]    #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]     #容器的启动命令参数列表
    workingDir: string     #容器的工作目录
    volumeMounts:    #挂载到容器内部的存储卷配置
     - name: string     #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
       mountPath: string    #存储卷在容器内mount的绝对路径,应少于512字符
       readOnly: boolean    #是否为只读模式
    ports:       #需要暴露的端口库号列表
     - name: string     #端口号名称
       containerPort: int   #容器需要监听的端口号
       hostPort: int    #容器所在主机需要监听的端口号,默认与Container相同
       protocol: string     #端口协议,支持TCP和UDP,默认TCP
    env:       #容器运行前需设置的环境变量列表
     - name: string     #环境变量名称
       value: string    #环境变量的值
     resources:       #资源限制和请求的设置
       limits:   #资源限制的设置
         cpu: string  #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
         memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
       requests:   #资源请求的设置
         cpu: string    #Cpu请求,容器启动的初始可用数量
         memory: string     #内存清楚,容器启动的初始可用数量
    livenessProbe:     #容器存活检测,方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种即可
      exec:      #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0  #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0   #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0 #处于失败状态时,探测操作至少连续多少次的成功才被认为是通过检测
       failureThreshold: 0 #处于成功状态时,探测操作至少连续多少次的失败才被视为是检测不通过
       securityContext:
         privileged:false
    restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
    nodeSelector: obeject  #表示将该Pod调度到包含这个label的node上,以key:value的格式指定
    imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
     - name: string
     hostNetwork:false  #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:  #在该pod上定义共享存储卷列表
     - name: string  #共享存储卷名称 (volumes类型有很多种)
       emptyDir: {}   #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
       hostPath: string     #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
         path: string     #Pod所在宿主机的目录,将被用于同期中mount的目录
       secret:      #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
         scretname: string  
         items:     
         - key: string
           path: string
       configMap:     #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
         name: string
         items:
         - key: string
           path: string

imagePullPolicy(镜像获取策略)

容器的imagePullPolicy字段用于为其指定镜像获取策略,它的可用值包括如下几个:

  • Always: 镜像标签为latest或镜像不存在时总是从指定的仓库中获取镜像。
  • Never: 禁止从仓库下载镜像,即仅使用本地镜像。
  • ‰IfNotPresent: 仅当本地镜像缺失时方从目标仓库下载镜像

livenessProbe(存活性检测)

容器探测(container probe)是Pod对象生命周期中的一项重要的日常任务,它是kubelet对容器周期性执行的健康状态诊断,诊断操作由容器的处理器(handler)进行定义。Kubernetes支持三种处理器用于Pod探测。分别如下:

  • ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断的操作称为Exec探测,状态码为0表示成功,否则即为不健康状态。‰
  • TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正常,否则为不健康状态。‰
  • HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起HTTP GET请求进行诊断,响应码为2xx或3xx时即为成功,否则为失败。

任何一种探测方式都可能存在三种结果:Success(成功)Failure(失败)Unknown(未知),只有第一种结果表示成功通过检测。

kubelet可在活动容器上执行两种类型的检测:存活性检测(livenessProbe)和就绪性检测(readinessProbe)

  • 存活性检测:用于判定容器是否处于运行(Running)状态;一旦此类检测未通过,kubelet将杀死容器并根据其restartPolicy决定是否将其重启;未定义存活性检测的容器的默认状态为Success
  • 就绪性检测:用于判断容器是否准备就绪并可对外提供服务;未通过检测的容器意味着其尚未准备就绪,端点控制器(如Service对象)会将其IP从所有匹配到此Pod对象的Service对象的端点列表中移除;检测通过之后,会再次将其IP添加至端点列表中。

livenessProbe 相关配置

...
    livenessProbe:  #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
      exec:      #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0  #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0   #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged:false
...

restartPolicy(Pod的重启策略)

  • Always: 表示一旦不管以何种方式终止运行,kubelet都将重启。
  • OnFailure: 表示只有Pod以非0退出码退出才重启。
  • Nerver:表示不再重启该Pod

需要注意的是,restartPolicy适用于Pod对象中的所有容器,而且它仅用于控制在同一节点上重新启动Pod对象的相关容器。首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长依次为10秒、20秒、40秒、80秒、160秒和300秒,300秒是最大延迟时长。事实上,一旦绑定到一个节点,Pod对象将永远不会被重新绑定到另一个节点,它要么被重启,要么终止,直到节点发生故障或被删除。

1.2 创建pod (基于配置清单)

使用kubectl create命令创建Pod前,需要先定义一个文件 test-nginx.yaml

1.2.1 定义配置清单文件

test-nginx.yaml

apiVersion: v1
kind: Pod
metadata:
name: test-nginx-pod
spec:
containers:
- name: test-containers
image: nginx
ports:
- name: test-nginx
containerPort: 80

1.2 创建

[root@master pods]# kubectl create -f test-nginx.yaml
pod/test-nginx-pod created

1.3 查询

最常用的查询命令是kubectl get,可以查询一个到多个Pod信息,查询指定的Pod命令如下:

[root@master pods]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test-nginx-pod 1/1 Running 0 29s

查询显示字段说明:

  • NAME:指Pod名称。
  • READY:显示Pod中的容器信息,/右边的数字表示Pod包含的容器总数目,/左边的数字表示准备就绪的容器数目。
  • STATUS:显示Pod的当前状态。
  • RESTARTS: Pod的重启次数。
  • AGE: Pod的运行时间。

1.4 删除

[root@master kubernetes]# kubectl delete pod test-nginx-pod
pod "test-nginx-pod" deleted

2. Pod生命周期

Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期。在这段时间中,Pod会处于多种不同的状态,并执行一些操作;其中,创建主容器(main container)为必需的操作,其他可选的操作还包括运行初始化容器(init container)、容器启动后钩子(post start hook)、容器的存活性探测(liveness probe)、就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等,这些操作是否执行则取决于Pod的定义。

pod-live

Pod的生命周期图

2.1 Pod生命进程相位

Pod对象总是应该处于其生命进程中以下几个相位之一。

  • Pending :API Server创建了Pod资源对象并已存入etcd中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中。‰
  • Running:Pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成。‰
  • Succeeded:Pod中的所有容器都已经成功终止并且不会被重启。‰
  • Failed :所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态或已经被系统终止。‰
  • Unknown:API Server无法正常获取到Pod对象的状态信息,通常是由于其无法与所在工作节点的kubelet通信所致

Pod的相位是在其生命周期中的宏观概述,而非对容器或Pod对象的综合汇总,而且相位的数量和含义被严格界定,它仅包含上面列举的相位值。

2.2 Pod的创建过程

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

pod-create-process

Pod资源对象创建过程

2.1.1 创建过程描述

  1. 用户通过kubectl或其他API客户端提交Pod Spec给API 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-scheduler为Pod对象挑选一个工作节点并将结果信息更新至API Server。
  7. 调度结果信息由API Server更新至etcd存储系统,而且API Server也开始反映此Pod对象的调度结果。
  8. Pod被调度到的目标工作节点上的kubelet尝试在当前节点上调用Docker启动容器,并将容器的结果状态回送至API Server。
  9. API Server将Pod状态信息存入etcd系统中。
  10. 在etcd确认写入操作成功完成后,API Server将确认信息发送至相关的kubelet,事件将通过它被接受。

2.3 Pod的终止过程

Pod对象终止流程具体如下:

pod-del-process

2.3.1 终止过程描述

  1. 用户发送删除Pod对象的命令。
  2. API服务器中的Pod对象会随着时间的推移而更新,在宽限期内(默认为30秒),Pod被视为dead
  3. 将Pod标记为Terminating状态。
  4. (与第3步同时运行) kubelet在监控到Pod对象转为Terminating状态的同时启动Pod关闭过程。
  5. (与第3步同时运行)端点控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的Service资源的端点列表中移除。
  6. 如果当前Pod对象定义了preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行;如若宽限期结束后,preStop仍未执行结束,则第2步会被重新执行并额外获取一个时长为2秒的小宽限期。
  7. Pod对象中的容器进程收到TERM信号。
  8. 宽限期结束后,若存在任何一个仍在运行的进程,那么Pod对象即会收到SIGKILL信号。
  9. Kubelet请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,它变得对用户不再可见。

默认情况下,所有删除操作的宽限期都是30秒,不过,kubectl delete命令可以使用--grace-period=<seconds>选项自定义其时长,若使用0值则表示直接强制删除指定的资源,不过,此时需要同时为命令使用--force选项。