您现在的位置是:首页 >技术杂谈 >Pod生命周期网站首页技术杂谈

Pod生命周期

Rkun18 2024-07-02 00:01:02
简介Pod生命周期

Pod生命周期

  • Pod创建过程
  • 运行初始化容器过程
  • 运行主容器过程
    • 容器启动后钩子,容器终止前钩子
    • 容器存活性,就绪性探测
  • Pod终止过程

在这里插入图片描述

在整个Pod生命周期,会出现5中状态:

取值描述
Pending(悬决)Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
Running(运行中)Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded(成功)Pod 中的所有容器都已成功终止,并且不会再重启。
Failed(失败)Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown(未知)因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

创建和终止

创建

  1. 用户通过kubectl或其他api客户端提交创建pod信息给apiserver
  2. apiserver生产pod对象信息,并存入etcd,然后返回确认信息至客户端
  3. apiserver反应ectd中pod对象变化,其他组件使用watch机制跟踪apiserver
  4. scheduler发现有新的pod对象要创建,开始为pod分配主机并将结果信息更新至apiserver
  5. node节点上kebelet发现有pod调度过来,尝试使用docker启动容器,并将结果送到apiserver
  6. apiserver将接收到的pod信息存入etcd中

终止

  1. 用户向apiserver发出删除pod命令
  2. apiserver中的pod信息会变化,在宽限期(30s),pod被视为dead
  3. pod标记为terminating标记
  4. kubelet监控到pod对象转为terminating状态同时启动pod关闭过程
  5. 端点控制器监控到pod对象的关闭行为时将其从所以匹配到此端点的service资源的端点列表一处
  6. 如果当前pod对象定义了preStop钩子处理器,则在其标记terminating后会以同步的方式启动
  7. pod中容器进程收到停止信号
  8. 宽限期结束,若pod还存在仍在运行的进程,pod对象会受到立即终止信号
  9. kubelet将pod资源宽限期设置为0从而完成操作,此时pod对于用户已经可不见

初始化容器

初始化容器在Pod的主容器启动之前要运行的容器。(完成主容器前置工作)

  • 初始化容器必须运行完成至结束,否则k8s需要重启它直至成功
  • 必须按照定义的顺序执行

初始化容器场景:

  • 提供主容器镜像中不具备的工具程序或自定义代码
  • 初始化容器要咸鱼应用容器串行启动并运行完成,可用于容器启动直至其依赖的条件得到满足(感觉有点类似于docker拉取镜像,如果镜像依赖于其他服务,就先拉取其他镜像资源,一层一层叠加)

案例

  • 需要主容器运行nginx

  • 运行nginx前需要nginx先连接上mysql和redis所在服务器

  • 提前规定服务器地址

    • mysql:192.168.126.129

    • redis: 192.168.126.130

创建pod-initcontainer.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-initcontainer
  namespace: dev
spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports: 
    - name: nginx-port
      containerPort: 80
  initContainers:
  - name: test-mysql
    image: busybox:1.30
    command: ['sh', '-c', 'until ping 192.168.126.129 -c 1 ; do echo waiting for mysql...; sleep 2; done;']  #直到ping通才停止
  - name: test-redis
    image: busybox:1.30
    command: ['sh', '-c', 'until ping 192.168.126.130 -c 1 ; do echo waiting for reids...; sleep 2; done;']

我这两个服务器IP地址有效,可以ping通:

[root@master ~]# cd  mine/
[root@master mine]# vim pod-initcontainer.yaml
[root@master mine]# kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created
[root@master mine]# kubectl get pod -n dev
NAME                READY   STATUS    RESTARTS   AGE
pod-initcontainer   1/1     Running   0          16s

可以尝试切换无法到达的IP进行尝试,主容器应该无法创建

钩子函数

允许用户自己定义行为代码,完成一些指定的功能

钩子函数支持三种方式定义动作:

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

    ……
      lifecycle:
        postStart: 
          exec:
            command:
            - cat
            - /tmp/healthy  #查看/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
    ……
    

新建一个pod-hook-exec.yaml:

apiVersion: v1
kind: Pod
metadata:
  name: pod-hook-exec
  namespace: dev
spec:
  containers:
  - name: main-container
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    lifecycle:
      postStart: 
        exec: # 在容器启动的时候执行一个命令,修改掉nginx的默认首页内容
          command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
      preStop:
        exec: # 在容器停止之前停止nginx服务
          command: ["/usr/sbin/nginx","-s","quit"]
[root@master mine]# kubectl create -f pod-hook-exec.yaml
pod/pod-hook-exec created
[root@master mine]# kubectl get pod -n dev -o wide
NAME            READY   STATUS    RESTARTS   AGE   IP           NODE    NOMINATED NODE   READINESS GATES
pod-hook-exec   1/1     Running   0          39s   10.244.2.8   node2   <none>           <none>
[root@master mine]# curl 10.244.2.8:80
postStart...

容器探测

用于检测容器中应用实例能否正常运行,如果实例状态不符合预期,那么k8s就会把问题实例摘除,不承担业务流量,k8s提供两种探针实现:

  • liveness probes:存活性探针,检测应用实例是否处于正常状态,若不是k8s会重启实例

  • readlness probes:就绪性探针,用于检测应用实例是否可以接受请求,如果不能,k8s不会转发流量

    三种探测方式:

    • 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
      ……
      

以livenessProbe为例,新建

新建test1.yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-exec
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["/bin/cat","/tmp/hello.txt"] # 执行一个查看文件的命令

默认情况下没有这个文件,所以它会重启容器

#创建Pod
[root@master mine]# vim test1.yaml
[root@master mine]# kubectl create -f test1.yaml
pod/pod-liveness-exec created
[root@master mine]# kubectl get pod -n dev
NAME                READY   STATUS    RESTARTS   AGE
pod-liveness-exec   1/1     Running   0          19s
#查看详情
[root@master mine]# kubectl describe pods pod-liveness-exec -n dev
.......
  Warning  Unhealthy  9s (x6 over 59s)  kubelet, node2     Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
  Normal   Killing    9s (x2 over 39s)  kubelet, node2     Container nginx failed liveness probe, will be  restarted 
  #没有这个文件niginx容器重启 
[root@master mine]# kubectl get pod -n dev
NAME                READY   STATUS             RESTARTS   AGE
pod-liveness-exec   0/1     CrashLoopBackOff   6          4m43s
#RESTARTS重启次数已经变成三次


#删除这个Pod
[root@master mine]# kubectl delete -f test1.yaml
pod "pod-liveness-exec" deleted
#修改yaml文件
[root@master mine]# kubectl create -f test1.yaml
pod/pod-liveness-exec created
[root@master mine]# cat test1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-exec
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        command: ["/bin/ls","/tmp/"] # 执行一个查看文件的命令
#这条命令是可以执行的
[root@master mine]# kubectl describe pods pod-liveness-exec -n dev
....
  Normal  Created    65s   kubelet, node2     Created container nginx
  Normal  Started    65s   kubelet, node2     Started container nginx
  #发现没有重启
[root@master mine]# kubectl get pod -n dev
NAME                READY   STATUS    RESTARTS   AGE
pod-liveness-exec   1/1     Running   0          2m36s

重启策略

Pod 的 spec 中包含一个 restartPolicy 字段,其可能取值包括 Always、OnFailure 和 Never。默认值是 Always。

restartPolicy 适用于 Pod 中的所有容器。restartPolicy 仅针对同一节点上 kubelet 的容器重启动作。当 Pod 中的容器退出时,kubelet 会按指数回退方式计算重启的延迟(10s、20s、40s、…),其最长延迟为 5 分钟。 一旦某容器执行了 10 分钟并且没有出现问题,kubelet 对该容器的重启回退计时器执行重置操作。

  • Always:容器失效,自动重启容器
  • OnFailure:容器终止运行且退出码不为0时重启
  • Never:无论状态如何从不重启

创建pod-restartpolicy.yaml文件:

apiVersion: v1
kind: Pod
metadata:
  name: pod-restartpolicy
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:
        scheme: HTTP
        port: 80
        path: /hello  #没有这个路径所以无法访问
  restartPolicy: Never # 设置重启策略为Never
#创建Pod
[root@master mine]# vim pod-restartpolicy.yaml
[root@master mine]# kubectl create -f pod-restartpolicy.yaml
pod/pod-restartpolicy created
#查看是否重启
[root@master mine]# kubectl get pod -n dev
NAME                READY   STATUS      RESTARTS   AGE
pod-restartpolicy   0/1     Completed   0          111s
#发现并没有重启
#查看详细信息
[root@master mine]# kubectl describe pod pod-restartpolicy -n dev
....
  Warning  Unhealthy  3m11s (x3 over 3m31s)  kubelet, node2     Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    3m11s                  kubelet, node2     Stopping container nginx
#返回404未找到但是由于设置了重启策略为Never所以不重启
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。