其实这章去年就该发了U•ェ•*U(今天2021.1.7日)

不知道为什么打开这章就开始头晕了>﹏<

 k8s pod健康检查

  我们平时检查pod状态好不好,无非就是看pod的running状态,但是有很多情况下,pod虽然是running,但是却无法提供服务

  我们作为管理员不能总是等到客户或其他同事发现连接不上了才去修复吧,而健康检查就是定期模拟客户端去访问来确定是否健康的一个机制

 

一. liveness Probe(存活检查)

如果检查失败,将杀死容器,根据restartpolicy(重启策略)来决定pod是否重启

存活检查方式

1. exec         #执行shell命令,返回状态码是0为成功
2. httpGet      #发送http请求,返回2xx-3xx范围状态码为成功
3. tcpSocket   #发起tcp socker建立成功

案例1 (exec)

cat > ss.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox:latest
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5  
      periodSeconds: 5  
EOF

参数说明

    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy
           #创建一个文件,30s后删除,在此期间会通过live不断检查这个heal文件是否存在

    livenessProbe:       #存活检查
      exec:                  #方法为exec 执行命令
        command:                #命令多个操作以- 开头
        - cat
        - /tmp/healthy

      initialDelaySeconds: 5 
             #指定容器启动5s后开始执行liveness检测,
             #一般按照服务的特性来调整
             #比如一个服务启动需要30s,那么这个值就应该大于30

      periodSeconds: 5  
             #指定每5s执行一个liveness检测。
             #如果连续执行3此liveness检测均失败 
             #则会杀死容器,重启

部署

[root@k8s-master01 ~]# kubectl create -f ss.yaml 
pod/liveness-exec created

查看

[root@k8s-master01 ~]# kubectl get pod
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   3          4m31s

#可以看到隔三岔五他就pod就被重启了
#这是因为pod在创建后在执行commnd命令创建了/tmp/healthy文件

#liveness在pod创建成功5s后开始检查/tmp/healthy文件是否存在,每5s检测一次
#30s后文件被删除,检测不到文件3次后表示失败,根据默认重启规则重启了pod容器

考虑到我自己时间久了容易忘,这里留一下什么是状态码

在linux中当命令执行成功后,返回的值为0.不成功则值为非0

#上一次命令执行错误,返回非0的值
[root@k8s-master01 ~]# ls /xxxx

ls: 无法访问/xxxx: 没有那个文件或目录
[root@k8s-master01 ~]# echo $?
2



#上一次命令执行成功,返回值为0
[root@k8s-master01 ~]# ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

[root@k8s-master01 ~]# echo $?
0

 

案例2  httpGet

cat > ss.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default

spec:
  containers:
  - name: liveness-httpget-container
    image: nginx:1.15
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:               #tcp请求检测
        port: http           #请求模式http
        path: /index.html    #请求的url
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10
EOF

部署

kubectl create -f ss.yaml

查看

[root@k8s-master01 ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   1/1     Running   0          56s

测试

#进入容器
[root@k8s-master01 ~]# kubectl exec -it liveness-httpget  bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.

#找到页面文件位置
root@liveness-httpget:/# cd /usr/share/nginx/html/
root@liveness-httpget:/usr/share/nginx/html# ls
50x.html  index.html

#删除该索引文件
root@liveness-httpget:/usr/share/nginx/html# rm -f index.html 

查看

[root@k8s-master01 ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   1/1     Running   1          6m35s

#可以看到pod重启了一次,表明存活检测成功

#这里与第一种方法不同,他是通过检测url来实现的
#在存活检测时做了类似下面的操作

#访问url中的该页面
[root@k8s-master01 ~]# curl -I 10.244.2.2:80/index.html
HTTP/1.1 200 OK          #正常访问返回状态码为2xx-3xx
Server: nginx/1.15.12
Date: Fri, 08 Jan 2021 02:42:24 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 16 Apr 2019 13:08:19 GMT
Connection: keep-alive
ETag: "5cb5d3c3-264"
Accept-Ranges: bytes


#如果找不到该页面,会报404然后退出来保证pod始终存活
[root@k8s-master01 ~]# curl -I 10.244.2.2:80/index1.html
HTTP/1.1 404 Not Found
Server: nginx/1.15.12
Date: Fri, 08 Jan 2021 02:43:37 GMT
Content-Type: text/html
Content-Length: 154
Connection: keep-alive

案例3 tcpSocket

cat > ss.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      restartPolicy: Always
      containers:
      - image: nginx:1.15
        imagePullPolicy: IfNotPresent
        name: web
        ports:
        - containerPort: 80        #pod ip上公开的端口,可以通过pod ip+端口访问
        livenessProbe:
          tcpSocket:
            port: 81           #这里故意写错,容器提供访问的端口是80,我们检测81是不存在的
          initialDelaySeconds: 5
          periodSeconds: 5

EOF

部署

kubectl create -f ss.yaml

查看

[root@k8s-master01 ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
web-5dccd4b5b9-dgvkt   1/1     Running   0          16s
[root@k8s-master01 ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
web-5dccd4b5b9-dgvkt   1/1     Running   0          16s
[root@k8s-master01 ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
web-5dccd4b5b9-dgvkt   1/1     Running   1          24s
[root@k8s-master01 ~]# kubectl get pod
NAME                   READY   STATUS    RESTARTS   AGE
web-5dccd4b5b9-dgvkt   1/1     Running   1          24s

这个我找了很久没有找到合适的验证方法,这里是一个猜想

可能他是以客户端的形式去访问这个提供服务的端口来验证是否存活的

我将检测端口改为80后就不重启了,有知道的大大说明一下~感谢(*^_^*)

 

二 readinessProbe(就绪检查)

在pod启动之前去检查是否满足要求,如果存在则表示就绪完成

检测方法和上面的基本一致,不过区别是在容器启动之前就会检测

cat > ss.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default

spec:
  containers:
  - name: liveness-httpget-container
    image: nginx:1.15
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:       #改为就绪检测
      httpGet:               
        port: http           
        path: /index1.html    #这里去请求一个不存在的文件
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10
EOF

部署

kubectl apply -f ss.yaml

查看

[root@k8s-master01 ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   0/1     Running   0          5s

#可以看到pod状态为running,但是ready为0/1
#说明就绪检测没有完成,因为我们给他设置了一个检测不到的值index1.html

查看详细信息

kubectl describe pod liveness-httpget 

返回

Events:
  Type     Reason     Age                   From                   Message
  ----     ------     ----                  ----                   -------
  Normal   Scheduled  <unknown>             default-scheduler      Successfully assigned default/liveness-httpget to 192.168.1.21
  Normal   Pulled     2m19s                 kubelet, 192.168.1.21  Container image "nginx:1.15" already present on machine
  Normal   Created    2m19s                 kubelet, 192.168.1.21  Created container liveness-httpget-container
  Normal   Started    2m19s                 kubelet, 192.168.1.21  Started container liveness-httpget-container
  Warning  Unhealthy  27s (x22 over 2m12s)  kubelet, 192.168.1.21  Readiness probe failed: HTTP probe failed with statuscode: 404

#可以在最后一行看到Readiness probefailed 进程检测失败
#HTTP probe failed with statuscode: 404 状态返回码是404 找不到

测试

#我们进入容器手动添加这个检测文件
[root@k8s-master01 ~]# kubectl exec -it liveness-httpget bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.

#进入页面文件目录
root@liveness-httpget:/# cd /usr/share/nginx/html/

#创建文件
root@liveness-httpget:/usr/share/nginx/html# touch index1.html

#退出容器
root@liveness-httpget:/usr/share/nginx/html# exit
exit


#查看pod状态
[root@k8s-master01 ~]# kubectl get pod
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   1/1     Running   0          4m34s


#状态就恢复了

并且存活检查liveness Probe和readinessProbe是可以在yaml中一起使用,不会冲突