关于kubernetes:不背锅运维k8s探针实战

8次阅读

共计 6440 个字符,预计需要花费 17 分钟才能阅读完成。

重启策略

  • Always:当容器终止退出,总是重启容器,默认策略
  • OnFailure:当容器异样退出(退出状态码非 0)时,才重启容器
  • Never:当容器终止退出,从不重启容器

查看 pod 的重启策略

# 查看 pod,以 yaml 格局输入
kubectl get pods test-pod1 -o yaml

# 找到 restartPolicy 字段,就是重启策略
restartPolicy: Always

健康检查有以下 3 种类型:

健康检查是查看容器外面的服务是否失常

  • livenessProbe(存活探测):如果查看失败,将杀死容器,依据 pod 的 restartPolicy 来操作。
  • readinessProbe(就绪探测):如果查看失败,k8s 会把 Pod 从 service endpoints 中剔除
  • startupProbe(启动探测):查看胜利才由存活查看接手,用于爱护慢启动容器

反对以下三种查看办法:

  • httpGet:发动 HTTP 申请,返回 200-400 范畴状态码为胜利。
  • exec:执行 Shell 命令返回状态码是 0 为胜利。
  • tcpSocket:发动 TCP Socket 建设胜利。

案例实战

  1. livenessProbe(存活探针):应用 exec 的形式(执行 Shell 命令返回状态码是 0 则为胜利)
apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        livenessProbe:
          exec:
            command:
            - ls
            - /opt/goweb-demo/runserver
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort

periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测,initialDelaySeconds 字段通知 kubelet 在执行第一次探测前应该期待 5 秒,kubelet 在容器内执行命令 ls /opt/goweb-demo/runserver 来进行探测。如果命令执行胜利并且返回值为 0,kubelet 就会认为这个容器是衰弱存活的。如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

验证存活查看的成果

# 查看某个 pod 的里的容器,kubectl get pods goweb-demo-686967fd56-556m9 -n test-a -o jsonpath={.spec.containers[*].name}

# 进入某个 pod 里的容器
kubectl exec -it goweb-demo-686967fd56-556m9 -c goweb-demo -n test-a -- bash

# 进入容器后,手动删除掉 runserver 可执行文件,模仿故障
rm -rf /opt/goweb-demo/runserver

# 查看 Pod 详情(在输入后果的最上面,有信息显示存活探针失败了,这个失败的容器被杀死并且被重建了。)kubectl describe pod goweb-demo-686967fd56-556m9 -n test-a

Events:
  Type     Reason     Age                   From     Message
  ----     ------     ----                  ----     -------
  Warning  Unhealthy  177m (x6 over 3h59m)  kubelet  Liveness probe failed: ls: cannot access '/opt/goweb-demo/runserver': No such file or directory

# 一旦失败的容器复原为运行状态,RESTARTS 计数器就会减少 1
tantianran@test-b-k8s-master:~$ kubectl get pods -n test-a
NAME                          READY   STATUS    RESTARTS      AGE
goweb-demo-686967fd56-556m9   1/1     Running   1 (22s ago)   13m # RESTARTS 字段加 1,goweb-demo-686967fd56-8hzjb   1/1     Running   0             13m
...
  1. livenessProbe(存活探针):应用 httpGet 申请的形式查看 uri path 是否失常
apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        livenessProbe:
          httpGet:
            path: /login
            port: 8090
            httpHeaders:
            - name: Custom-Header
              value: Awesome
          initialDelaySeconds: 3
          periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort

在这个配置文件中,你能够看到 Pod 也只有一个容器。periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。initialDelaySeconds 字段通知 kubelet 在执行第一次探测前应该期待 3 秒。kubelet 会向容器内运行的服务(服务在监听 8090 端口)发送一个 HTTP GET 申请来执行探测。如果服务器上 /login 门路下的处理程序返回胜利代码,则 kubelet 认为容器是衰弱存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并将其重启。返回大于或等于 200 并且小于 400 的任何代码都示意胜利,其它返回代码都示意失败。

验证成果

# 进入容器删除动态文件,模仿故障
kubectl exec -it goweb-demo-586ff85ddb-4646k -c goweb-demo -n test-a -- bash
rm -rf login.html 

# 查看 pod 的 log
kubectl logs goweb-demo-586ff85ddb-4646k -n test-a

2023/01/12 06:45:19 [Recovery] 2023/01/12 - 06:45:19 panic recovered:
GET /login HTTP/1.1
Host: 10.244.222.5:8090
Connection: close
Accept: */*
Connection: close
Custom-Header: Awesome
User-Agent: kube-probe/1.25


html/template: "login.html" is undefined
/root/my-work-space/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:911 (0x8836d1)
/root/my-work-space/pkg/mod/github.com/gin-gonic/gin@v1.8.2/context.go:920 (0x88378c)
/root/my-work-space/src/goweb-demo/main.go:10 (0x89584e)

# 查看 pod 详情
kubectl describe pod goweb-demo-586ff85ddb-4646k -n test-a

Warning  Unhealthy  34s (x3 over 40s)   kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500 # 状态码为 500

# 复原后查看 Pod,RESTARTS 计数器曾经增 1
kubectl get pod goweb-demo-586ff85ddb-4646k -n test-a

NAME                          READY   STATUS    RESTARTS      AGE
goweb-demo-586ff85ddb-4646k   1/1     Running   1 (80s ago)   5m39s
  1. readinessProbe(就绪探针)联合 livenessProbe(存活探针)探测 tcp 端口:

第三种类型的存活探测是应用 TCP 套接字。应用这种配置时,kubelet 会尝试在指定端口和容器建设套接字链接。如果能建设连贯,这个容器就被看作是衰弱的,如果不能则这个容器就被看作是有问题的。

apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        readinessProbe:
          tcpSocket:
            port: 8090
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          tcpSocket:
            port: 8090
          initialDelaySeconds: 15
          periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort

TCP 检测的配置和 HTTP 检测十分类似。这个例子同时应用就绪和存活探针。kubelet 会在容器启动 5 秒后发送第一个就绪探针。探针会尝试连贯 goweb-demo 容器的 8090 端口。如果探测胜利,这个 Pod 会被标记为就绪状态,kubelet 将持续每隔 10 秒运行一次探测。除了就绪探针,这个配置包含了一个存活探针。kubelet 会在容器启动 15 秒后进行第一次存活探测。与就绪探针相似,存活探针会尝试连贯 goweb-demo 容器的 8090 端口。如果存活探测失败,容器会被重新启动。

验证成果

# 进入容器后,杀掉 goweb-demo 的过程
kubectl exec -it goweb-demo-5d7d55f846-vm2kc -c goweb-demo -n test-a -- bash

root@goweb-demo-5d7d55f846-vm2kc:/opt/goweb-demo# ps -aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0   2476   576 ?        Ss   07:23   0:00 /bin/sh -c /opt/goweb-demo/runserver
root@goweb-demo-5d7d55f846-vm2kc:/opt/goweb-demo# kill -9 1

# 查看 pod 详情,曾经收回正告
kubectl describe pod goweb-demo-5d7d55f846-vm2kc -n test-a

  Warning  Unhealthy  16s                 kubelet            Readiness probe failed: dial tcp 10.244.240.48:8090: connect: connection refused
  Warning  BackOff    16s                 kubelet            Back-off restarting failed container

# 查看 pod,RESTARTS 计数器曾经减少为 2,因为有两个探针
tantianran@test-b-k8s-master:~$ kubectl get pod -n test-a

NAME                          READY   STATUS    RESTARTS        AGE
goweb-demo-5d7d55f846-vm2kc   1/1     Running   2 (2m55s ago)   12m
  1. 应用 startupProbe(启动探针)爱护慢启动容器

有一种情景是这样的,某些利用在启动时须要较长的初始化工夫。要这种状况下,若要不影响对死锁作出疾速响应的探测,设置存活探测参数是要技巧的。技巧就是应用雷同的命令来设置启动探测,针对 HTTP 或 TCP 检测,能够通过将 failureThreshold * periodSeconds 参数设置为足够长的工夫来应答蹩脚状况下的启动工夫。

apiVersion: v1
kind: Namespace
metadata:
  name: test-a
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  replicas: 10
  selector:
    matchLabels:
      app: goweb-demo
  template:
    metadata:
      labels:
        app: goweb-demo
    spec:
      containers:
      - name: goweb-demo
        image: 192.168.11.247/web-demo/goweb-demo:20221229v3
        livenessProbe:
          httpGet:
            path: /login
            port: 8090
          failureThreshold: 1
          periodSeconds: 10
        startupProbe:
          httpGet:
            path: /login
            port: 8090
          failureThreshold: 30
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: goweb-demo
  namespace: test-a
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8090
  selector:
    app: goweb-demo
  type: NodePort

下面的例子,应用程序将会有最多 5 分钟(30 * 10 = 300s)的工夫来实现其启动过程。一旦启动探测胜利一次,存活探测工作就会接管对容器的探测,对容器死锁作出疾速响应。如果启动探测始终没有胜利,容器会在 300 秒后被杀死,并且依据 restartPolicy 来执行进一步处理。

本文转载于:https://mp.weixin.qq.com/s/ag…

正文完
 0