k8s探测机制之pod健康检查

发布时间:2020-06-26 20:58:20 作者:wx5b9c94b17c62a
来源:网络 阅读:898

一:需求来源:

首先来看一下,整个需求的来源:当把应用迁移到 Kubernetes 之后,要如何去保障应用的健康与稳定呢?其实很简单,可以从两个方面来进行增强:

1,首先是提高应用的可观测性;
2,第二是提高应用的可恢复能力。

从可观测性上来讲,可以在三个方面来去做增强:

1,首先是应用的健康状态上面,可以实时地进行观测;
2,第二个是可以获取应用的资源使用情况;
3,第三个是可以拿到应用的实时日志,进行问题的诊断与分析。

当出现了问题之后,首先要做的事情是要降低影响的范围,进行问题的调试与诊断。最后当出现问题的时候,理想的状况是:可以通过和 K8s 集成的自愈机制进行完整的恢复。

二:介绍两种探测方式:livenessProbe和ReadnessProbe

什么是Endpoint?
Endpoint是k8s集群中的一个资源对象,存储在etcd中,用来记录一个service对应的所有pod的访问地址。

2,Liveness和Readness两种探测机制的使用场景:
Liveness 指针适用场景是支持那些可以重新拉起的应用,而 Readiness 指针主要应对的是启动之后无法立即对外提供服务的这些应用。

3,,Liveness和Readness两种探测机制的相同点和不同点:
相同点是根据探测pod内某个应用或文件,来检查pod的健康状况,不同点是liveness如果探测失败会重启pod,而readliness则在连续3次探测失败之后,会将pod设置为不可用的状态,并不会重启pod。

4,Liveness 指针和 Readiness 指针支持三种不同的探测方式:

第一种探测方式和第三种非常相似,一般常用的是第一和第二种的探测方式。

三,探测机制应用实例:

1,LivenessProbe:

方法1:使用exec探测方式,查看pod内某个指定的文件是否存在,如果存在则认为状态为健康的,否则会根据设置的重启重启策略重启pod。

###pod的配置文件:

[root@sqm-master yaml]# vim livenss.yaml
kind: Pod
apiVersion: v1
metadata:
  name: liveness
  labels:
    name: liveness
spec:
  restartPolicy: OnFailure    ##定义重启策略,仅在pod对象出现错误时才重启
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300  #创建文件,并且在30秒后将文件进行删除
    livenessProbe:      #执行活跃度探测
      exec:
        command:
        - cat              #探测/tmp目录下是有test文件,如果有则代表健康,如果没有则执行重启pod策略。
        - /tmp/test
      initialDelaySeconds: 10        #当容器运行多久之后开始探测(单位是s)
      periodSeconds: 5     #探测频率(单位s),每隔5秒探测一次。

探测机制中其他的可选字段:

//运行该pod进行测试:
[root@sqm-master yaml]# kubectl  apply -f  livenss.yaml 
pod/liveness created

//监测pod的状态:
会在容器启动10秒后开始探测,且每5s探测一次。
k8s探测机制之pod健康检查
我们可以看到pod一直在重启中,从上图看到RESTARTS
的次数已经为7次了,原因是在启动pod时执行了该命令:

/bin/sh -c "touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300"

在容器生命的最初30秒内有一个 /tmp/test 文件,在这30秒内 cat /tmp/test命令会返回一个成功的返回码。但30秒后, cat /tmp/test 将返回失败的返回码,会触发pod的重启策略。

//我们来查看一下pod的Events信息:
[root@sqm-master ~]# kubectl  describe  pod liveness 

k8s探测机制之pod健康检查
从上面的事件中可以发现,探测失败,将重启容器,原因是在指定的目录下没有发现该文件。

方法2:使用httpGet探测方式,运行一个web服务,探测web网页的根目录下是否有指定的文件,也就等同于 “curl -I 容器ip地址:/healthy”。(这里的目录/,指定的是容器内提供web服务的主目录。)

//pod的yaml文件:

[root@sqm-master yaml]# vim http-livenss.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    name: mynginx
spec:
  restartPolicy: OnFailure      #定义pod重启策略
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    livenessProbe:       #定义探测机制
      httpGet:               #探测方式为httpGet
        scheme: HTTP    #指定协议
        path: /healthy       #指定路径下的文件,如果不存在,探测失败
        port: 80
      initialDelaySeconds: 10       #当容器运行多久之后开始探测(单位是s)
      periodSeconds: 5       #探测频率(单位s),每隔5秒探测一次
---
apiVersion: v1       #关联一个service对象
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    name: mynginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

httpGet探测方式有如下可选的控制字段:

//运行该pod:
[root@sqm-master yaml]# kubectl  apply -f  http-livenss.yaml 
pod/web created
service/web-svc created

##查看pod运行10秒前的情况:
k8s探测机制之pod健康检查
##最开始的10秒该容器是活着的,且返回的状态码为200.
k8s探测机制之pod健康检查

###10秒后当探测机制开始探测时再次查看pod的情况:
k8s探测机制之pod健康检查

//查看的pod的events:
[root@sqm-master yaml]# kubectl describe  pod web 

k8s探测机制之pod健康检查

可以看到返回的状态码为404,表示在网页的根目录下并没有找到指定的文件,表示探测失败,且重启4次,状态是completed(完成的状态),说明pod是存在问题的。

2)接下来我们继续进行检测,使其最终探测成功:
修改pod的配置文件:
[root@sqm-master yaml]# vim http-livenss.yaml
k8s探测机制之pod健康检查

//重新运行pod:
[root@sqm-master yaml]# kubectl  delete -f  http-livenss.yaml 
pod "web" deleted
service "web-svc" deleted
[root@sqm-master yaml]# kubectl apply -f  http-livenss.yaml 
pod/web created
service/web-svc created
//最终我们查看pod的状态及Events信息:
[root@sqm-master yaml]# kubectl  get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web    1/1     Running   0          5s    10.244.1.11   node01   <none>           <none>
[root@sqm-master yaml]# kubectl  describe  pod web 
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  71s   default-scheduler  Successfully assigned default/web to node01
  Normal  Pulling    71s   kubelet, node01    Pulling image "nginx"
  Normal  Pulled     70s   kubelet, node01    Successfully pulled image "nginx"
  Normal  Created    70s   kubelet, node01    Created container nginx
  Normal  Started    70s   kubelet, node01    Started container nginx

可以看到pod的状态时正常运行的。

##测试访问网页头部信息:
[root@sqm-master yaml]# curl -I 10.244.1.11

k8s探测机制之pod健康检查
返回的状态码为200,表示这个pod的状况时健康的。

ReadnessProbe探测:

方法1:使用exec探测方式,与iveness相同,探测某个文件是否存在。
//pod的配置文件如下:

[root@sqm-master yaml]# vim readiness.yaml
kind: Pod
apiVersion: v1
metadata:
  name: readiness
  labels:
    name: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 30; rm -rf /tmp/test; sleep 300;
    readinessProbe:   #定义readiness探测方式
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10
      periodSeconds: 5
//运行该pod:
[root@sqm-master yaml]# kubectl apply -f  readiness.yaml 
pod/readiness created

//检测pod的状态:
k8s探测机制之pod健康检查

//查看pod的Events:
[root@sqm-master yaml]# kubectl  describe  pod readiness 

k8s探测机制之pod健康检查
可以看到找不到该文件,表示探测失败,但是readiness机制与liveness机制不同,它并不会重启pod,而是连续探测3次失败后,则将容器设置为不可用的状态。

方法二:httpGet方式。

[root@sqm-master yaml]# vim http-readiness.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web2
  labels:
    name: web2
spec:
  containers:
  - name: web2
    image: nginx
    ports:
    - containerPort: 81
    readinessProbe:
      httpGet:
        scheme: HTTP    #指定协议
        path: /healthy    #指定路径,如果不存在,则需要进行创建,否则探测失败
        port: 81
      initialDelaySeconds: 10
      periodSeconds: 5
---     
apiVersion: v1       
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    name: web2
  ports:
  - protocol: TCP
    port: 81             
    targetPort: 81
//运行pod:
[root@sqm-master yaml]# kubectl apply -f  http-readiness.yaml 
pod/web2 created
service/web-svc created
//查看pod的状态:
[root@sqm-master yaml]# kubectl  get pod -o wide
NAME        READY   STATUS      RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
readiness   0/1     Completed   0          37m     10.244.2.12   node02   <none>           <none>
web         1/1     Running     0          50m     10.244.1.11   node01   <none>           <none>
web2        0/1     Running     0          2m31s   10.244.1.14   node01   <none>           <none>

k8s探测机制之pod健康检查
查看pod的Events信息,通过探测,可以知道pod是不健康的,且http访问失败。
它并不会重启,而是直接将pod设置为不可用的状态。

健康检测在滚动更新过程中的应用:

首先我们通过explain工具来查看更新使用的字段:

[root@sqm-master ~]#  kubectl  explain deploy.spec.strategy.rollingUpdate

k8s探测机制之pod健康检查
可以看到在滚动更新的过程中有两个参数可用:

maxSurge和maxUnavailable的适用场景:
1,如果您希望在保证系统可用性和稳定性的前提下尽可能快地进行升级,可以将 maxUnavailable 设置为 0,同时为 maxSurge 赋予一个较大值。
2,如果系统资源比较紧张,pod 负载又比较低,为了加快升级速度,可以将 maxSurge 设置为 0,同时为 maxUnavailable 赋予一个较大值。需要注意的是,如果 maxSurge 为 0maxUnavailable 为 DESIRED,可能造成整个服务的不可用,此时 RollingUpdate 将退化成停机发布
1)首先我们创建一个deployment资源对象:

[root@sqm-master ~]# vim app.v1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-web
spec:
  replicas: 10              #定义副本数量为10个
  template:
    metadata:
      labels:
        name: my-web
    spec:
       containers:
        - name: my-web
          image: nginx
          args:
          - /bin/sh
          - -c
          - touch /usr/share/nginx/html/test.html; sleep 300000; #创建文件,使其在探测时保持pod为健康状态
          ports:
          - containerPort: 80
          readinessProbe:       #使用readiness机制
            exec:
              command:
              - cat
              - /usr/share/nginx/html/test.html
            initialDelaySeconds: 10
            periodSeconds: 10
//运行该pod后,查看pod数量(10个):
[root@sqm-master yaml]# kubectl  get pod -o wide
NAME                      READY   STATUS      RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
my-web-7bbd55db99-2g6tp   1/1     Running     0          2m11s   10.244.2.44   node02   <none>           <none>
my-web-7bbd55db99-2jdbz   1/1     Running     0          118s    10.244.2.45   node02   <none>           <none>
my-web-7bbd55db99-5mhcv   1/1     Running     0          2m53s   10.244.1.40   node01   <none>           <none>
my-web-7bbd55db99-77b4v   1/1     Running     0          2m      10.244.1.44   node01   <none>           <none>
my-web-7bbd55db99-h888n   1/1     Running     0          2m53s   10.244.2.41   node02   <none>           <none>
my-web-7bbd55db99-j5tgz   1/1     Running     0          2m38s   10.244.2.42   node02   <none>           <none>
my-web-7bbd55db99-kjgm2   1/1     Running     0          2m25s   10.244.1.42   node01   <none>           <none>
my-web-7bbd55db99-kkmh3   1/1     Running     0          2m38s   10.244.1.41   node01   <none>           <none>
my-web-7bbd55db99-lr896   1/1     Running     0          2m13s   10.244.1.43   node01   <none>           <none>
my-web-7bbd55db99-rpd8v   1/1     Running     0          2m23s   10.244.2.43   node02   <none>       

探测成功,10个副本全部运行。

2)第一次更新:
更新nginx镜像版本,且设置滚动更新策略:

[root@sqm-master yaml]# vim app.v1.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-web
spec: 
  strategy:       #设置滚动更新策略,通过该字段下的rollingUpdate的子属性来设置
    rollingUpdate:
      maxSurge: 3                 #指定在滚动更新过程中最多可创建3个额外的 pod
      maxUnavailable: 3     #- 指定在滚动更新过程中最多允许3 pod 不可用
  replicas: 10              
  template:
    metadata:
      labels:
        name: my-web
    spec:
       containers:
        - name: my-web
          image: 172.16.1.30:5000/nginx:v2.0    #更新的镜像为私有仓库中的镜像nginx:v2.0
          args:
          - /bin/sh
          - -c
          - touch /usr/share/nginx/html/test.html; sleep 300000; 
          ports:
          - containerPort: 80
          readinessProbe:       
            exec:
              command:
              - cat
              - /usr/share/nginx/html/test.html
            initialDelaySeconds: 10
            periodSeconds: 10
//执行yaml文件后,查看pod数量:
[root@sqm-master yaml]# kubectl  get pod -o wide
NAME                      READY   STATUS      RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
my-web-7db8b88b94-468zv   1/1     Running     0          3m38s   10.244.2.57   node02   <none>           <none>
my-web-7db8b88b94-bvszs   1/1     Running     0          3m24s   10.244.1.60   node01   <none>           <none>
my-web-7db8b88b94-c4xvv   1/1     Running     0          3m38s   10.244.2.55   node02   <none>           <none>
my-web-7db8b88b94-d5fvc   1/1     Running     0          3m38s   10.244.1.58   node01   <none>           <none>
my-web-7db8b88b94-lw6nh   1/1     Running     0          3m21s   10.244.2.59   node02   <none>           <none>
my-web-7db8b88b94-m9gbh   1/1     Running     0          3m38s   10.244.1.57   node01   <none>           <none>
my-web-7db8b88b94-q5dqc   1/1     Running     0          3m38s   10.244.1.59   node01   <none>           <none>
my-web-7db8b88b94-tsbmm   1/1     Running     0          3m38s   10.244.2.56   node02   <none>           <none>
my-web-7db8b88b94-v5q2s   1/1     Running     0          3m21s   10.244.1.61   node01   <none>           <none>
my-web-7db8b88b94-wlgwb   1/1     Running     0          3m25s   10.244.2.58   node02   <none>           <none>
//查看pod的版本信息:
[root@sqm-master yaml]# kubectl  get deployments. -o wide
NAME     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                        SELECTOR
my-web   10/10   10           10          49m   my-web       172.16.1.30:5000/nginx:v2.0   name=my-web

探测成功,10个pod版本全部更新成功。

3)第二次更新:
将镜像版本更新为3.0版本,且设置滚动更新策略。(探测失败)
pod的配置文件如下:

[root@sqm-master yaml]# vim app.v1.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-web
spec:
  strategy:
    rollingUpdate:
      maxSurge: 3                  #定义更新策略,数量依然都是保持3个
      maxUnavailable: 3
  replicas: 10                       #pod数量依然是10个
  template:
    metadata:
      labels:
        name: my-web
    spec:
       containers:
        - name: my-web
          image: 172.16.1.30:5000/nginx:v3.0   #测试镜像版本更新为3.0
          args:
          - /bin/sh
          - -c
          - sleep 300000;        #不在创建指定文件,使其探测失败
          ports:
          - containerPort: 80
          readinessProbe:       
            exec:
              command:
              - cat
              - /usr/share/nginx/html/test.html
            initialDelaySeconds: 10
            periodSeconds: 5
//重新运行pod配置文件:
[root@sqm-master yaml]# kubectl apply -f  app.v1.yaml 
deployment.extensions/my-web configured
//查看pod更新后的数量:
[root@sqm-master yaml]# kubectl  get pod  -o wide
NAME                      READY   STATUS      RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
my-web-7db8b88b94-468zv   1/1     Running     0          12m    10.244.2.57   node02   <none>           <none>
my-web-7db8b88b94-c4xvv   1/1     Running     0          12m    10.244.2.55   node02   <none>           <none>
my-web-7db8b88b94-d5fvc   1/1     Running     0          12m    10.244.1.58   node01   <none>           <none>
my-web-7db8b88b94-m9gbh   1/1     Running     0          12m    10.244.1.57   node01   <none>           <none>
my-web-7db8b88b94-q5dqc   1/1     Running     0          12m    10.244.1.59   node01   <none>           <none>
my-web-7db8b88b94-tsbmm   1/1     Running     0          12m    10.244.2.56   node02   <none>           <none>
my-web-7db8b88b94-wlgwb   1/1     Running     0          12m    10.244.2.58   node02   <none>           <none>
my-web-849cc47979-2g59w   0/1     Running     0          3m9s   10.244.1.63   node01   <none>           <none>
my-web-849cc47979-2lkb6   0/1     Running     0          3m9s   10.244.1.64   node01   <none>           <none>
my-web-849cc47979-762vb   0/1     Running     0          3m9s   10.244.1.62   node01   <none>           <none>
my-web-849cc47979-dv7x8   0/1     Running     0          3m9s   10.244.2.61   node02   <none>           <none>
my-web-849cc47979-j6nwz   0/1     Running     0          3m9s   10.244.2.60   node02   <none>           <none>
my-web-849cc47979-v5h7h   0/1     Running     0          3m9s   10.244.2.62   node02   <none>           <none>

我们可以看到当前pod的总数量为13个,(包括maxSurge增加额外的数量)因为探测失败,则设置为将3个pod(包括额外的pod)为不可用的状态,但还剩下7个pod可用( 因为maxUnavailable设置为3个),但注意:这7个pod的版本并没有更新成功,还是上一个的版本。

//查看pod的更新后的版本信息:
[root@sqm-master yaml]# kubectl  get deployments. -o wide
NAME     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                        SELECTOR
my-web   7/10    6            7           58m   my-web       172.16.1.30:5000/nginx:v3.0   name=my-web

参数解释:
READY :表示用户的期望值
UP-TO-DATE:表示已更新的
AVAILABLE:表示可用的

我们可以发现已更新的镜像版本数量为6个(包括额外的3个pod),但是为不可用的状态,但是确保可用的的pod数量为7个,但是版本并没有更新。

总结:
描述在滚动更新过程中,探测机制有什么作用?

如果在公司中需要对某个应用中的pod进行更新操作,如果没有探测机制,无论该pod是不是当你已经做好更新工作准备要进行更新的,它都会将该应用中所有的pod进行更新,这样会造成严重的后果,虽然更新后你发现pod的状态是正常的,为了达到controller manager的期望值,READY的值依然是1/1, 但是pod已经是重新生成的pod了,表示pod内的数据将会全部丢失。
如果加上探测机制的话,会探测容器内你指定的文件或其他应用是否存在,如果达到你指定的条件,则探测成功,则会对你的pod进行更新,如果探测失败则会设置pod(容器)为不可用,虽然探测失败的容器不可用了,但至少该模块中还有其他之前版本的pod可用,确保该公司该服务的正常运行。可见探测机制是多么的重要啊。

———————— 本文至此结束,感谢阅读 ————————

推荐阅读:
  1. kubernetes系列教程(八)Pod健康检查机制
  2. k8s之健康检查(Health Check)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

k8s探测机制之pod健康检查 %d

上一篇:Spring MVC 3.0 深入及对注解的详细讲解

下一篇:ionic侧边栏 ion-side-menus 以及 ion-tap结合侧边 栏详解

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》