​Pod是k8s系统的基础单元,是资源对象模型中可由用户创建或部署的最小组件,也是在k8s系统上运行容器化应用的资源对象

pod对象自从创建开始至终止退出的时间范围称为生命周期,Pod中主容器运行之间会运行一系列的pod来保证主容器可正常运行,创建主容器为必须的操作,其他可选的操作还包括运行初始化容器(init container)、容器启动后钩子(start hook)、容器的存活性探测(liveness probe)、就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等,这些操作是否执行则取决于pod的定义

一、生命周期中,Pod会出现5种状态(相位)

  • 挂起(Pending):apiserver已经创建了pod资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中。

  • 运行中(Running):pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成。

  • 成功(Succeeded):pod中的所有容器都已经成功终止并且不会被重启。

  • 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态。

  • 未知(Unknown):apiserver无法正常获取到pod对象的状态信息,通常由网络通信失败所导致。

二、Pod的创建和终止

Pod创建过程

①用户通过kubectl或其他api客户端提交需要创建的pod信息给apiServer。

②apiServer开始生成pod对象的信息,并将信息存入etcd,然后返回确认信息至客户端。

③apiServer开始反映etcd中的pod对象的变化,其它组件使用watch机制来跟踪检查apiServer上的变动。

④scheduler发现有新的pod对象要创建,开始为Pod分配主机并将结果信息更新至apiServer。

⑤调度结果信息由api server更新至etcd,而且api server也开始反映此pod对象的调度结果

⑥node节点上的kubelet发现有pod调度过来,尝试调用docker启动容器,并将结果回送至apiServer。

⑦apiServer将接收到的pod状态信息存入etcd中,etcd确认写入操作成功完成后,api server将确认信息发送至相关的kubelet

Pod终止过程

①用户向apiServer发送删除pod对象的命令。

②apiServcer中的pod对象信息会随着时间的推移而更新,在宽限期内(默认30s),pod被视为dead。

③将pod标记为terminating状态。

④kubelet在监控到pod对象转为terminating状态的同时启动pod关闭过程。

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

⑥如果当前pod对象定义了preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行。

⑦pod对象中的容器进程收到停止信号。

⑧宽限期结束后,若pod中还存在仍在运行的进程,那么pod对象会收到立即终止的信号。

⑨kubelet请求apiServer将此pod资源的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见。

三、Pod生命周期中的重要行为

除了创建应用容器之外,用户还可以为pod对象定义其生命周期中的多种行为,如初始化容器、存活性探测及就绪性探测等

1、初始化容器

初始化容器即应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作:

①初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么k8s需要重启它直到成功完成

②初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能运行

初始化容器有很多的应用场景,下面列出的是最常见的几个:

①提供主容器镜像中不具备的工具程序或自定义代码

②初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足

2、生命周期钩子函数

钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。

kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:

①post start:容器创建之后执行,如果失败了会重启容器

②pre stop :容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作

 poststart-nginx实例:

apiVersion: v1
kind: Pod
metadata:
  name: poststart-nginx
  namespace: default
spec:  containers:
  - name: poststart-nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    lifecycle:
       postStart:
         exec:
           command: ["/bin/sh","-c","echo home >> /usr/share/nginx/html/index.html"]
    ports:
    - name: http
      containerPort: 80[root@k8s-master01]# kubectl apply -f poststart-pod.yaml 
pod/poststart-nginx created
[root@k8s-master01]# kubectl get pods  -o wideNAME
READY         STATUS RESTARTS AGE  IP           NODE
poststart-nginx 1/1 Running 0 11s 172.18.58.217 k8s-node02
[root@k8s-master01]# curl 172.18.58.217
home     

钩子处理器支持使用下面三种方式定义动作:

①Exec命令:在容器内执行一次命令

  lifecycle:
    postStart: 
      exec:
        command:
        - cat
        - /tmp/healthy

②TCPSocket:在当前容器尝试访问指定的socket

  lifecycle:
    postStart:
      tcpSocket:
        port: 8080

③HTTPGet:在当前容器中向某url发起http请求

 lifecycle:
    postStart:
      httpGet:
        path: / #URI地址
        port: 80 #端口号
        host: 192.168.109.100 #主机地址
        scheme: HTTP #支持的协议,http或者https

3、容器探针

容器探测时pod对象生命周期中的一项重要的日常任务,它是kubelet对容器周期性执行的健康状态诊断,诊断操作由容器的处理器进行定义。k8s支持三种容器探针用于pod探测:

ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断的操作称为Exec探测,状态码为0表示成功,否则即为不健康状态

TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正 常,否则为不健康状。

HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起HTTP GET请求进行诊断,响应 码大于等于200且小于400时即为成功

Kubelet可在活动容器上执行两种类型的检测:

(livenessProbe)存活性检测:用于判定容器是否处于运行状态,一旦此类检测未通过,kubelet将杀死容器并根据restartPolicy决定是否将其重启;未定义存活性检测的容器的默认状态未success

(readinessProbe)就绪性检测:用于判断容器是否准备就绪并可对外提供服务;未通过检测的容器意味着尚未准备就绪,端点控制器会将其IP从所有匹配到此pod对象的service对象的端点列表中移除;检测通过之后,会再次将其IP添加至端点列表中。

livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器

探针目前均支持三种探测方式:

①Exec命令:在容器内执行一次命令,如果命令执行的退出码为0,则认为程序正常,否则不正常

 livenessProbe:
    exec:
      command:
      - cat
      - /tmp/healthy

②TCPSocket:将会尝试访问一个用户容器的端口,如果能够建立这条连接,则认为程序正常,否则不正常

  livenessProbe:
    tcpSocket:
      port: 8080

③HTTPGet:调用容器内Web应用的URL,如果返回的状态码在200和399之间,则认为程序正常,否则不正常

  livenessProbe:
    httpGet:
      path: / #URI地址
      port: 80 #端口号
      host: 127.0.0.1 #主机地址
      scheme: HTTP #支持的协议,http或者https

liveness-exec实例:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-container
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox:latest
    imagePullPolicy: IfNotPresent  #本地没有就下载
    command: ["/bin/sh","-c","touch /tmp/healthy;sleep 30;rm -rf /tmp/healthy;sleep 3600"]
    livenessProbe:
       exec:
         command: ["test","-e","/tmp/healthy"]    #检测文件是否存在,判断存活
       initialDelaySeconds: 1    #开始探测的时间
       periodSeconds: 3          #探测时间间隔

readinness-httpget实例:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-container
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: nginx:latest
    imagePullPolicy: IfNotPresent  #本地没有就下载
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
       httpGet:
         port: http
         path: /index.html
       initialDelaySeconds: 1    #开始探测的时间
       periodSeconds: 3          #探测时间间隔

四、容器的重启

容器程序发生崩溃或容器申请超出限制的资源等原因都可能会导致pod对象的终止,此时是否应该重建该pod对象则取决于其重启策略(restartPolicy)属性的定义:

  • Always:但凡pod对象终止就将其重启,此为默认设定

  • OnFailure:只在pod对象出现错误时方才将其重启

  • Never:从不重启

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

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐