Kubernetes之探针

Kubernetes之探针-----容器的监控检查及恢复机制

在kubernetes中当pod被调度到node节点以后,会在pod中创建定义的容器。容器的健康状态就非常重要了,决定着pod这个资源是否可以正常提供服务。在k8s中并不是以容器是否创建成功来作为判断pod是否正常的依据。而是根据容器内应用是否正常运行来作为判断依据。当发现容器里面的应用发生故障之后而自动触发恢复机制,也就是pod的重启策略(实际就是重新创建了pod),用来实现服务的正常运行。所以对容器的监控检查就至关重要了。

kubernetes中支持启动startupProbe和就绪readinessProbe还有存活livenessProbe(启动探针)三种种探针

startupProbe(启动探针): 指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet将杀死容器,容器服从其重启策略进行重启。如果容器没有提供启动探测,则默认状态为成功Success。

livenessProbe(存活探针):指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略
的影响。如果容器不提供存活探针,则默认状态为 Success。

readinessProbe(就绪探针):指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为Success。
就绪探针(Readiness Probe):

问题:一个新Pod创建后,Service就能立即选择到它,并会把请求转发给Pod,那问题就来了,通常一个Pod启动是需要时间的,如果Pod还没准备好(可能需要时间来加载配置或数据,或者可能需要执行一个预热程序之类),这时把请求转给Pod的话,Pod也无法处理,造成请求失败。

解决这个问题的方法就是给Pod加一个业务就绪探针Readiness Probe,当检测到Pod就绪后才允许Service将请求转给Pod。
存活探针(livenessProbe):

Kubernetes提供了自愈的能力,具体就是能感知到容器崩溃,然后能够重启这个容器。但是有时候例如Java程序内存泄漏了,程序无法正常工作,但是JVM进程却是一直运行的,对于这种应用本身业务出了问题的情况,Kubernetes提供了Liveness Probe机制,为 Pod 里的容器定义一个健康检查"探针"(Probe)。kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器是否运行(来自 Docker 返回的信息)作为依据。这种机制,是生产环境中保证应用健康存活的重要手段。

探针的定义方式

Exec:Probe执行容器中的命令并检查命令退出的状态码,如果状态码为0则说明已经就绪。
HTTP GET:往容器的IP:Port发送HTTP GET请求,如果Probe收到2xx或3xx,说明已经就绪。
TCP Socket:尝试与容器建立TCP连接,如果能建立连接说明已经就绪。
探针探测结果有以下值:
1、Success:表示通过检测。
2、Failure:表示未通过检测。
3、Unknown:表示检测没有正常进行。

启动探针-startupprobe

exec:
通过指定命令执行的返回值判断容器是否启动

[root@k8s-master test]# cat test-start-exec.yml 
apiVersion: v1
kind: Pod
metadata:
 name: pod-1
 labels:
  web: nginx
spec:
 containers:
  - name: nginx-1
    image: daocloud.io/library/nginx
    ports:
     - name: http
       containerPort: 80
    startupProbe: #定义启动探针进行健康检查
     exec: #指定使用的类型为命令类型
      command:
       - "/bin/bash"
       - "-c"
       - "cat /usr/share/nginx/html/index.html"
     initialDelaySeconds: 5 #健康检查,在容器启动5s后开始执行,单位“秒”,默认是 0 秒
     periodSeconds: 5 #执行探测的时间间隔(单位是秒),默认为 10s,单位“秒”,最小值是1
     timeoutSeconds: 2 #表示容器必须在2s内做出相应反馈给probe,否则视为探测失败,默认值为1
     successThreshold: 1 #连续探测几次成功,才认为探测成功,探测1次成功表示成功,最小值为1。
     failureThreshold: 3 #探测失败的重试次数,重试一定次数后将认为失败,默认为 3,最小值为 1
     
[root@k8s-master test]# kubectl get pod -w 
NAME    READY   STATUS    RESTARTS        AGE
pod-1   0/1     Pending   0               0s
pod-1   0/1     Pending   0               0s
pod-1   0/1     ContainerCreating   0               0s
pod-1   0/1     ContainerCreating   0               0s
pod-1   0/1     Running             0               1s
pod-1   1/1     Running             0               10s #等待10秒后后检查成功进入ready状态

httpget模式
[root@k8s-master test]# cat test-start-http.yml
apiVersion: v1
kind: Pod
metadata:
 name: pod-8
 labels:
  web: nginx
spec:
 containers:
  - name: nginx-tcp
    image: daocloud.io/library/nginx
    ports:
     - name: http
       containerPort: 80
    startupProbe:
      httpGet: #指定使用的类型为http请求
       scheme: HTTP #指定请求的协议
       port: 80 #指定请求的端口
       path: "/index.html" #指定请求的路径
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 2
      successThreshold: 1
      failureThreshold: 3

[root@k8s-master test]# kubectl get pod -w 
NAME    READY   STATUS    RESTARTS        AGE
pod-8   0/1     Pending   0               0s
pod-8   0/1     Pending   0               0s
pod-8   0/1     ContainerCreating   0               0s
pod-8   0/1     ContainerCreating   0               1s
pod-8   0/1     Running             0               2s
pod-8   0/1     Running             0               16s
pod-8   1/1     Running             0               16s

存活探针(livenessProbe)------命令模式探针:

Kubernetes 文档中的例子:

[root@kub-k8s-master ~]# cd prome/
[root@kub-k8s-master prome]# vim test-liveness-exec.yaml
---
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: test-liveness-exec
spec:
  containers:
  - name: liveness
    image: daocloud.io/library/nginx
    args:
    - /bin/sh
    - -c  
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 50
    livenessProbe:
      exec:
        command: 
        - cat 
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5
它在启动之后做的第一件事是在/tmp目录下创建了一个healthy文件,以此作为自己已经正常运行的标志。而30s过后,它会把这个文件删除掉。
与此同时,定义了一个这样的 livenessProbe(健康检查)。它的类型是 exec,它会在容器启动后,在容器里面执行一句我们指定的命令,比如:"cat /tmp/healthy"。这时,如果这个文件存在,这条命令的返回值就是 0,Pod就会认为这个容器不仅已经启动,而且是健康的。这个健康检查,在容器启动5s后开始执行(initialDelaySeconds: 5),每5s执行一次(periodSeconds: 5)。

创建Pod:

[root@kub-k8s-master prome]# kubectl apply -f test-liveness-exec.yaml 
pod/test-liveness-exec created

查看 Pod 的状态:

[root@kub-k8s-master prome]# kubectl get pod 
NAME                    READY   STATUS    RESTARTS   AGE
nginx-configmap         1/1     Running   0          16h
nginx-pod               1/1     Running   0          12h
test-liveness-exec      1/1     Running   0          75s

由于已经通过了健康检查,这个 Pod 就进入了 Running 状态。

然后30 s 之后,再查看一下 Pod 的 Events:

[root@kub-k8s-master prome]# kubectl describe pod test-liveness-exec 

发现,这个 Pod 在 Events 报告了一个异常:

Events:
  Type     Reason     Age                  From                    Message
  ----     ------     ----                 ----                    -------
Warning  Unhealthy  54s (x9 over 3m34s)  kubelet, kub-k8s-node1  Liveness probe failed: cat: /tmp/healthy: No such file or directory

这个健康检查探查到 /tmp/healthy 已经不存在了,所以它报告容器是不健康的。那么接下来会发生什么呢?

再次查看一下这个 Pod 的状态:

[root@kub-k8s-master prome]# kubectl get pod test-liveness-exec
NAME                 READY   STATUS    RESTARTS   AGE
test-liveness-exec   1/1     Running   4          5m19s

这时发现,Pod 并没有进入 Failed 状态,而是保持了 Running 状态。这是为什么呢?

RESTARTS 字段从 01 的变化,就明白原因了:这个异常的容器已经被 Kubernetes 重启了。在这个过程中,Pod 保持 Running 状态不变。

#注
k8s 中并没有 Docker 的 Stop 语义。所以如果容器被探针检测到有问题,查看状态虽然看到的是 Restart,但实际却是重新创建了容器。

这个功能就是 Kubernetes 里的Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建。

小提示:

    Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去。  
http get方式探针
[root@kub-k8s-master prome]# vim liveness-httpget.yaml
---
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
    - name: liveness-exec-container
      image: daocloud.io/library/nginx
      imagePullPolicy: IfNotPresent
      ports:
        - name: http
          containerPort: 80
      livenessProbe: 
        httpGet:
          port: http
          path: /index.html
        initialDelaySeconds: 1
        periodSeconds: 3
        timeoutSeconds: 2          
        successThreshold: 1 
        failureThreshold: 3

创建该pod

[root@kub-k8s-master prome]# kubectl create -f liveness-httpget.yaml 
pod/liveness-httpget-pod created 

查看当前pod的状态

[root@kub-k8s-master prome]# kubectl describe pod liveness-httpget-pod
...
Liveness:       http-get http://:http/index.html delay=1s timeout=1s period=3s #success=1 #failure=3
... 

登陆容器

测试将容器内的index.html删除掉
[root@kub-k8s-master prome]# kubectl exec -it liveness-httpget-pod /bin/bash
root@liveness-httpget-pod:/# mv /usr/share/nginx/html/index.html index.html
root@liveness-httpget-pod:/# command terminated with exit code 137
可以看到,当把index.html移走后,这个容器立马就退出了。

此时,查看pod的信息

[root@kub-k8s-master prome]# kubectl describe pod liveness-httpget-pod
...
Normal   Killing    49s                  kubelet, kub-k8s-node2  Container liveness-exec-container failed liveness probe, will be restarted
  Normal   Pulled     49s                  kubelet, kub-k8s-node2  Container image "daocloud.io/library/nginx" already present on machine
...

看输出,容器由于健康检查未通过,pod会被杀掉,并重新创建

[root@kub-k8s-master prome]#  kubectl get pods
NAME                    READY   STATUS             RESTARTS   AGE
lifecycle-demo          1/1     Running            1          34h
liveness-httpget-pod    1/1     Running            1          5m42s

#restarts 为 1

重新登陆容器,发现index.html又出现了,证明容器是被重拉了。

[root@kub-k8s-master prome]# kubectl exec -it liveness-httpget-pod /bin/bash
root@liveness-httpget-pod:/# cat /usr/share/nginx/html/index.html

在生产环境最好是一块使用,尤其是就绪和存活探针共用。

Pod的重启策略

Pod 的重启策略:
可以通过设置 restartPolicy,改变 Pod 的恢复策略。一共有3种:
    1. Always:      在任何情况下,只要容器不在运行状态,就自动重启容器;
    2. OnFailure:    只在容器 异常时才自动重启容器;
    3. Never:         从来不重启容器。
实际使用时,需要根据应用运行的特性,合理设置这三种恢复策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值