• liveness-probe探针和readness-probe


    探针

    在我们之前提到过的deploy控制器里面,他是对pod的状态进行管理,只有当pod的状态不是running的时候他才会重构pod,但是如果我们启动了一个nginx的pod,但是这个pod的index文件被删除掉了,此时pod的状态依旧是running,但是用户无法拿到正常的页面,这种情况下控制器是做不了管控的,对于这种情况,我们可以来使用探针

    liveness-probe 存活探针

    这个探针的作用是保证pod的正常运行,注意,是正常运行而不是运行,这个就是他与deploy控制器最大的区别
    我们可以使用这个探针来检测nginx容器的index.html文件是否存在,如果存在的话那么这个容器就是正常在运行的,如果不存在那么就是我们开头就提到过的那种情况,控制器看他的状态是running,但是他没有index文件,探针负责每隔一段时间就检查这个文件是否存在,如果存在就不做操作,如果不存在的话那么kebelet就会干掉这个容器并重新启动一个新的容器

    探针的3种方式

    探针有3种检测方式,分别是exec,httpGet和tcpSocket,这三种方式的定义方法都大差不差

    1. exec

    这种方式就是通过事先定义好的命令去检测,如果命令执行的结果为0那么就是正常的,如果命令的结果是非0的任何值,那么说明命令执行失败了,容器没有正常运行,需要重构容器

    copy
    • 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
    apiVersion: v1
    kind: Pod
    metadata:
    labels:
    run: nginx
    name: nginx
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    # 存活探针
    livenessProbe:
    # 执行的操作
    exec:
    # 使用test -f 命令来检测文件是否存在
    command: ["test","-f","/usr/share/nginx/html/index.html" ]
    # 在执行第一次检测之前需要等待多少秒,这里是2
    initialDelaySeconds: 2
    # 每隔多少秒触发一次检测,这里也是2
    periodSeconds: 2
    dnsPolicy: ClusterFirst
    restartPolicy: Always
    status: {}

    我们写好的yaml文件是检测index.html文件是否存在,那么我们现在来将他创建出来,然后删除index.html文件看看他会发生什么

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    [root@master k8s]# kubectl apply -f liveness-probe.yaml
    pod/nginx created
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 3s

    他现在是正常运行的,并且重启次数是0,那么我们使用命令删除掉他的index.html文件

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [root@master k8s]# kubectl exec -it nginx -- rm -f /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 60s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 62s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 1 (1s ago) 63s

    我们可以看到,在我们执行完删除命令之后,过了几秒这个容器的重启次数就是1了,然后我们再来看看index.html文件是否回来了

    copy
    • 1
    • 2
    [root@master k8s]# kubectl exec -it nginx -- ls -l /usr/share/nginx/html/index.html
    -rw-r--r-- 1 root root 615 Oct 24 13:46 /usr/share/nginx/html/index.html

    我们可以看到,这个文件确实重新回来了,为什么他会重新回来呢?
    我们之前说过,只要存活探针检测到这个文件不存在了,那么他就会直接使用之前的镜像来创建一个新的pod
    所以这个文件就又有了

    2. httpGet

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    apiVersion: v1
    kind: Pod
    metadata:
    labels:
    run: nginx
    name: nginx
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    livenessProbe:
    # 只改动了这个地方
    httpGet:
    # http请求的地址,端口
    path: /index.html
    port: 80
    initialDelaySeconds: 2
    periodSeconds: 2
    dnsPolicy: ClusterFirst
    restartPolicy: Always
    status: {}

    通过上面的yaml文件我们可以很清楚的知道,我们需要请求的是这个网站的根目录下的index.html,注意,是网站的根目录,不是linux的根目录,注意区分开

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    [root@master k8s]# kubectl apply -f liveness-probe.yaml
    pod/nginx created
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 3s

    我们还是去删除掉他的index.html文件

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [root@master k8s]# kubectl exec -it nginx -- rm -f /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 47s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 48s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 1 (0s ago) 49s

    我们可以看到,当我们删除掉这个文件之后,他请求不到index.html文件了,所以这个容器会重启

    3. tcpSocket

    这个方式就更加简单了,探针会对你定义的端口发起tcp连接,如果可以不能正常进行三次握手,那么就会重启容器

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    apiVersion: v1
    kind: Pod
    metadata:
    labels:
    run: nginx
    name: nginx
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    livenessProbe:
    tcpSocket:
    port: 81
    initialDelaySeconds: 2
    periodSeconds: 2
    dnsPolicy: ClusterFirst
    restartPolicy: Always
    status: {}

    我们直接将80端口改为81端口,nginx使用的是80端口提供服务,我们现在让他去尝试连接81端口肯定是连接不上的,我们来看看效果

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@master k8s]# kubectl apply -f liveness-probe.yaml
    pod/nginx created
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 0 8s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    nginx 1/1 Running 1 (1s ago) 9s

    这种方式比较简单,就是直接对你指定的端口发起tcp连接,能连上就代表正常,连不上那就重启

    这就是探针的3种检测方式了,接下来看就绪探针

    readness-probe 就绪探针

    这种探针跟liveness探针的区别就是,liveness会重启容器,这个探针不会,这个探针就是说,如果你的deployment的副本数为3,我这个探针依旧是检测你的index.html文件,如果这个文件不存在的话,那么我就不会将流量转发到这个pod上了,并不会重启容器,我们来看看

    这个探针依旧是那3种方式

    1. exec

    我们这里使用deployment的方式来操作,看的更加直观一点

    copy
    • 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
    • 28
    • 29
    • 30
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    name: deploy1
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: deploy1
    strategy: {}
    template:
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    readinessProbe:
    exec:
    command: ["test", "-f", "/usr/share/nginx/html/index.html"]
    initialDelaySeconds: 2
    periodSeconds: 2
    status: {}

    我们接下来的操作就是,创建这个控制器,然后进入到每个容器里面修改他的index.html文件的内容,最后再去删除某个容器的index.html文件,尝试访问

    copy
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    # 我们先将这个控制器创建出来
    [root@master k8s]# kubectl apply -f deploy1.yaml
    deployment.apps/deploy1 created
    [root@master k8s]# kubectl get pods -owide
    NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    deploy1-869c888fcd-nkqcr 1/1 Running 0 7s 10.244.104.9 node2
    deploy1-869c888fcd-qpcj6 1/1 Running 0 7s 10.244.104.12 node2
    deploy1-869c888fcd-s9gjk 1/1 Running 0 7s 10.244.166.149 node1
    # 然后我们将服务暴露出去
    [root@master k8s]# kubectl expose deployment deploy1 --port=80 --target-port=80 --type=NodePort
    service/deploy1 exposed
    [root@master k8s]# kubectl get svc
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    deploy1 NodePort 10.106.239.238 80:31268/TCP 33s
    kubernetes ClusterIP 10.96.0.1 443/TCP 30d
    # 我们将每个容器的index文件改掉
    [root@master k8s]# kubectl exec -it deploy1-869c888fcd-nkqcr -- bash
    root@deploy1-869c888fcd-nkqcr:/# echo host01 > /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl exec -it deploy1-869c888fcd-qpcj6 -- bash
    root@deploy1-869c888fcd-qpcj6:/# echo host02 > /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl exec -it deploy1-869c888fcd-s9gjk -- bash
    root@deploy1-869c888fcd-s9gjk:/# echo host03 > /usr/share/nginx/html/index.html
    root@deploy1-869c888fcd-s9gjk:/# exit
    # 然后我们通过svc暴露出来的端口来访问
    [root@master k8s]# curl localhost:31268
    host03
    [root@master k8s]# curl localhost:31268
    host02
    [root@master k8s]# curl localhost:31268
    host01
    # 我们可以发现他会将流量转发到每一个pod上,此时我们来删除第一个容器的index.html文件
    [root@master k8s]# kubectl exec -it deploy1-869c888fcd-nkqcr -- rm -f /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    deploy1-869c888fcd-nkqcr 0/1 Running 0 9m42s
    deploy1-869c888fcd-qpcj6 1/1 Running 0 9m42s
    deploy1-869c888fcd-s9gjk 1/1 Running 0 9m42s

    这个时候我们看到第一个pod的read状态是0/1了,我们再来尝试访问

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    [root@master k8s]# curl localhost:31268
    host02
    [root@master k8s]# curl localhost:31268
    host02
    [root@master k8s]# curl localhost:31268
    host02
    [root@master k8s]# curl localhost:31268
    host03

    可以看到我们现在无论怎么访问他都不会将流量转发到这个pod上了

    2. httpGet

    这种方式的定义跟之前的定义方式一样

    copy
    • 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
    • 28
    • 29
    • 30
    • 31
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    name: deploy1
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: deploy1
    strategy: {}
    template:
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    readinessProbe:
    httpGet:
    path: /index.html
    port: 80
    initialDelaySeconds: 2
    periodSeconds: 2
    status: {}
    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    [root@master k8s]# kubectl apply -f deploy1.yaml
    deployment.apps/deploy1 created
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    deploy1-6757fdb6d9-dl7fc 1/1 Running 0 3s
    deploy1-6757fdb6d9-mrttl 1/1 Running 0 3s
    deploy1-6757fdb6d9-zkj5b 1/1 Running 0 3s

    我们还是同样删除一个容器里的index.html,其他效果就不演示了,只看他的状态就知道了

    copy
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    [root@master k8s]# kubectl exec -it deploy1-6757fdb6d9-dl7fc -- rm -f /usr/share/nginx/html/index.html
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    deploy1-6757fdb6d9-dl7fc 1/1 Running 0 78s
    deploy1-6757fdb6d9-mrttl 1/1 Running 0 78s
    deploy1-6757fdb6d9-zkj5b 1/1 Running 0 78s
    [root@master k8s]# kubectl get pods
    NAME READY STATUS RESTARTS AGE
    deploy1-6757fdb6d9-dl7fc 0/1 Running 0 79s
    deploy1-6757fdb6d9-mrttl 1/1 Running 0 79s
    deploy1-6757fdb6d9-zkj5b 1/1 Running 0 79s

    可以看得到,ready那里已经变成0/1了也就是他不会在有流量转发到他这里了

    3. tcpSocket

    copy
    • 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
    • 28
    • 29
    • 30
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    name: deploy1
    spec:
    replicas: 3
    selector:
    matchLabels:
    app: deploy1
    strategy: {}
    template:
    metadata:
    creationTimestamp: null
    labels:
    app: deploy1
    spec:
    containers:
    - image: nginx
    imagePullPolicy: IfNotPresent
    name: nginx
    resources: {}
    readinessProbe:
    tcpSocket:
    port: 80
    initialDelaySeconds: 2
    periodSeconds: 2
    status: {}

    也是这样定义的,这个我就不演示了,效果跟前俩是一样的,tcp连接不上的话ready就会变成0

    综述:虽然我这里全部都是使用nginx镜像,但是我们一般会使用exec来检测配置文件是否存在,使用httpGet来检测一些网站类的容器,使用tcpSocket来对开放了端口的容器进行检测

    本文作者:FuShudi

    本文链接:https://www.cnblogs.com/fsdstudy/p/18010183

    版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

  • 相关阅读:
    Linux之vim的使用详细解析
    搜素专题(DFS )
    【C#】转换8位或16位像素值为Bitmap
    Java字符串简介
    c++类和对象实现日期的相关操作
    蓝桥杯每日一题2023.10.25
    Linux磁盘管理
    自己编译静态ffmpeg freetype2 not found问题解决
    OpenResty安装
    装饰模式与职责链模式笔记
  • 原文地址:https://www.cnblogs.com/fsdstudy/p/18010183