Kubernetes最小单元Pod的生命周期

  • 1.1 Pod生命周期

    1.1.1 过程及状态

    Pod 的生命周期管理是 Kubernetes 集群中非常重要的一部分,它涉及到 Pod 从创建到销毁的整个过程。下面是 Pod 生命周期中各个阶段的简要说明:

    • Pod 创建过程:当一个 Pod 被创建时,Kubernetes 会为它分配资源并开始调度过程。

    • 运行初始化容器(Init Container):在 Pod 的主容器启动之前,可以定义一个或多个初始化容器。这些容器会先于主容器运行,通常用于执行一些初始化操作,比如设置配置文件或等待其他服务就绪。

    • 运行主容器(Main Container):初始化容器完成后,Pod 中的主容器会启动。主容器是 Pod 的核心部分,它负责执行应用程序的主要逻辑。

    • 容器启动后钩子(Post Start Hook):这是 Kubernetes 提供的一种回调机制,当容器创建并启动后,会调用这个钩子。可以在这个钩子中执行一些容器启动后需要立即进行的操作。

    • 容器终止前钩子(Pre Stop Hook):当容器即将被终止时,Kubernetes 会调用这个钩子。这允许容器进行一些清理工作,比如保存状态、释放资源等。

    • 容器的存活性探测(Liveness Probe):Kubernetes 会定期检查容器的存活性,以确保容器仍在正常运行。如果探测失败,Kubernetes 会重启该容器。

    • 就绪性探测(Readiness Probe):与存活性探测类似,就绪性探测用于确定容器是否已经准备好接收流量。如果探测失败,Kubernetes 会将该容器从服务的端点列表中移除,直到它再次就绪。

    • Pod 终止过程:当 Pod 被标记为需要终止时,Kubernetes 会停止所有的容器,并进行清理工作。在 Pod 被完全终止之前,可能会执行一些终止前的操作,比如保存状态或执行其他必要的清理任务。

    image-20240509100139686

    Pod 的状态确实可以反映其当前的生命周期阶段。以下是 Pod 的五种状态(相位)的详细解释:

    • 挂起(Pending):这个阶段表示 Pod 已经被 Kubernetes API 服务器创建,但尚未被调度到任何节点上。这可能是因为没有合适的节点可供调度,或者因为 Pod 正在等待某些依赖的资源(如 ConfigMaps、Secrets 或者容器镜像)。

    • 运行中(Running):在这个状态中,Pod 已经被调度到节点上,并且所有的容器都已经被创建。至少有一个容器正在运行,或者正在启动或重启。

    • 成功(Succeeded):当 Pod 中的所有容器都正常运行并成功退出(返回了退出代码 0),并且不会被重启时,Pod 就会进入成功状态。这通常用于表示批处理任务已经完成。

    • 失败(Failed):如果 Pod 中的所有容器都终止了,但至少有一个容器是因为失败而终止的(即返回了非零的退出代码),Pod 就会进入失败状态。这表明 Pod 没有成功完成任务。

    • 未知(Unknown):当 Kubernetes 控制平面无法获取到 Pod 的状态信息时,Pod 就会进入未知状态。这通常是由于与 Pod 所在节点的通信失败导致的。如果节点长时间无法与控制平面通信,可能会认为节点及其上的 Pods 处于未知状态。

    1.1.2 创建和终止

    1.1.2.1 Pod创建过程

    Pod 的创建过程可以简写为以下几个步骤:

    • 提交请求:用户通过 kubectl 或 API 客户端向 API 服务器提交创建 Pod 的请求。

    • 创建对象:API 服务器创建 Pod 对象并存储到 etcd,然后向客户端确认创建成功。

    • 监听变化:其他组件通过 watch 机制监听 API 服务器上的 Pod 对象变化。

    • 调度决策:调度器为 Pod 选择节点,并将调度结果更新到 API 服务器。

    • 启动容器:节点上的 kubelet 启动容器,并将状态回传给 API 服务器。

    • 状态更新:API 服务器更新 etcd 中的 Pod 状态信息。

    image-20240509100813009

    1.1.2.2 Pod终止过程
    • 发送删除命令:用户通过 kubectl 或 API 客户端向 API 服务器发送删除 Pod 对象的命令。

    • 宽限期:API 服务器开始等待宽限期(默认为 30 秒),在此期间 Pod 被视为 "dead",但尚未被立即删除。

    • 标记为终止:Pod 被标记为 terminating 状态,告知系统它正在被删除。

    • Kubelet 启动关闭过程:节点上的 kubelet 监控到 Pod 状态变为 terminating,开始关闭 Pod。

    • 端点控制器移除:端点控制器发现 Pod 正在关闭,将其从所有相关服务的端点列表中移除。

    • PreStop 钩子:如果 Pod 定义了 preStop 钩子,这些钩子会被触发并同步执行,以进行清理操作。

    • 停止容器:Pod 中的容器进程收到停止信号,开始正常关闭。

    • 强制终止:如果宽限期结束,仍有进程在运行,kubelet 会发送信号强制终止这些进程。

    • 完成删除:Kubelet 请求 API 服务器将 Pod 的宽限期设置为 0,完成删除操作,此时 Pod 对用户不可见。

    1.1.3 初始化容器

    初始化容器(Init Container)在 Kubernetes 中用于执行 Pod 中主容器启动前的一些初始化任务。

    • 必须成功完成:每个初始化容器必须运行成功直至结束。如果某个初始化容器失败,Kubernetes 会尝试重启该容器,直到它成功完成。这确保了在主容器启动之前,所有的初始化工作都已经正确执行。

    • 顺序执行:初始化容器按照在 Pod 定义中出现的顺序执行。只有当前一个初始化容器成功完成后,下一个才会开始执行。这允许复杂的初始化逻辑被分解成有序的步骤。

    1.1.3.1 应用场景
    • 环境检查:初始化容器可以用于检查外部服务是否可用,例如数据库或配置服务器,然后才启动应用容器。

    • 数据加载:在启动应用之前,可能需要从外部源加载数据或配置文件到 Pod 中。

    • 权限设置:有时需要在启动主容器之前设置文件权限或创建必要的目录结构。

    • 依赖安装:安装主容器运行所需的依赖库或工具,特别是当这些依赖不包含在主容器镜像中时。

    • 资源等待:等待某些资源(如 PersistentVolume 卷)准备就绪。

    • 健康检查:对系统进行健康检查,确保所有依赖服务都处于健康状态,然后才启动应用。

    • 自定义脚本执行:运行自定义脚本,执行如数据库迁移或缓存预热等操作。

    1.1.3.2 测试
    • 创建一个包含两个初始化容器的 Pod,其中一个初始化容器用于检查 MySQL 服务是否可达,另一个用于检查 Redis 服务是否可达。只有在两个服务都可达的情况下,主容器(Nginx)才会启动。

    [root@K8s-master ~]# vim pod-initcontainer.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-initcontainer
      namespace: test
    spec:
      containers:
      - name: main-container
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
      initContainers:
      - name: test-mysql
        image: busybox
        command: ['sh', '-c', 'until ping -c 1 192.168.110.100; do echo waiting for mysql...; sleep 2; done;']
      - name: test-redis
        image: busybox
        command: ['sh', '-c', 'until ping -c 1 192.168.110.200; do echo waiting for redis...; sleep 2; done;']
        
    ​
    - 根据 Kubernetes 的行为,initContainers 中的容器将按照它们在配置中出现的顺序依次执行。
    - 只有当 test-mysql 成功完成后,test-redis 才会开始执行。
    - 只有当所有的初始化容器都成功完成后,Kubernetes 才会启动主容器 main-container。
    ​
    [root@K8s-master ~]# kubectl apply -f pod-initcontainer.yaml
    pod/pod-initcontainer created
    [root@K8s-master ~]# kubectl get pod pod-initcontainer -n test   #处于初始化过程,因为两台服务器不可达
    NAME                READY   STATUS     RESTARTS   AGE
    pod-initcontainer   0/1     Init:0/2   0          2m51s
    [root@K8s-master ~]# nmcli connection modify ens33 +ipv4.addresses 192.168.110.100/24  #增加两台主机地址
    [root@K8s-master ~]# nmcli connection modify ens33 +ipv4.addresses 192.168.110.200/24
    [root@K8s-master ~]# nmcli connection up ens33 
    [root@K8s-master ~]# kubectl get pod pod-initcontainer -n test   #主容器正常运行
    NAME                READY   STATUS    RESTARTS   AGE
    pod-initcontainer   1/1     Running   0          33s
    [root@K8s-master ~]# kubectl describe pod pod-initcontainer -n test 
    Events:
      Type    Reason     Age    From               Message
      ----    ------     ----   ----               -------
      Normal  Scheduled  4m49s  default-scheduler  Successfully assigned test/pod-initcontainer to k8s-node-02
      Normal  Pulling    4m48s  kubelet            Pulling image "busybox"
      Normal  Pulled     4m45s  kubelet            Successfully pulled image "busybox" in 2.488707224s
      Normal  Created    4m45s  kubelet            Created container test-mysql
      Normal  Started    4m45s  kubelet            Started container test-mysql
      Normal  Pulling    4m44s  kubelet            Pulling image "busybox"
      Normal  Pulled     4m42s  kubelet            Successfully pulled image "busybox" in 2.403816887s
      Normal  Created    4m42s  kubelet            Created container test-redis
      Normal  Started    4m41s  kubelet            Started container test-redis
      Normal  Pulled     4m41s  kubelet            Container image "nginx:1.17.1" already present on machine
      Normal  Created    4m41s  kubelet            Created container main-container
      Normal  Started    4m41s  kubelet            Started container main-container
      #可以看到把mysql和redis都搞定Nginx才能起来,主容器才能起来

    1.1.4 钩子函数

    • Kubernetes 中的容器生命周期钩子(lifecycle hooks)些钩子允许开发者在容器的生命周期中的特定时刻执行自定义操作。kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:

      • Post Start Hook

        • 这个钩子在容器创建并成功运行之后立即执行。它可以用来执行容器启动后需要立即进行的任务,比如发送信号给其他服务,或者执行某些初始化逻辑。

        • 如果 Post Start 钩子失败,即执行的命令返回非零退出码,Kubernetes 会认为容器启动失败,并根据容器的重启策略决定是否重启容器。

      • Pre Stop Hook

        • 这个钩子在容器即将终止之前执行。它通常用于执行清理工作,如保存状态、优雅地关闭服务、释放资源等。

        • Pre Stop 钩子提供了一种优雅关闭容器的方式。如果容器在 Pre Stop 钩子执行期间没有停止,Kubernetes 将等待一段时间(默认为 30 秒)之后,发送 SIGKILL 信号强制终止容器。

    Kubernetes 中容器生命周期钩子处理器支持的三种动作类型:ExecTCPSocketHTTPGet

    • Exec 命令

      • 这个动作类型允许在容器内执行一个命令行命令。

      • 如果命令执行成功(退出状态码为0),钩子继续执行;如果失败(非零退出状态码),则容器将被重启。

      lifecycle:
        postStart:
          exec:
            command: ["cat", "/tmp/healthy"]
    • TCPSocket

      • 这个动作类型尝试在容器内访问指定的 TCP 端口。

      • 如果能够建立连接,则钩子动作成功;否则,容器将被重启。

      lifecycle:
        postStart:
          tcpSocket:
            port: 8080
    • HTTPGet

      • 这个动作类型在容器内向指定的 URL 发起 HTTP GET 请求。

      • 如果请求成功(HTTP 状态码为 200-399),钩子动作成功;如果失败,则容器将被重启。

      lifecycle:
        postStart:
          httpGet:
            path: /healthz  # URI地址
            port: 80        # 端口号
            host: 192.168.110.100  # 主机地址
            scheme: HTTP    # 支持的协议,可以是 HTTP 或 HTTPS
    1.1.4.1 钩子函数使用实例(Exec为例)
    [root@K8s-master ~]# vim pod-hook-exec.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-hook-exec
      namespace: test
    spec:
      containers:
      - name: main-container
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        lifecycle:
          postStart:
            exec:
              command: ["/bin/bash", "-c", "echo 'postStart...' > /usr/share/nginx/html/index.html"]
          preStop:
            exec:
              command: ["/usr/sbin/nginx", "-s", "quit"]
              
    [root@K8s-master ~]# kubectl apply -f pod-hook-exec.yaml 
    pod/pod-hook-exec created
    [root@K8s-master ~]# kubectl get pod -n test -o wide
    NAME            READY   STATUS    RESTARTS   AGE     IP            NODE          NOMINATED NODE   READINESS GATES
    pod-hook-exec   1/1     Running   0          3m17s   10.244.2.11   k8s-node-02   <none>           <none>
    [root@K8s-master ~]# curl 10.244.2.11
    postStart...

    1.1.5 容器探测

    在Kubernetes中,确实存在两种类型的探针,用于确保容器实例的健康和可用性:

    • Liveness Probe(存活性探针):这种探针用于判断容器是否仍然处于“存活”状态。如果一个容器的存活性探针失败,Kubernetes会认为这个容器无法正常工作,因此会重启这个容器。存活性探针的典型用途是检测应用程序是否已经崩溃或者变得无响应。

    • Readiness Probe(就绪性探针):这种探针用于判断容器是否已经准备好接受流量。如果一个容器的就绪性探针失败,Kubernetes会从服务的负载均衡池中将该容器摘除,直到该容器再次报告它已经准备好。就绪性探针常用于确保新启动的容器在开始接收流量之前已经完成了初始化过程。

    这两种探针都可以通过HTTP请求、TCP连接尝试或者执行容器内命令等方式来实现。它们可以配置为定期执行,并且可以设置初始延迟、超时时间以及探测间隔。

    在配置时,可以为每个探针设置以下参数:

    • InitialDelaySeconds:在容器启动后等待多少秒才开始执行探针检查。

    • TimeoutSeconds:探针检查超时的时间。

    • PeriodSeconds:探针检查的执行频率。

    • SuccessThreshold:探测成功后,需要连续成功多少次才认为容器健康。

    • FailureThreshold:探测失败后,需要连续失败多少次才认为容器不健康。

    Kubernetes 中存活性探针(Liveness Probe)和就绪性探针(Readiness Probe)支持的三种探测方式。以下是对这三种方式的简要说明:

    • Exec 命令探针:通过在容器内部执行一个命令来检查容器的健康状况。如果命令执行成功(即退出码为0),则认为容器是健康的。例如:

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

    这个例子中,如果容器内 /tmp/healthy 文件存在,cat 命令将成功执行,探针将返回健康状态。

    • TCP Socket 探针:通过尝试与容器内部的某个端口建立 TCP 连接来检查容器的健康状况。如果连接成功建立,探针认为容器是健康的。例如:

    livenessProbe:
      tcpSocket:
        port: 8080

    在这个例子中,Kubernetes 将尝试连接到容器的 8080 端口,如果连接成功,容器被认为是健康的。

    • HTTP GET 探针:通过向容器内部的 Web 应用发送 HTTP GET 请求来检查容器的健康状况。如果 HTTP 响应的状态码在 200 到 399 之间,探针认为容器是健康的。例如:

    livenessProbe:
      httpGet:
        path: /healthz  # 这里是健康检查的URI路径
        port: 80        # 这里是容器内部的端口号
        host: 127.0.0.1 # 这里是主机地址,通常设置为localhost或127.0.0.1
        scheme: HTTP    # 这里指定使用的是HTTP协议
    1.1.5.1 Exec命令探针
    [root@K8s-master ~]# vim pod-liveness-exec.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness-exec
      namespace: test
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          exec:
            command: ["/bin/cat", "/tmp/hello.txt"]
            
    [root@K8s-master ~]# kubectl apply -f pod-liveness-exec.yaml 
    pod/pod-liveness-exec created
    [root@K8s-master ~]# kubectl describe pods pod-liveness-exec -n test
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  52s                default-scheduler  Successfully assigned test/pod-liveness-exec to k8s-node-02
      Normal   Pulled     21s (x2 over 51s)  kubelet            Container image "nginx:1.17.1" already present on machine
      Normal   Created    21s (x2 over 51s)  kubelet            Created container nginx
      Normal   Killing    21s                kubelet            Container nginx failed liveness probe, will be restarted
      Normal   Started    20s (x2 over 50s)  kubelet            Started container nginx
      Warning  Unhealthy  1s (x5 over 41s)   kubelet            Liveness probe failed: /bin/cat: /tmp/hello.txt: No such file or directory
    # 观察上面的信息就会发现nginx容器启动之后就进行了健康检查
    # 检查失败之后,容器被kill掉,然后尝试进行重启(这是重启策略的作用,后面讲解)
    # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
    [root@K8s-master ~]# kubectl get pods pod-liveness-exec -n test   #启动后进行健康检测
    NAME                READY   STATUS    RESTARTS      AGE
    pod-liveness-exec   1/1     Running   3 (24s ago)   115s
    [root@K8s-master ~]# kubectl get pods pod-liveness-exec -n test   #稍等会被杀掉
    NAME                READY   STATUS             RESTARTS      AGE
    pod-liveness-exec   0/1     CrashLoopBackOff   4 (17s ago)   2m48s
    # 可以修改成一个存在的文件,就正常了
    [root@K8s-master ~]# kubectl exec pod-liveness-exec -n test -it -c nginx /bin/sh
    # echo hello > /tmp/hello.txt
    
    [root@K8s-master ~]# kubectl get pod pod-liveness-exec -n test 
    NAME                READY   STATUS    RESTARTS       AGE
    pod-liveness-exec   1/1     Running   20 (39s ago)   46m
    1.1.5.2 TCP Socket 探针
    [root@K8s-master ~]# vim pod-liveness-tcpsocket.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness-tcpsocket
      namespace: test
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          tcpSocket:
            port: 8080
    
    
    [root@K8s-master ~]# kubectl apply -f pod-liveness-tcpsocket.yaml
    pod/pod-liveness-tcpsocket created
    [root@K8s-master ~]# kubectl describe pod pod-liveness-tcpsocket -n test
    Events:
      Type     Reason     Age                  From               Message
      ----     ------     ----                 ----               -------
      Normal   Scheduled  2m14s                default-scheduler  Successfully assigned test/pod-liveness-tcpsocket to k8s-node-02
      Normal   Pulled     44s (x4 over 2m13s)  kubelet            Container image "nginx:1.17.1" already present on machine
      Normal   Created    44s (x4 over 2m13s)  kubelet            Created container nginx
      Normal   Killing    44s (x3 over 104s)   kubelet            Container nginx failed liveness probe, will be restarted
      Normal   Started    43s (x4 over 2m13s)  kubelet            Started container nginx
      Warning  Unhealthy  34s (x10 over 2m4s)  kubelet            Liveness probe failed: dial tcp 10.244.2.18:8080: connect: connection refused
    # 观察上面的信息,发现尝试访问8080端口,但是失败了
    # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
    [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test
    NAME                     READY   STATUS    RESTARTS      AGE
    pod-liveness-tcpsocket   1/1     Running   5 (46s ago)   3m16s
    [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test
    NAME                     READY   STATUS             RESTARTS      AGE
    pod-liveness-tcpsocket   0/1     CrashLoopBackOff   5 (33s ago)   4m13s
    
    #可以修改成一个可以访问的端口,比如80,再试,结果就正常了
    [root@K8s-master ~]# sed -i 's/8080/80/' pod-liveness-tcpsocket.yaml 
    [root@K8s-master ~]# kubectl delete -f pod-liveness-tcpsocket.yaml 
    pod "pod-liveness-tcpsocket" deleted
    [root@K8s-master ~]# kubectl apply -f pod-liveness-tcpsocket.yaml 
    pod/pod-liveness-tcpsocket created
    [root@K8s-master ~]# kubectl get pod pod-liveness-tcpsocket -n test
    NAME                     READY   STATUS    RESTARTS   AGE
    pod-liveness-tcpsocket   1/1     Running   0          12s
    1.1.5.3 HTTP GET 探针
    [root@K8s-master ~]# vim pod-liveness-httpget.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness-httpget
      namespace: test
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /hello
    
    [root@K8s-master ~]# kubectl apply -f pod-liveness-httpget.yaml 
    pod/pod-liveness-httpget created
    [root@K8s-master ~]# kubectl describe pod pod-liveness-httpget -n test
    Events:
      Type     Reason     Age               From               Message
      ----     ------     ----              ----               -------
      Normal   Scheduled  66s               default-scheduler  Successfully assigned test/pod-liveness-httpget to k8s-node-01
      Normal   Pulled     5s (x3 over 65s)  kubelet            Container image "nginx:1.17.1" already present on machine
      Normal   Created    5s (x3 over 65s)  kubelet            Created container nginx
      Warning  Unhealthy  5s (x6 over 55s)  kubelet            Liveness probe failed: Get "http://10.244.1.6:80/hello": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
      Normal   Killing    5s (x2 over 35s)  kubelet            Container nginx failed liveness probe, will be restarted
      Normal   Started    4s (x3 over 65s)  kubelet            Started container nginx
    [root@K8s-master ~]# kubectl get pod pod-liveness-httpget -n test
    NAME                   READY   STATUS             RESTARTS      AGE
    pod-liveness-httpget   0/1     CrashLoopBackOff   4 (16s ago)   2m47s
    
    # 观察上面信息,尝试访问路径,但是未找到,出现404错误
    # 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
    
    #修改一个可以访问的路径
    [root@K8s-master ~]# sed -i 's#/hello#/#' pod-liveness-httpget.yaml 
    [root@K8s-master ~]# kubectl delete -f pod-liveness-httpget.yaml 
    pod "pod-liveness-httpget" deleted
    [root@K8s-master ~]# kubectl apply -f pod-liveness-httpget.yaml 
    pod/pod-liveness-httpget created
    [root@K8s-master ~]# kubectl get pod pod-liveness-httpget -n test
    NAME                   READY   STATUS    RESTARTS   AGE
    pod-liveness-httpget   1/1     Running   0          3s
    1.1.5.4 livenessProbe的子属性
    [root@K8s-master ~]# kubectl explain pod.spec.containers.livenessProbe
    livenessProbe:
      exec: <Object> # 在容器内执行的命令
      tcpSocket: <Object> # 用于探测的TCP端口和IP
      httpGet: <Object> # 用于探测的HTTP GET请求
      initialDelaySeconds: <integer> # 容器启动后等待多少秒执行第一次探测
      timeoutSeconds: <integer> # 探测超时时间,默认为1秒,最小1秒
      periodSeconds: <integer> # 执行探测的频率,默认为10秒,最小1秒
      failureThreshold: <integer> # 连续探测失败多少次才被认定为失败,默认为3,最小1
      successThreshold: <integer> # 连续探测成功多少次才被认定为成功,默认为1
    • 配置实例

    [root@K8s-master ~]# vim pod-liveness-httpget.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-liveness-httpget
      namespace: dev
    spec:
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - name: nginx-port
          containerPort: 80
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /
          initialDelaySeconds: 30 # 容器启动后30秒开始探测
          timeoutSeconds: 5       # 探测超时时间为5秒

    1.1.6 重启策略

    1.1.6.1 三种策略

    Kubernetes 中的 Pod 支持以下三种重启策略:

    • Always

      • 描述:无论容器退出的原因是什么,都会自动重启容器。

      • 默认值:如果未指定重启策略,Kubernetes 默认使用 Always。

    • OnFailure

      • 描述:仅当容器以非零退出码终止时,才会重启容器。

      • 条件:需要指定退出码来触发重启。

    • Never

      • 描述:不论容器退出的原因是什么,都不会重启容器。

    1.1.6.2 重启延迟
    • 首次重启:首次需要重启的容器将立即进行重启。

    • 后续重启:随后如果再次需要重启,kubelet 将会引入延迟,延迟时长从 10 秒开始,并呈指数增长。

    • 延迟时长序列:10s、20s、40s、80s、160s,之后达到最大延迟时长。

    • 最大延迟时长:300s,这是后续重启操作的最大延迟时长。

    [root@K8s-master ~]# vim pod-restartpolicy.yaml
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-restartpolicy
      namespace: test
    spec:
      restartPolicy: Never   #论容器退出的原因是什么,都不会重启容器
      containers:
      - name: nginx
        image: nginx:1.17.1
        ports:
        - containerPort: 80
          name: nginx-port
        livenessProbe:
          httpGet:
            scheme: HTTP
            port: 80
            path: /hello
    ​
    [root@K8s-master ~]# kubectl apply -f pod-restartpolicy.yaml 
    pod/pod-restartpolicy created
    [root@K8s-master ~]# kubectl describe pod pod-restartpolicy -n test  # 查看Pod详情,发现nginx容器失败
    Events:
      Type     Reason     Age                From               Message
      ----     ------     ----               ----               -------
      Normal   Scheduled  94s                default-scheduler  Successfully assigned test/pod-restartpolicy to k8s-node-02
      Normal   Pulled     92s                kubelet            Container image "nginx:1.17.1" already present on machine
      Normal   Created    92s                kubelet            Created container nginx
      Normal   Started    92s                kubelet            Started container nginx
      Warning  Unhealthy  63s (x3 over 83s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
      Normal   Killing    63s                kubelet            Stopping container nginx
    [root@K8s-master ~]# kubectl get pod pod-restartpolicy -n test  # 再观察pod的重启次数,发现一直是0,并未重启
    NAME                READY   STATUS      RESTARTS   AGE
    pod-restartpolicy   0/1     Completed   0          2m3s

    1.1.7 Pod常见状态转换场景

    Pod中的容器数Pod状态发生事件AlwaysOnFailureNever
    包含一个容器Running容器成功退出RunningSucceededSucceeded
    包含一个容器Running容器失败退出RunningRunningFailed
    包含两个容器Running1个容器失败退出RunningRunningRunning
    包含两个容器Running容器内存溢出挂掉RunningRunningFailed

    注释:

    • 对于 Always 重启策略,容器将立即重启。

    • 对于 OnFailureNever 重启策略,如果容器成功退出且退出码为0,Pod状态将变为Succeeded。

    • 对于 Always 重启策略,容器将立即重启。

    • 对于 OnFailure 重启策略,容器将以非零退出码退出,因此会重启。

    • 对于 Never 重启策略,容器将不会重启,Pod状态将变为Failed。

    • 对于 Always 重启策略,由于内存溢出导致的容器终止将重启容器。

    • 对于 OnFailure 重启策略,内存溢出导致的容器终止会触发重启,因为退出码是非零的。

    • 对于 Never 重启策略,容器将不会重启,Pod中其他容器继续运行,但失败的容器状态将为Terminated

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/606516.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三层架构实验

交换部分 第一个步骤配 Eth-Trunk&#xff0c;目的是&#xff1a;将两条线绑在一起 sw和1sw2上配置 [sw1]interface Eth-Trunk 0 //创建隧道 [sw1-Eth-Trunk0]q [sw1]int g 0/0/2 [sw1-GigabitEthernet0/0/2]eth-trunk 0 //进入接口划分隧道 [sw1-GigabitEthernet0/0/2]…

JavaScript算法描述【排序与搜索】六大经典排序|搜索旋转排序数组|在排序数组中查找元素的第一个和最后一个位置、数组中的第K个|

&#x1f427;主页详情&#xff1a;Choice~的个人主页 文章目录 搜索旋转排序数组方法一 二分查询最大最小值思路详解代码方法二 二分查询中间数 在排序数组中查找元素的第一个和最后一个位置、数组中的第K个最大元素和颜色分类在排序数组中查找元素的第一个和最后一个位置方法…

【LeetCode刷题】153. 寻找旋转排序数组中的最小值

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 153. 寻找旋转排序数组中的最小值 2. 题目描述 3. 解题方法 根据题目分析&#xff0c;可以明确一点&#xff0c;无论该数组如何旋转&#xff0c;都会有这样的一个性质&#xff0c;就是nums[0] > nums[n-1]&#xf…

CST软件的界面快捷键汇总与操作窗口【入门基础】

CST界面操作快捷键 利用鼠标和键盘快捷键的GUI操作 View > Mouse Control 本章节介绍&#xff0c;使用鼠标和键盘快捷键&#xff0c;操作CST软件的2D/3D GUI (Graphical User Interface图形用户界面)的方法。为了快速方便地操作2D/3D Model&#xff0c;建议熟悉本章节的内…

springcloud报错:Failed to start bean‘webServerStartStop‘

如果你正在使用nacos进行服务注册&#xff0c;然后报一下错误&#xff1a; 那就说明的nacos没有打开&#xff0c;所以找到你的下载nacos的文件夹 好了&#xff0c;错误完美解决~

eNSP Pro 最新版安装实践

目录 写在前面什么是eNSP Pro版本配置需求 安装流程宿主机环境安装步骤 写在前面 最近听到说&#xff0c;华为的eNSP Pro不再限制账号使用了&#xff0c;马上尝试了一下。 官网下载链接&#xff1a; https://support.huawei.com/enterprise/zh/enterprise-professional-servic…

鸿蒙内核源码分析(环境脚本篇) | 编译鸿蒙原来如此简单

很香的 Docker 如果只是为了编译鸿蒙,初级的接触鸿蒙,docker是很香的,从第一次接触docker就对它爱不释手, 脏活累活它干了,少了太多的麻烦. docker 编译鸿蒙看编译环境篇就行了, L1 和 L2 都编译通过了.如果要深入的了解鸿蒙,比如调试鸿蒙的代码或编译工具,就需要另辟蹊径了. …

区块链的可扩展性三难问题

这个词是由以太坊的联合创始人Vitalik Buterin创造的&#xff0c;并提出了理想的区块链需要具备的三个特征&#xff1a;去中心化、可扩展性和安全性。 Vitalik还提出&#xff0c;区块链几乎不可能很好地实现所有这三个特征&#xff0c;所以会出现权衡。 因此&#xff0c;今天…

linux 使用intel oneapi报错报错

使用intel oneapi 2024.1.0 时经常报这个错误 因为当前 intel2024.1.0没有在使用 需要改回2024.0.0并安装适配的torch的包来运行

XN297 2.4GHz 单片高速无线收发芯片

概述 XN297是一款工作在2.400~2.483GHz世界通用ISM频段的单片无线收发芯片。该芯片集成 射频收发器、频率发生器、晶体振荡器、调制解调器等功能模块&#xff0c;并且支持一对多组网和带 ACK的通信模式。发射输出功率、工作频道以及通信数据率均可配置。 主要特性 1、低功…

三星硬盘好还是西数硬盘好?硬盘数据丢失怎么找回

在数字化时代&#xff0c;硬盘作为数据存储的核心组件&#xff0c;其品质与性能直接关系到用户的数据安全与使用体验。在众多硬盘品牌中&#xff0c;三星与西数无疑是两个备受关注的名字。那么&#xff0c;究竟是三星硬盘更胜一筹&#xff0c;还是西数硬盘更受用户青睐&#xf…

【项目】使用Yolov8 + tesseract 实现“营业执照”信息解析(OCR) + 输入可为图片或者pdf + 完整代码 + 整体方案 + 全网首发

本项目可用于毕业设计参考、实验等,营业执照分为横版和竖版,整体检测+识别效果如下所示: 说明:图片来源于网络,如有侵权,请联系作者删除。 目录

DRF 目录总结+思维导图

【0】思维导图链接 链接: https://gitmind.cn/app/docs/mcd0bc41 密码: 4350 【一】DRF 基础知识 DRF 基础知识-CSDN博客 【二】CBV 源码解析 Django CBV源码分析-CSDN博客 【三】APIView源码解析 DRF APIView源码分析-CSDN博客 【四】request源码分析 DRF APIView源码分…

# 从浅入深 学习 SpringCloud 微服务架构(十三)SCG 网关中使用 sentinel 限流

从浅入深 学习 SpringCloud 微服务架构&#xff08;十三&#xff09;SCG 网关中使用 sentinel 限流 一、SCG 网关中使用 sentinel 限流&#xff1a;入门案例 1、基于 Sentinel 的限流&#xff1a; 1&#xff09; Sentinel 支持对 Spring Cloud Gateway, Zuul 等主流的 API G…

【全开源】Java洗衣清洁服务同城清洗服务小程序源码

特色功能&#xff1a; 在线预约与支付&#xff1a;用户可以通过洗衣小程序在线预约洗衣服务&#xff0c;并选择支付方式进行支付&#xff0c;如微信支付、支付宝等。这种在线预约和支付的方式极大地方便了用户&#xff0c;提高了服务的便捷性。智能推荐与选择&#xff1a;根据…

探索C++的string:从基础到深入

文章目录 string类string类的接口string的常见构造string类对象的容量操作string类的遍历及访问操作string类对象的修改操作string类的非成员函数 总结 string类 C中的string类是一个非常重要的字符串处理工具&#xff0c;它提供了一种方便且灵活的方式来处理字符串。它位于标…

Vue3专栏项目 -- 一、第一个页面(下)

一、Dropdown 组件&#xff08;下拉菜单组件&#xff09;编码 1、基本功能&#xff1a;展示出下拉按钮和下拉菜单栏的样式 我们可以通过bootstrap来实现这个下拉框&#xff0c;需要注意它这个只是有样式&#xff0c;是没有行为的 然后这个下拉按钮的文字展示是根据用户名称展…

云推流-让ue/unity内容及3D大型模型内容轻松做到网页使用的解决方案

UE&#xff08;Unreal Engine&#xff09;和Unity作为当下最热门的游戏引擎之一&#xff0c;为开发者提供了强大的工具集和平台支持&#xff0c;使得创建高质量、交互式的3D场景变得越来越容易。 然而&#xff0c;当我们把这种较大的资源分享给其他人时&#xff0c;对方可能需要…

qml拖动交换之Gridview

qml拖动交换之Gridview 坐标变换代码 QML中mapToItem和mapFromItem的使用 坐标变换 代码 import QtQuick 2.6 import QtQuick.Window 2.2Window {visible: truewidth: 1024height: 480title: qsTr("Drag Icon")property ListModel dataModel: ListModel {ListEleme…

摩菲Murphy显示器显示表 总线编程器维修PV780B

Murphy仪器维修包括&#xff1a;摩菲数字显示器&#xff1b;摩菲监视仪表&#xff1b;摩菲CAN总线控制器等维修 维修故障包括&#xff1a;黑屏、指示灯无显示&#xff0c;触摸屏上电无反应&#xff0c; 上电蓝屏、白屏&#xff0c;通电几分钟后屏幕变为蓝屏&#xff0c;主板故…