k8s核心资源Pod-主容器之存活性探测

一、Pod生命周期------主容器之探针

是什么及作用

容器探测用于检测容器中的应用实例是否正常工作,是保障业务可用性的一种传统机制。

如果经过探测,实例的状态不符合预期,那么kubernetes就会把该问题实例" 摘除 ",不承担业务流量。

探针的分类

kubernetes提供了几种探针来实现容器探测,分别是:

  • liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器

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

  • startup probes:启动探针

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

二、Pod生命周期------主容器之存活性探测

存活性探测的案例

下面以liveness probes为例,做几个演示:

方式一、exec

创建pod-liveness-exec.yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-exec
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      exec:
        # 因为/root/123默认不存在,因此存活性探测失败,将一直重启
        command: ["/bin/cat","/root/123"]
        # 如果采用下面这行的command,将存活性探测成功,不会重启
        # command: ["/bin/sh", "-c", "echo helloworld >> /usr/share/nginx/html/index.html"]

创建查看效果

复制代码
[root@master ~]# kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created
​
​
[root@master ~]# kubectl describe pods pod-liveness-exec -n test
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  44s               default-scheduler  Successfully assigned lh/pod-liveness-exec to node2.example.com
  Warning  Failed     42s               kubelet            Failed to pull image "nginx:latest": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/nginx:latest": failed to resolve reference "docker.io/library/nginx:latest": failed to authorize: failed to fetch anonymous token: Get "https://auth.docker.io/token?scope=repository%3Alibrary%2Fnginx%3Apull&service=registry.docker.io": read tcp 192.168.226.30:57024->44.205.64.79:443: read: connection reset by peer
  Warning  Failed     42s               kubelet            Error: ErrImagePull
  Normal   BackOff    41s               kubelet            Back-off pulling image "nginx:latest"
  Warning  Failed     41s               kubelet            Error: ImagePullBackOff
  Normal   Pulled     25s               kubelet            Successfully pulled image "nginx:latest" in 2.854548687s
  Warning  Unhealthy  4s (x3 over 24s)  kubelet            Liveness probe failed: /bin/cat: /root/123: No such file or directory
  Normal   Killing    4s                kubelet            Container nginx failed liveness probe, will be restarted
  Normal   Pulling    3s (x3 over 43s)  kubelet            Pulling image "nginx:latest"
  Normal   Created    1s (x2 over 25s)  kubelet            Created container nginx
  Normal   Started    1s (x2 over 24s)  kubelet            Started container nginx
  Normal   Pulled     1s                kubelet            Successfully pulled image "nginx:latest" in 2.645598698s
[root@master ~]# kubectl get pod pod-liveness-exec -n test -o wide -w
NAME                READY   STATUS             RESTARTS      AGE
pod-liveness-exec   0/1     CrashLoopBackOff   4 (31s ago)   3m11s

观察上面的信息就会发现nginx容器启动之后就进行了健康检查 检查失败之后,容器被kill掉,然后尝试进行重启,等待一下,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长

方式二、tcpsocket

创建pod-liveness-tcpsocket.yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-tcpsocket
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    ports: 
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      tcpSocket:
        # 如果以8080端口为存活性探测,会因探测失败,而自动重启容器
        port: 8080
        # 如果以80端口为存活性探测,会探测成功,不会重启容器

创建并查看效果

复制代码
[root@master ~]# kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created
​
[root@master ~]# kubectl describe pods pod-liveness-tcpsocket -n test
.........
Events:
  Type     Reason     Age               From               Message
  ----     ------     ----              ----               -------
  Normal   Scheduled  20s               default-scheduler  Successfully assigned lh/pod-liveness-tcpsocket to node2.example.com
  Normal   Pulling    20s               kubelet            Pulling image "nginx:latest"
  Normal   Pulled     17s               kubelet            Successfully pulled image "nginx:latest" in 2.943589962s
  Normal   Created    17s               kubelet            Created container nginx
  Normal   Started    17s               kubelet            Started container nginx
  Warning  Unhealthy  0s (x2 over 10s)  kubelet            Liveness probe failed: dial tcp 10.244.2.20:8080: connect: connection refused
[root@master ~]# kubectl get pod -n test -o wide -w
NAME                     READY   STATUS             RESTARTS        AGE
pod-liveness-tcpsocket   0/1     CrashLoopBackOff   4 (11s ago)     2m41s

观察上面的信息,发现尝试访问8080端口,但是失败了稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长,当然如果将端口修改成能访问的端口就恢复正常了

方式三、httpget

创建pod-liveness-httpget.yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness-httpget
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      # http://127.0.0.1:80/hello,这个地址是不存在的404,存活性探测失败而重启
      httpGet: 
        scheme: HTTP 
        port: 80 
        path: /hello 

创建pod观看效果

复制代码
[root@master ~]# kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created
[root@master ~]#  kubectl describe pod pod-liveness-httpget -n test
Events:
  Type     Reason     Age   From               Message
  ----     ------     ----  ----               -------
  Normal   Scheduled  18s   default-scheduler  Successfully assigned lh/pod-liveness-httpget to node1.example.com
  Normal   Pulling    16s   kubelet            Pulling image "nginx:latest"
  Normal   Pulled     13s   kubelet            Successfully pulled image "nginx:latest" in 2.661896334s
  Normal   Created    13s   kubelet            Created container nginx
  Normal   Started    13s   kubelet            Started container nginx
  Warning  Unhealthy  6s    kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404

观察上面信息,尝试访问路径,但是未找到,出现404错误# 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长

复制代码
[root@master ~]# kubectl get pod -n test -o wide -w
NAME                     READY   STATUS             RESTARTS         AGE
pod-liveness-httpget     1/1     Running            2 (6s ago)       68s
# 当然接下来,可以修改成一个可以访问的路径path,比如/,再试,结果就正常了......

至此,已经使用liveness Probe演示了三种探测方式。

存活性探测的衍生讨论

查看livenessProbe的子属性,会发现除了这三种方式,还有一些其他的配置,在这里一并解释下:

复制代码
[root@master ~]# kubectl explain pod.spec.containers.livenessProbe
FIELDS:
   exec <Object>  
   tcpSocket    <Object>
   httpGet      <Object>
   initialDelaySeconds  <integer>  # 容器启动后等待多少秒执行第一次探测
   timeoutSeconds       <integer>  # 探测超时时间。默认1秒,最小1秒
   periodSeconds        <integer>  # 执行探测的频率。默认是10秒,最小1秒
   failureThreshold     <integer>  # 连续探测失败多少次才被认定为失败。默认是3。最小值是1
   successThreshold     <integer>  # 连续探测成功多少次才被认定为成功。默认是1

下面稍微配置两个,演示下效果即可:

创建yaml文件,pod-liveness.yaml

复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-liveness
  namespace: test
spec:
  containers:
  - name: nginx
    image: nginx:1.18
    ports:
    - name: nginx-port
      containerPort: 80
    livenessProbe:
      httpGet:
        scheme: HTTP
        port: 80 
        path: /
      initialDelaySeconds: 30 # 容器启动后30s开始探测
      timeoutSeconds: 5 # 探测超时时间为5s
复制代码
kubectl apply -f pod-liveness.yaml
​
#查看pod-liveness这个pod的状态
kubectl get pod -n test -o wide -w
​
#发现过30秒才开始存活性探测
相关推荐
兴趣使然黄小黄1 小时前
【Docker】Docker架构详解:核心组件及其应用指南
docker·容器·架构
小二·2 小时前
Go 语言系统编程与云原生开发实战(第21篇)
开发语言·云原生·golang
小二·2 小时前
Go 语言系统编程与云原生开发实战(第20篇)
开发语言·云原生·golang
shughui13 小时前
Docker Desktop下载、安装、配置、使用
运维·docker·容器·自动化
EverydayJoy^v^17 小时前
Kubernetes 知识点(1)——基础依赖
云原生·容器·kubernetes
hopsky17 小时前
Docker Compose 启动的容器内存 监控
docker·容器·eureka
FrameNotWork20 小时前
多设备 Android Logcat 自动采集方案:基于 Docker + Shell 实现日志按天切割与自动清理
android·docker·容器
Haoea!20 小时前
Docker + Harbor 私有镜像仓库搭建
运维·docker·容器
iambooo20 小时前
Docker 架构与核心原理深度解析:容器到底是怎么实现的?
运维·docker·容器