• Kubernetes(k8s)的Pod资源清单生命周期Lifecycle相关属性详细讲解


    1. 概述

    Pod对象从创建到删除的这段时间范围称为Pod的生命周期,主要包含下面的过程:

    1. Pod创建
    2. 运行初始化容器(init container)
    3. 运行主容器(main container)
      1. 容器启动后钩子(post start)
      2. 容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
      3. 容器删除前钩子(pre stop)
    4. Pod删除

    Pod生命周期

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

    • 挂起(Pending):API Server已经创建了Pod资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中
    • 运行中(Running):Pod已经被调度到某节点,并且所有容器都已经被kubelet创建完成
    • 成功(Succeeded):Pod中的所有容器都已经成功删除并且不会被重启
    • 失败(Failed):所有容器都已经删除,但至少有一个容器删除失败,即容器返回了非0值的退出状态
    • 未知(Unknown):API Server无法正常获取到Pod对象的状态信息,通常由于网络通信失败所导致

    2. Pod的创建和删除过程

    2.1 Pod的创建过程

    Pod的创建

    1. 用户通过kubectl或其他的API客户端提交需要创建的Pod信息给API Server
    2. API Server开始生成Pod对象的信息,并将信息存入etcd,然后返回确认信息至客户端
    3. API Server开始反映etcd中的Pod对象的变化,其它组件使用watch机制来跟踪检查API Server上的变动
    4. Scheduler发现有新的Pod对象要创建,开始为Pod分配主机并将结果信息更新至API Server
    5. Node节点上的kubelet发现有Pod调度过来,尝试调度Docker启动容器,并将结果返回至API Server
    6. API Server将接收到的Pod状态信息存入到etcd中

    2.2 Pod的删除过程

    1. 用户向API Server发送删除Pod对象的命令
    2. 将Pod标记为terminating状态
    3. kubelet在监控到Pod对象转为terminating状态的同时启动Pod关闭过程
    4. 端点控制器监控到Pod对象的关闭行为时,将其从所有匹配到此端点的service资源的端点列表中移除
    5. 如果当前Pod对象定义了preStop钩子处理器,则在其标记为terminating后会以同步的方式启动执行
    6. Pod对象中的容器进程收到停止信号
    7. 宽限期结束后(默认30s),如果Pod中还存在运行的进程,那么Pod对象会收到立即删除的信号
    8. kubectl请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,此时Pod对于用户已经不可用

    3. init container初始化容器

    初始化容器是在Pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征:

    • 初始化容器必须运行完成直至结束,如果某个初始化容器运行失败,那么kubernetes需要重启它直至成功完成
    • 初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能运行

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

    • 提供主容器镜像中不具备的工具程序或自定义代码
    • 初始化容器要先于应用容器串行启动并运行完成,可用于满足应用容器启动的先决要求

    接下来做一个案例,模拟下面这个需求:

    • 假设主容器运行Nginx,但是要求在运行Nginx之前要能够连接上MySQL和Redis所在的服务器
    • 为了简化测试,事先规定好MySQL和Redis所在的IP地址分别为192.168.23.188和192.168.23.189(188的IP目前能ping通,189的IP目前不能ping通)

    新建pod-lifecycle.yaml,内容如下。然后进行pod创建

    
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
      initContainers:
        - name: init-mysql
          image: busybox
          command: ['/bin/sh', '-c', 'until ping 192.168.23.188 -c 1; do echo waiting for mysql; sleep 3; done;']
        - name: init-redis
          image: busybox
          command: ['/bin/sh', '-c', 'until ping 192.168.23.189 -c 1; do echo waiting for redis; sleep 3; done;']
    [root@k8s-master ~]# 
    [root@k8s-master ~]# kubectl apply -f pod-lifecycle.yaml 
    pod/pod-lifecycle created
    [root@k8s-master ~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    查看pod启动状态。只有第一个init成功,卡在第二个init container了

    [root@k8s-master ~]# kubectl get pod -n dev
    NAME            READY   STATUS     RESTARTS   AGE
    pod-lifecycle   0/1     Init:1/2   0          28s
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4

    4. 钩子函数

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

    • post start:容器创建之后执行,如果失败会重启容器
    • pre stop:容器删除之前执行,执行完成之后容器将成功删除,在其完成之前会阻塞删除容器的操作

    钩子处理器支持三种定义方式:

    1. exec命令:在容器内执行一次命令。语法如下:
      lifecycle:
        postStart: 
          exec:
            command:
                 - cat
                 - /tmp/test.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. tcpSocket:在当前容器尝试访问指定的socket
       lifecycle:
         postStart:
           tcpSocket:
             port: 8080
    
    • 1
    • 2
    • 3
    • 4
    1. httpGet:在当前容器中向某url发起HTTP请求
       lifecycle:
         postStart:
           httpGet:
             path: /                   # URI地址
             port: 80                  # 端口号
             host: 192.168.23.161     # 主机地址  
             scheme: HTTP              # 支持的协议,http或者https
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    新建pod-lifecycle.yaml,内容如下。然后进行pod创建

    [root@k8s-master ~]# cat pod-lifecycle.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-lifecycle
      namespace: dev
      labels:
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
          ports:
            - name: nginx-port
              containerPort: 80
              protocol: TCP
          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@k8s-master ~]# 
    [root@k8s-master ~]# kubectl apply -f pod-lifecycle.yaml 
    pod/pod-lifecycle created
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    访问nginx服务。可以看到postStat起作用了

    [root@k8s-master ~]# kubectl get pod -n dev -o wide
    NAME            READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
    pod-lifecycle   1/1     Running   0          64s   10.244.169.150   k8s-node2   <none>           <none>
    [root@k8s-master ~]# 
    [root@k8s-master ~]# curl 10.244.169.150:80
    postStart
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. 容器探测

    容器探测用于检测容器中的应用实例是否正常工作,kubernetes提供了三种探针来实现容器探测,本文主要讲解liveness probes和readiness probes

    • liveness probes:存活性探测,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器
    • readiness probes:就绪性探测,用于检测应用实例是否可以接受请求,如果不能,k8s不会转发流量到该应用实例
    • startupProbe探针,用于判断容器内应用程序是否已经启动,一旦成功将不再进行探测。如果配置了startupProbe探针,就会先禁止其他的探针,直到startupProbe探针成功为止

    liveness probes和readiness probes均支持三种探测方式。语法如下,readinessProbe和livenessProbe的语法一样

    1. exec命令:在容器内执行一次命令。如果命令执行的退出码为0,则认为程序正常,否则不正常
    livenessProbe:
      exec:
        command:
          - cat
          -	/tmp/test.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. tcpSocket:在当前容器尝试访问指定的socket。如果能够建立连接,则认为程序正常,否则不正常
    livenessProbe:
      tcpSocket:
        port: 8080
    
    • 1
    • 2
    • 3
    1. httpGet:在当前容器中向某url发起HTTP请求。如果返回的状态码在200和399之间,则认为程序正常,否则不正常
    livenessProbe:
      httpGet:
        path: /                         # URI地址
        port: 80                        # 端口号
        host: 192.168.23.161            # 主机地址
        scheme: HTTP                    # 支持的协议,http或者https
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过命令kubectl explain pod.spec.containers.livenessProbe查看其它属性,整理如下:

    exec 
    tcpSocket  
    httpGet
    initialDelaySeconds       # 容器启动后等待多少秒执行第一次探测
    timeoutSeconds            # 探测超时时间。默认1秒,最小1秒
    periodSeconds             # 执行探测的频率。默认是10秒,最小1秒
    failureThreshold          # 连续探测失败多少次才被认定为失败。默认是3。最小值是1
    successThreshold          # 连续探测成功多少次才被认定为成功。默认是1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5.1 exec方式

    新建pod-lifecycle.yaml,内容如下:

    [root@k8s-master ~]# cat pod-lifecycle.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-lifecycle
      namespace: dev
      labels:
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
          livenessProbe:
            exec:
              command: ["ls", "/tmp"] 
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    5.2 tcpSocket方式

    新建pod-lifecycle.yaml,内容如下:

    [root@k8s-master ~]# cat pod-lifecycle.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-lifecycle
      namespace: dev
      labels:
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
          ports:
            - name: nginx-port
              containerPort: 80
              protocol: TCP
          livenessProbe:
            tcpSocket:
              port: 80
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5.3 httpGet方式

    新建pod-lifecycle.yaml,内容如下:

    [root@k8s-master ~]# cat pod-lifecycle.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-lifecycle
      namespace: dev
      labels:
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
          ports:
            - name: nginx-port
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:        # 其实就是访问http://127.0.0.1:80/
              port: 80
              scheme: HTTP
              path: /
              host: 127.0.0.0
    [root@k8s-master ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    6. 重启策略

    在容器探测中,一旦容器探测出现了问题,kubernetes就会对容器所在的Pod进行重启,其实这是由Pod的默认重启策略决定的。Pod的重启策略有3种:

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

    重启策略是针对Pod设定的。首次需要重启的容器,将在其需要的时候立即进行重启,随后再次重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长依次为10s、20s、40s、80s、160s和300s,300s是最大的延迟时长

    新建pod-lifecycle.yaml,内容如下:

    [root@k8s-master ~]# cat pod-lifecycle.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-lifecycle
      namespace: dev
      labels:
        user: bulut
    spec:
      containers:
        - name: nginx-container
          image: nginx:latest
      restartPolicy: Never
    [root@k8s-master ~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    python趣味编程-5分钟实现一个益智数独游戏(含源码、步骤讲解)
    Unix 操作系统背后的女程序员 Lorinda Cherry 去世,享年 78 岁
    JDBCUtils的使用和事务
    真正的Mac电脑必备装机应用CleanMyMac X
    探索亚马逊大语言模型:开启人工智能时代的语言创作新篇章
    嵌入式养成计划-29-网络编程----TCP与UDP的基础模型
    IMX6ULL学习笔记(6)——通过USB OTG烧录U-Boot(MfgTool工具)
    Jquery 将 JSON 列表的 某个属性值,添加到数组中,并判断一个值,在不在数据中
    HTML5新增的input元素属性:placeholder、required、autofocus、min、max等
    3.9 拆解小红书爆文,流量密码原来是这些【玩赚小红书】
  • 原文地址:https://blog.csdn.net/yy8623977/article/details/124805042