k8s上Pod生命周期、重启策略、容器探测简介

目录

一.Pod的创建过程

二.Pod的终止过程

三.Pod的重启策略(restartPolicy)

1.Always

2.OnFailture

3.Never

4.示例

四.Pod生命周期内的5种状态(相位)

1.Pending

2.Running

3.Succeeded

4.Failed

5.Unknown

[五.初始化容器(init container)](#五.初始化容器(init container))

1.运行初始化容器

2.以一个案例进行验证初始化容器的重要性

(1)首先只为mysql提供一个IP地址,tomcat的还没有提供

(2)编写文件

(3)应用验证

(4)为redis提供可用IP地址,并应用验证

[六.主容器(main container)](#六.主容器(main container))

1.钩子函数简介

(1)exec,只在容器内执行一次

(2)tcpSocket,在当前的容器中尝试访问指定socket,成功后继续执行

(3)httpGet,在当前的容器中向某url发起http请求,成功后继续执行

2.容器探测

[(1)liveness probes](#(1)liveness probes)

[(2)readiness probes](#(2)readiness probes)

(3)initialDelaySeconds和timeoutSeconds


一.Pod的创建过程

1.用户通过kubectl提交pod信息传给apiserver,apiserver生成pod信息,将信息存入etcd,并像kubectl返回确认信息

2.apiserver开始记录etcd上apiserver传来的pod的变化,剩余其他组件使用watch机制跟踪apiserver信息变化

3.scheduler发现pod创建请求,为pod分配主机,向apiserver返回分配信息

4.node上kubectl接收到pod调度任务,使用现有容器引擎启动容器,向apiserver返回启动等结果

5.apiserver最后又将pod状态存入etcd

二.Pod的终止过程

1.kubectl客户端向apiserver发出删除pod命令

2.apiserver中的pod信息在默认的30s宽限期内被视为dead,被标记为terminating状态

(1)kubelet察觉到pod为terminating状态后会开始关闭该pod的进程,node上的设备察觉到进程关闭后会把该pod在此node上匹配的service资源都移出列表

(2)若是pod定义了prestop钩子相关部分,在terminating后会同步开启执行prestop

4.容器进程收到停止信号后,判断宽限期结束后是否还有运行中的进程,若存在,该进程和pod会被要求立即终止

5.apiserver收到kubelet将pod宽限期设置为0的请求,随后完成删除

三.Pod的重启策略(restartPolicy)

主要是针对容器探测时出现问题后的重启具体策略,主要有Always、OnFailure、Never三种策略,除首次重启外,以后的每次重启间隔一般都为10s-20s-40s-80s这样的双倍递增规律

1.Always

容器生效后,自动重启,默认就是Always

2.OnFailture

容器停止运行而且退出码不为0时才重启

3.Never

不管是处于什么状态,都不重启

4.示例

apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        postStart:
          tcpSocket:
            port: 8080
  restartPolicy: Always
​
[root@k8s-master pod]# kubectl get pods -n myns
NAME      READY   STATUS             RESTARTS      AGE
mynginx   0/1     CrashLoopBackOff   1 (43s ago)   2m
[root@k8s-master pod]# vim nginx.yaml 
[root@k8s-master pod]# kubectl get pods -n myns
NAME      READY   STATUS             RESTARTS      AGE
mynginx   0/1     CrashLoopBackOff   2 (11s ago)   2m16s    #该容器无法正常创建,需要重启
​
​
#将策略更改为Never,不会重启,直接显示error
[root@k8s-master pod]# kubectl get pods -n myns
NAME      READY   STATUS   RESTARTS   AGE
mynginx   0/1     Error    0          54s
[root@k8s-master pod]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        postStart:
          tcpSocket:
            port: 8080
  restartPolicy: Never

四.Pod生命周期内的5种状态(相位)

1.Pending

挂起状态,已经创建了pod,但没有被调度完成或者仍处于镜像拉取过程中

2.Running

运行中,pod已经被调度至受管节点,且pod要求的所有容器都已经创建完成

3.Succeeded

成功,pod中的所有容器都成功终止且不会被重启

4.Failed

失败,所有容器都停止,有一个或以上容器终止失败,容器返回非0值

5.Unknown

无法正常获取到pod状态信息,通常是网络通信问题

五.初始化容器(init container)

当需要用到主容器镜像中没有的代码或文件时、需要利用初始化容器去延缓主容器创建时间、或需要利用初始化容器去满足主容器依赖条件的情况下多用到初始化容器

1.运行初始化容器

(1)简单来说初始化容器就是在主容器执行之前要执行的工作,所以初始化容器必须完整运行完成不能失败才能执行到主容器,若运行失败,会一直被重启直到成功(理解为卡在初始化执行阶段)

(2)初始化容器严格按照定义的顺序执行,理解为第一个执行成功第二个才能开始执行

2.以一个案例进行验证初始化容器的重要性

准备创建三个容器,主容器为nginx,两个初始化容器为busybox、分别用于测试mysql和tomcat(这两个服务需要具有IP地址,仅供简单测试,两个服务并非真正启动)

(1)首先只为mysql提供一个IP地址,tomcat的还没有提供

[root@k8s-master pod]# ifconfig ens33:1 192.168.2.140 netmask 255.255.255.0 up

(2)编写文件

初始化容器中直到ping通两次指定的IP才算真正完成

[root@k8s-master pod]# cat test-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-nginx
  labels:
    name: mytest
  namespace: myns
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - name: nginx-port
      containerPort: 80
  initContainers:
  - name: test-mysql
    image: busybox
    command: ["/bin/sh","-c","until ping 192.168.2.140 -c 2; do echo preparing mysql; sleep 2; done;"]
  - name: test-tomcat
    image: busybox
    command: ["/bin/sh","-c","until ping 192.168.2.141 -c 2; do echo preparing tomcat; sleep 2; done;"]

(3)应用验证

[root@k8s-master pod]# kubectl apply -f test-nginx.yaml
[root@k8s-master pod]# kubectl get pods test-nginx -n myns   #始终位于初始化未完成状态,说明初始化容器中有未完成任务
NAME         READY   STATUS     RESTARTS   AGE
test-nginx   0/1     Init:1/2   0          2m24s
​
[root@k8s-master pod]# kubectl describe pod test-nginx -n myns  #describe查看详情
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  100s  default-scheduler  Successfully assigned myns/test-nginx to k8s-node1
  Normal  Pulling    99s   kubelet            Pulling image "busybox"
  Normal  Pulled     95s   kubelet            Successfully pulled image "busybox" in 4.515s (4.515s including waiting)
  Normal  Created    95s   kubelet            Created container test-mysql
  Normal  Started    95s   kubelet            Started container test-mysql
  Normal  Pulling    92s   kubelet            Pulling image "busybox"
  Normal  Pulled     89s   kubelet            Successfully pulled image "busybox" in 3.365s (3.365s including waiting)
  Normal  Created    89s   kubelet            Created container test-tomcat
  Normal  Started    89s   kubelet            Started container test-tomcat   
  #可以看到卡在test-tomcat初始化容器的执行上,因为我们没有为其提供可用IP地址,它无法完成文件中的command(ping不通两次)部分,也就无法进入主容器nginx的创建启动

(4)为redis提供可用IP地址,并应用验证

[root@k8s-master pod]# ifconfig ens33:2 192.168.2.141 netmask 255.255.255.0 up
[root@k8s-master pod]# kubectl get pods -n myns
NAME         READY   STATUS    RESTARTS   AGE
test-nginx   1/1     Running   0          14m
​
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  3m40s  default-scheduler  Successfully assigned myns/test-nginx to k8s-node1
  Normal  Pulling    3m39s  kubelet            Pulling image "busybox"
  Normal  Pulled     3m35s  kubelet            Successfully pulled image "busybox" in 4.515s (4.515s including waiting)
  Normal  Created    3m35s  kubelet            Created container test-mysql
  Normal  Started    3m35s  kubelet            Started container test-mysql
  Normal  Pulling    3m32s  kubelet            Pulling image "busybox"
  Normal  Pulled     3m29s  kubelet            Successfully pulled image "busybox" in 3.365s (3.365s including waiting)
  Normal  Created    3m29s  kubelet            Created container test-tomcat
  Normal  Started    3m29s  kubelet            Started container test-tomcat  #已有可用IP地址,执行完成
  Normal  Pulling    38s    kubelet            Pulling image "nginx"   #进一步执行主容器nginx的任务
  Normal  Pulled     12s    kubelet            Successfully pulled image "nginx" in 26.146s (26.146s including waiting)
  Normal  Created    12s    kubelet            Created container nginx   #主容器执行成功
  Normal  Started    12s    kubelet            Started container nginx

六.主容器(main container)

1.钩子函数简介

主要是设置来感知生命周期事件,在特定的周期阶段执行用户特定的操作,又分为启动后(post start,指容器创建之后就执行的部分,此处执行失败会重启容器)和结束前(pre stop,指容器终止运行之前执行的部分,此处执行失败会导致删除容器失败)两种。

钩子函数定义方式

(1)exec,只在容器内执行一次

apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        postStart:
          exec:
            command: ["/bin/bash","-c","cat /sdf.txt"]  #此时这个文件不存在,钩子函数执行失败
            
#换一个存在的文件就能够成功
[root@k8s-master pod]# kubectl get pods -n myns
NAME      READY   STATUS    RESTARTS   AGE
mynginx   1/1     Running   0          96s
[root@k8s-master pod]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        postStart:
          exec:
            command: ["/bin/bash","-c","ls /root"]

(2)tcpSocket,在当前的容器中尝试访问指定socket,成功后继续执行

apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        preStop:
          tcpSocket:
            port: 80

(3)httpGet,在当前的容器中向某url发起http请求,成功后继续执行

apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      lifecycle:
        preStop:
          httpGet:
            path: http://192.168.2.150
            port: 80
            
[root@k8s-master pod]# kubectl get pods -n myns
NAME      READY   STATUS    RESTARTS   AGE
mynginx   1/1     Running   0          56s

2.容器探测

主要是用于检测容器中的应用实例工作状态是否正常,不符合预期的实例就会被剔除,不分配任务。两种容器探测探针也支持exec、tcpSocket、httpGet三种检测方式,用法和钩子函数中用法基本一致。

(1)liveness probes

存活性探针,用于检测应用实例是否处于正常状态,不正常则会重启容器

(2)readiness probes

就绪性探针,用于检测应用实例是否可以进行接受请求的工作,不能则不会为其分配工作

(3)initialDelaySeconds和timeoutSeconds

initialDelaySeconds是容器启动后多少秒开始探测,timeoutSeconds是探测超时时间为多少,默认单位是秒

[root@k8s-master pod]# cat nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: mynginx
  namespace: myns
  labels:
    run: nginx
    user: sulibao
spec:
  containers:
    - name: mynginx
      image: nginx
      ports:
      - name: nginx-port
        containerPort: 80 
      livenessProbe:
        exec:
          command: ["/bin/bash","-c","ls /root"]
        initialDelaySeconds: 30
        timeoutSeconds: 5
相关推荐
探索云原生2 小时前
在 K8S 中创建 Pod 是如何使用到 GPU 的: nvidia device plugin 源码分析
ai·云原生·kubernetes·go·gpu
启明真纳2 小时前
elasticache备份
运维·elasticsearch·云原生·kubernetes
jwolf24 小时前
基于K8S的微服务:一、服务发现,负载均衡测试(附calico网络问题解决)
微服务·kubernetes·服务发现
nangonghen4 小时前
在华为云通过operator部署Doris v2.1集群
kubernetes·华为云·doris·operator
会飞的土拨鼠呀6 小时前
chart文件结构
运维·云原生·kubernetes
自在的LEE8 小时前
当 Go 遇上 Windows:15.625ms 的时间更新困局
后端·kubernetes·go
云川之下12 小时前
【k8s】访问etcd
kubernetes·etcd
warrah19 小时前
k8s迁移——岁月云实战笔记
笔记·容器·kubernetes
会飞的土拨鼠呀1 天前
Kubernetes 是什么?
云原生·容器·kubernetes
wenwenxiong1 天前
单节点calico性能优化
kubernetes