k8s的Health Check

Health Check(健康检查)

Kubernetes默认的健康检查机制    
    每个容器启动时都会执行一个进程,此进程由Dockerfile 的CMD 或ENTRYPOIRT 指定。如果进程退出时返回码非零,则认为容器发生故障,kubernetes就会根据restartPolicy重启容器
模拟容器发生故障
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: healthcheck
  name: healthcheck
spec:
  restartPolicy: OnFailure
  containers:
  - name: healthcheck
    image: centos
    args:
    - /bin/sh
    - -c
    - sleep 10; exit 3
View Code
kubctl apply -f healthcheck.yml
 
过几分钟查看Pod,可以看到容器已经重启了两次
kubectl get pod healthcheck 
  
  从上面的例子中,容器进程返回值非零,kubernetes 则认为容器发生故障,需要重启。有一些情况是发生了故障,但是进程并不会退出。比如访问Web服务器显示500内部错误,可能是系统超载,也可能是资源死锁,此时httpd进程并没有异常退出,在这种情况下重启容器是最直接、最有效的解决方法,
 

Liveness 探测

  Liveness 探测让用户可以自定义判断容器是否是健康的条件。如果探测失败,Kubernetes 就会重启容器

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness
spec:
  restartPolicy: OnFailure
  containers:
  - name: liveness
    image: centos
    args:
    - /bin/sh
    -  -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:   #定义如何执行Liveness探测
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 10  #容器启动后10s开始执行Liveness探测
      periodSeconds: 5     # 每5s执行一次Liveness 探测
View Code
  启动进程首先创建文件/tmp/healthy ,30s后删除,在我们的设定中,如果/tmp/healthy文件存在,则认为容器处于正常状态,反之则发生故障。
 
探测方法
  1.  通过cat检查/tmp/healthy文件是否存在。如果命令执行成功,返回值为0,Kubernetes则认为本次Liveness 探测成功;如果命令返回值非零,本次Liveness探测失败。
  2. initialDelaySeconds : 10 指定容器启动10s后开始执行Liveness探测,我们一般会根据应用启动的准备时间设置。比如某个应用的正常启动时间要花30s, 那initialDelaySeconds 的值就应该大于30s
  3. periodSeconds : 5 指定每5秒执行一次Liveness 探测。Kubernetes 如果连续执行3次Liveness 探测均失败,则会杀掉并重启容器。

 

创建 Pod liveness:
kubectl apply -f liveness.yml
查看 liveness
kubectl describe pod liveness

Readiness 探测

  用户通过Liveness 探测告诉Kubernetes 什么时候可以实现容器自愈;Readiness 探测是告诉kubernetes 什么时候可以将容器加入到service负载均衡池中,对外提供服务。

Readiness 探测的配置语法与 Liveness 探测完全一样

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: readiness
  name: readiness
spec:
  restartPolicy: OnFailure
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 10
      periodSeconds: 5
View Code

Pod readiness 的 READY 状态经历了如下变化:

  1. 刚被创建时,READY 状态为不可用。

  2. 15 秒后(initialDelaySeconds + periodSeconds),第一次进行 Readiness 探测并成功返回,设置 READY 为可用。

  3. 30 秒后,/tmp/healthy 被删除,连续 3 次 Readiness 探测均失败后,READY 被设置为不可用 STATUS变为Completed,而RESTARTS一直为0。

通过 kubectl describe pod readiness 也可以看到 Readiness 探测失败的日志。

Liveness 与Readness对比
  1. Liveness 探测是两种Health Check 机制,如果不特意配置,Kubernetes 将会对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为0来判断是否探测成功
  2. 两种探测的配置方法完全一致,支持的配置参数也是一致的。不同之处在于探测失败后的行为:
    1. Liveness 探测是重启容器
    2. Readiness 探测是容器设置为不可用,不接收Service转发的请求。
  3. Liveness 探测和Readiness 探测是独立执行的,二者之间没有依赖,所以可以单独使用,也可以同时使用。用Liveness探测容器是否需要重启以实现自愈;用Readiness探测判断容器是否已准备好对外提供服务。

Health Check 在Scale Up中的应用

  当执行Scale Up 操作时,新副本会作为backend被添加到Service 的负载均衡中,与已有副本一起处理客户的请求。考虑到应用启动通常都需要一个准备阶段,比如加载缓存数据、连接数据库等,从容器启动到真正能够对外提供服务是需要一段时间的。可以通过Readiness探测判断容器是否就绪,避免将请求发送到没有准备好的backend

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: web
        image: nginx
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    run: web
  ports:
  - protocol: TCP
    port: 8082        #ClusterIP 上监听端口
    targetPort: 80   #Pod 监听端口
View Code
上面配置的作用是:
  1. 容器启动10s后开始探测
  2. 如果http://[container_ip]:8080/healthy 返回代码不是200~400,表示容器没有就绪,不接收Service web-svc的请求。
  3. 每5秒探测一次
  4. 直到返回代码为200~400,表明容器已经准备就绪,然后让其加入web-svc的负载均衡中,开始处理客户请求。
  5. 探测会以5秒的间隔执行,如果连续发生3次失败,容器又会从负载均衡中移除。
 
对于生产环境的重要应用,都建议配置HealthCheck ,保证处理客户请求的容器都是准备就绪的Service backend。

Health Check 在滚动更新中的作用

 

对应用更新,kubeernetes 会启动新的副本,然后发生如下事件:
  1. 正常情况下新副本需要10s完成准备工作,在此之前无法响应业务请求
  2. 由于人为配置错误,副本始终无法完成工作(比如无法链接到后端数据库)
    假如没有配置 health Check,新副本本身没有异常退出,默认的Health Check 机制会被认为容器已经就绪,进而会逐步用心副本替代现有副本,其结果是,所有旧副本替换后,整个应用则将无法处理请求,无法对外提供服务
如果正确配置了 Helthy Check ,新副本只有通过了Readiness 探测才会被添加到Service; 如果没有通过探测,现有的副本不会被全部替换,业务仍然正常运行。
 
实践Health Check 在Rolling Update中的应用
app.v1.yml  模拟一个6副本的应用
apiVersion: extensions/v1beta1
kind: Deployment
metadata: 
 name: app
spec:
  replicas: 6
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: nginx
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 30000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5
View Code

10 秒后副本能够通过Readiness 探测

 接下来滚动更新应用,配置文件 app.v2.yml 如下:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 6
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: nginx
        args:
        - /bin/sh
        - -c
        - sleep 30000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5
View Code

很显然,由于新副本中不存在/tmp/healthy,因此无法通过Readiness 探测的,验证如图

从 kubectl get pod 输出信息
  1. Pod 的AGE栏可判断,前两个Pod是新的副本,目前处于NOT READY的状态
  2. 旧副本从最初的6个减少为5个

看 kubectl get deployment app 输出

  1. DESIRED 6 表示期望状态为6个READY 副本
  2. CURRNET 7 表示当前副本的数量,即2个新副本+5个旧副本
  3. UP-TO-DATA 2 表示当前已经完成更新的副本数,即2个新副本
  4. ALAILABLE 5 表示当前处于READY 状态的副本数,即5个旧副本
在我们的设定中,新副本始终无法通过Readiness 探测,所以这个状态会一直保持下去。
上面我们模拟了一个滚动失败的场景。Health Check 帮我们屏蔽了有缺陷的副本,同时保留了大部分旧副本
 
滚动更新通过参数maxSurgemaxUnavailable  来控制副本替换的数量。
 
1.maxSurge
   控制滚动更新过程中副本总数超过DESURED 的上限。maxSurgr 可以是具体的整数,也可以是百分比,向上取整。默认为25%
在上面的例子中DESIRED 为6 ,那么副本总数的最大值为   RoundUp(6+6*25%)=8
2.maxUnavailable
 
控制滚动更新过程中,不可用副本占DESIRED 的最大比例。maxUnavailable可以是具体的整数,也可以是百分比,向下取整。默认为25%
在上面的例子中DESIRED 为6 ,那么可用的副本总数的至少为  6-roundDown(6*25%)=5
maxSurge  值越大,初始创建的新副本就越多;maxUnavailable值越大,初始销毁的旧副本就越多。

参考 

https://www.cnblogs.com/benjamin77/p/9939050.html#auto_id_4

 

 
 
posted @ 2019-08-21 16:40  xmc_2022  阅读(282)  评论(0)    收藏  举报