kubernetes云原生纪元:健康检查-高可用的守护者

🧨提前祝大家新年快乐🥳


文章目录

  • kubernetes云原生纪元:健康检查-高可用的守护者
  • 配置信息
  • 第一种健康检查方式
  • 如何使用
  • 第二种健康检查方式
  • 使用方式
  • 第三种tcp健康检查方式



健康检查是对容器的,健康检查的配置跟容器同一级别的

配置信息

第一种健康检查方式

通过命令方式检查

  • livenessProbe: #是否存活的探针,用来检查应用是不是活着的
  • exec: #执行一个健康检查命令
    command: #健康检查命令内容如下: ps -ef| grep java|grep -v grep查看Java进程,如果进程存在表示存活的,如果Java进程不存在表示这个容器不正常,这个怎么判断的呢,当我们shell命令执行完有个退出值,这个值等于0的时候,表示这条命令执行的是正确的,当退出值为非0 表示执行是失败的,一旦执行失败就表示当前的健康检查没有通过,没有通过他的动作就是进行pod重启 /bin/bash
    c
    ps -ef| grep java|grep -v grep
  • initialDelaySeconds: 10 #表示当容器刚启动的时候等待10s再执行命令,因容器刚起来就执行检查命令会失败的,
  • periodSeconds: 10 #健康检查间隔10s ,
  • failureThreshold: 2 #失败阀值,表示失败两次我认为是彻底失败的,就放弃继续检查把pod重启
  • successThreshold: 1 #从错误到成功的阀值,表示之前检查错误当前成功一回表示检查通过
  • timeoutSeconds: 5 #每次执行健康检查命令的等待时间。如果超时也是表示检查失败不通过的

#最基本的健康检查配置如下:

livenessProbe: #是否存活的探针,用来检查应用是不是活着的 exec: #执行一个健康检查命令 command: - /bin/bash - -c - ps -ef| grep java|grep -v grep initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 2 successThreshold: 1 timeoutSeconds: 5

如何使用

Web-test.yaml完整配置如下:

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-demo
  namespace: dev
spec:
  selector:
    matchLabels:
      app: web-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: web-demo
    spec:
      containers:
        - name: web-demo
          image: hub.zhang.com/kubernetes/demo:2020011512381579063123
          ports:
            - containerPort: 8080
              #最基本的健康检查配置如下:
          livenessProbe: #是否存活的探针,用来检查应用是不是活着的
            exec: #执行一个健康检查命令
              command: #健康检查命令内容如下: ps -ef| grep java|grep -v grep 查看Java进程,如果进程存在表示存活的,如果Java进程不存在表示这个容器不正常,这个怎么判断的呢,当我们shell命令执行完有个退出值,这个值等于0的时候,表示这条命令执行的是正确的,当退出值为非0 表示执行是失败的,一旦执行失败就表示当前的健康检查没有通过,没有通过他的动作就是进行pod重启
                - /bin/bash
                - -c
                - ps -ef| grep java|grep -v grep
            initialDelaySeconds: 10 #表示当容器刚启动的时候等待10s再执行命令,因容器刚起来就执行检查命令会失败的,
            periodSeconds: 10 #健康检查间隔10s ,
            failureThreshold: 2 #失败阀值,表示失败两次我认为是彻底失败的,就放弃继续检查把pod重启
            successThreshold: 1 #从错误到成功的阀值,表示之前检查错误当前成功一回表示检查通过
            timeoutSeconds: 5 #每次执行健康检查命令的等待时间。如果超时也是表示检查失败不通过的
         #end

创建一下:

[root@master-001 ~]# kubectl apply -f web-inspect.yaml -n dev
deployment.apps/web-demo created
service/web-demo created
ingress.extensions/web-demo created

通过describe 描述命令查看一下:

[root@master-001 ~]# kubectl get pod
NAME                       READY   STATUS    RESTARTS   AGE
web-demo-f84d6c9d6-nhd5t   1/1     Running   1          100s
[root@master-001 ~]# kubectl describe pods web-demo-f84d6c9d6-nhd5t -n dev

在描述中我们可以看到有一条:

省略其他参数…

Liveness: exec [/bin/bash -c ps -ef| grep java|grep -v grep] delay=10s timeout=5s period=10s #success=1 #failure=2

表示我们健康检查配置生效

进入pod到里面执行下我们配置的命令再查看下退出值:

[root@master-001 ~]# kubectl exec -it web-demo-f84d6c9d6-nhd5t -n dev bash
bash-4.4#ps -ef|grep java| grep -v grep #执行配置的健康检查命令
14 root 0:20 /usrlib/jvm/java-1.8-openjdk......
bash-4.4#echo $? #查看命令退出值
0 #0表示命令执行成功
第二种健康检查方式

通过http方式检查

  • livenessProbe: 是否存活的探针,用来检查应用是不是活着的
  • httpGet: 描述以下会定期访问8080端口下的这个地址,如果http返回的状态码是200表示正常的,不是200都是失败的,假如地址被filter 过滤器跳转了302、303 他都认为是失败的
  • path: /examples/index.html 我们访问应用的路径
  • port: 8080 容器端口,不是服务端口也不是ingerss端口
  • scheme: HTTP 协议
  • 其他上面已经介绍过了。

基本配置如下:

livenessProbe: #是否存活的探针,用来检查应用是不是活着的 httpGet: # 描述以下会定期访问8080端口下的这个地址,如果http返回的状态码是200表示正常的,不是200都是失败的,假如地址被filter 过滤器跳转了302、303 他都认为是失败的 path: /examples/index.html # 我们访问应用的路径 port: 8080 #容器端口,不是服务端口也不是ingerss端口 scheme: HTTP #协议 initialDelaySeconds: 5 periodSeconds: 5 #5s检查一次失败表示不正常 failureThreshold: 1 successThreshold: 1 timeoutSeconds: 5

使用方式

在yaml中使用:

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-demo
  namespace: dev
spec:
  selector:
    matchLabels:
      app: web-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: web-demo
    spec:
      containers:
        - name: web-demo
          image: hub.zhang.com/kubernetes/demo:2020011512381579063123
          ports:
            - containerPort: 8080
              #最基本的健康检查配置如下:
          livenessProbe: #是否存活的探针,用来检查应用是不是活着的
            httpGet: # 描述以下会定期访问8080端口下的这个地址,如果http返回的状态码是200表示正常的,不是200都是失败的,假如地址被filter 过滤器跳转了302、303 他都认为是失败的
              path: /examples/index.html # 我们访问应用的路径
              port: 8080 #容器端口,不是服务端口也不是ingerss端口
              scheme: HTTP #协议
            initialDelaySeconds: 5
            periodSeconds: 5 #5s检查一次失败表示不正常
            failureThreshold: 1
            successThreshold: 1
            timeoutSeconds: 5
---
#service
apiVersion: v1
kind: Service
metadata:
  name: web-demo
  namespace: dev
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: web-demo
  type: ClusterIP

---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web-demo
  namespace: dev
spec:
  rules:
    - host: web.demo.com
      http:
        paths:
          - path: /
            backend:
              serviceName: web-demo
              servicePort: 80

创建一下:

[root@master-001 ~]# kubectl apply -f web-http.yaml -n dev

通过describe 描述命令查看一下:

[root@master-001 ~]# kubectl describe pod web-demo-cd9b77589-wz8sj -n dev

发现有问题:

是因为第一次检查的时候我们的服务容器还没有启动好,就去检查

省略…

Events:
Type Reason Age From Message

Normal Scheduled default-scheduler Successfully assigned dev/web-demo-cd9b77589-wz8sj to node-001
Warning FailedCreatePodSandBox 2m38s kubelet, node-001 Failed create pod sandbox: rpc error: code = Unknown desc = [failed to set up sandbox container “32f6a74ad1fc610a52df43df967d322c737b4dd059da2a682e26b30f3e396196” network for pod “web-demo-cd9b77589-wz8sj”: networkPlugin cni failed to set up pod “web-demo-cd9b77589-wz8sj_dev” network: error getting ClusterInformation: Get https://[10.96.0.1]:443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 10.96.0.1:443: i/o timeout, failed to clean up sandbox container “32f6a74ad1fc610a52df43df967d322c737b4dd059da2a682e26b30f3e396196” network for pod “web-demo-cd9b77589-wz8sj”: networkPlugin cni failed to teardown pod “web-demo-cd9b77589-wz8sj_dev” network: error getting ClusterInformation: Get https://[10.96.0.1]:443/apis/crd.projectcalico.org/v1/clusterinformations/default: dial tcp 10.96.0.1:443: i/o timeout]
Normal SandboxChanged 2m37s kubelet, node-001 Pod sandbox changed, it will be killed and re-created.
Warning Unhealthy 104s (x2 over 2m24s) kubelet, node-001 Liveness probe failed: Get http://192.168.93.72:8080/examples/index.html: net/http: request canceled (Client.Timeout exceeded while awaiting headers)

我们修改下yaml里面的initialDelaySeconds: 把时间延长,把失败阀值改成两次

initialDelaySeconds: 10
 failureThreshold: 2

一般这个初始化健康检查延迟时间要比我们预警程序启动的时间要多一些。

第三种tcp健康检查方式

配置如下:

livenessProbe: #是否存活的探针,用来检查应用是不是活着的
   tcpSocket: #通过tcp检查端口8080是否处于监听状态
      port: 8080
   initialDelaySeconds: 5
   periodSeconds: 5 #5s检查一次失败表示不正常
   failureThreshold: 1
   successThreshold: 1
   timeoutSeconds: 5

在yaml 中的使用方式跟上面两种一致这个就不展示了。

问题当我们服务刚启动,就暴露了服务端口,service发现挂到负载均衡就可以访问了,这个时候服务还没有启动好,很显然这样不对的。

处理方式:

readinessProbe: #对外可以访问告知 ,web程序一般使用http方式
  httpGet:  # 表示这个index.html返回200,就可以被 Service 发现
    path: /examples/index.html
    port: 8080
    scheme: HTTP

Yaml 配置方式:

使用tcp健康检查,使用http对外告知是否可以访问

#deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-demo
  namespace: dev
spec:
  selector:
    matchLabels:
      app: web-demo
  replicas: 1
  template:
    metadata:
      labels:
        app: web-demo
    spec:
      containers:
        - name: web-demo
          image: hub.zhang.com/kubernetes/demo:2020011512381579063123
          ports:
            - containerPort: 8080
              #最基本的健康检查配置如下:
          livenessProbe: #是否存活的探针,用来检查应用是不是活着的
            tcpSocket: #通过tcp检查端口是否处于监听状态
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5 #5s检查一次失败表示不正常
            failureThreshold: 1
            successThreshold: 1
            timeoutSeconds: 5
          readinessProbe: #对外可以访问告知 ,web程序一般使用http方式
            httpGet:  # 表示这个index.html返回200,就可以被 Service 发现
              path: /examples/index.html
              port: 8080
              scheme: HTTP
---
#service
apiVersion: v1
kind: Service
metadata:
  name: web-demo
  namespace: dev
spec:
  ports:
    - port: 80
      protocol: TCP
      targetPort: 8080
  selector:
    app: web-demo
  type: ClusterIP

---
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web-demo
  namespace: dev
spec:
  rules:
    - host: web.demo.com
      http:
        paths:
          - path: /
            backend:
              serviceName: web-demo
              servicePort: 80

测试一下:

Kubectl apply -f web-tcp.yaml -n dev

我们可以看到running状态,但是没有Ready,没有准备好

java health检查接口_java

46s后才可以,这就表示readinessProbe:起到了作用,他在等到配置的url返回200后才告知Service可以访问。

java health检查接口_kubernetes_02

我们可以通过kubctl get deploy -n dev 查看这个Available属性,如果非readinessProbe就是0

java health检查接口_docker_03

如果restart发生的频率比较低,几天几十天发生一次,就把重启策略Always改成Never,检查失败会保留上下文日志,如果起不来了 livenessProbe去掉,配置一些简单的命令ls ps 进入容器内进行调试