Denken Sie an die Probleme, die durch einen k8s-Gesundheitscheck verursacht werden

Problemhintergrund

Das Mobiltelefon hat eine Warn-SMS erhalten und die Benutzeroberfläche der Online-Umgebung ist nicht normal! ! ! Der Alarminhalt ist, dass ein bestimmter API-Statuscode eines externen Dienstes anormal ist und der Statuscode 500 ist. Der gute Typ ging zur PaaS-Plattform (KuberSphere), um die erste Reaktion zu überprüfen, und stellte fest, dass ein Pod des Dienstes neu gestartet wurde und nach dem Neustart weiter neu gestartet wurde. Zu diesem Zeitpunkt wurde eine weitere Alarmwiederherstellungsnachricht empfangen (etwa eine Minute nach der Alarmnachricht) und der Statuscode war 200. . . Dieser Artikel behandelt dieses Problem.

k8s-Gesundheitscheck

k8s-Sonde

k8s-Probes sind regelmäßige Diagnosen, die von Kubelet auf Containern durchgeführt werden. Zur Diagnose ruft das Kubelet den vom Container implementierten Handler auf . Es gibt drei Arten von Handlern:

  • ExecAction : Führt den angegebenen Befehl innerhalb des Containers aus. Die Diagnose gilt als erfolgreich, wenn der Befehl mit einem Rückgabecode von 0 beendet wird.
  • CPSocketAction : Führt eine TCP-Prüfung gegen die IP-Adresse des Containers am angegebenen Port durch. Die Diagnose gilt als erfolgreich, wenn der Port offen ist.
  • HTTPGetAction : Führt eine HTTP-Get-Anforderung an die IP-Adresse des Containers am angegebenen Port und Pfad aus. Eine Diagnose gilt als erfolgreich, wenn die Antwort einen Statuscode größer oder gleich 200 und kleiner als 400 hat.

k8s- Gesundheitsprüfungssonde

  • livenessProbe (Survival-Probe) : Wird verwendet, um zu bestimmen, ob der Container aktiv ist (Running-Zustand). Wenn die LivenessProbe-Probe feststellt, dass der Container fehlerhaft ist, „killt“ das Kubelet den Container und führt die entsprechende Verarbeitung gemäß der Neustartstrategie des Containers durch . Wenn ein Container keinen livenessProbe-Probe enthält, geht kubelet davon aus, dass der vom livenessProbe-Probe des Containers zurückgegebene Wert immer Success ist.
  • readinessProbe (Bereitschaftstest) : Wird verwendet, um zu bestimmen, ob der Containerdienst verfügbar ist (Bereit-Zustand) und der Pod, der den Bereit-Zustand erreicht, Anfragen empfangen kann. Für den vom Dienst verwalteten Pod wird die Beziehung zwischen dem Dienst und dem PodEndpoint auch basierend darauf festgelegt, ob der Pod bereit ist. Wenn der Bereit-Status während des laufenden Prozesses zu False wird, isoliert das System ihn automatisch von der Back-End-Endpunktliste des Dienstes und fügt dann den Pod, der in den Bereit-Status zurückversetzt wurde, wieder zur Back-End-Endpunktliste hinzu.
  • startupProbe (Startprobe) : Wenn startupProbe konfiguriert ist, werden andere Probes gesperrt, bis sie erfolgreich sind, und nach dem Erfolg werden keine weiteren Probes durchgeführt. Es eignet sich besser für Szenarien, in denen die Container-Startzeit lang ist. Erfordert Kubernetes-Version v1.18 oder höher.

Identifizieren Sie das Problem

Die von uns konfigurierten Zustandsprüfungen lauten wie folgt:

livenessProbe:
  httpGet:
    path: /actuator/health
    port: 8080
    scheme: HTTP
  initialDelaySeconds: 90
  timeoutSeconds: 3
  periodSeconds: 10
  successThreshold: 1
  failureThreshold: 3
readinessProbe:
  httpGet:
    path: /actuator/health
    port: 8080
    scheme: HTTP
  initialDelaySeconds: 90
  timeoutSeconds: 3
  periodSeconds: 10
  successThreshold: 1
  failureThreshold: 3
复制代码

Hier sind einige Konfigurationsbedeutungen wie folgt:

Aufbau Bedeutung
httpGet.Pfad Anforderungspfad erhalten
httpGet.port Anforderungsport erhalten
httpGet.schema Anforderungsprotokoll erhalten
initialDelaySeconds Anfängliche Verzögerung in Sekunden, wie lange ein Container nach dem Start warten soll, bevor er seinen Zustand überprüft.
timeoutSekunden Timeout (in Sekunden), wie lange auf den Abschluss des Tests gewartet werden soll. Wird die Zeit überschritten, gilt die Sonde als ausgefallen. Der Standardwert ist 1 Sekunde. Der Mindestwert ist 1.
PeriodeSekunden Prüfhäufigkeit ausführen (Sekunden), wie oft die Prüfung durchgeführt werden soll, in Sekunden. Der Standardwert ist 10 Sekunden. Der Mindestwert ist 1.
Erfolgsschwelle Integritätsschwellenwert, nachdem die Erkennung fehlgeschlagen ist, ist die minimale aufeinanderfolgende erfolgreiche Erkennung erfolgreich. Der Standardwert ist 1. Der Mindestwert ist 1. Muss 1 in Liveness-Probe und Start-Probe sein.
Fehlerschwelle Fehlerhafter Schwellenwert, die Mindestanzahl aufeinanderfolgender Probefehler, die erforderlich sind, damit die Probe in den Fehlerstatus wechselt.

Das vom Unternehmen bereitgestellte Konfigurationsdokument enthält nicht die Konfiguration des Starttests. Es wird vermutet, dass die bereitgestellte Version von k8s den Starttest nicht unterstützt.

Aus dem Hintergrund des Problems haben wir einige Kernpunkte :

  1. Ein Pod wird neu gestartet.
  2. Nachdem der Pod-Neustart abgeschlossen ist, wird der Neustart fortgesetzt.
  3. 告警短信大概一分钟后告警恢复。

到这里可以联想到,存活探针发送get请求获取到的响应的状态码不在 200 和 400之间或者直接超时,所以容器重启直接影响服务,告警通知;但是配置的初始延迟为90秒太短导致一直重启;就在这时就绪探针判断 Ready 状态变为False,则系统自动将其从 Service 的后端 Endpoint 列表中隔离出去,故障 pod 排除掉之后,告警恢复。

是什么原因导致正在运行的容器,PaaS平台是有事件日志的,当时忘记截图了(盘的时候查不到了)... 记得当时有http超时事件,也有状态码为503的事件。超时可能是网络波动或者大概率是初始延迟设置过短。那么这个503状态码到底是为什么呢?

Actuator

Actuator是Springboot的一个模块,模块提供了Spring Boot的所有生产就绪功能。

Endpoints

Actuator 端点允许您监视应用程序并与之交互。 Spring Boot 包括许多内置端点,并允许您添加自己的端点。 例如,提供基本的应用程序运行状况信息的 health 端点。

Actuator的health端点

我们配置健康检查用的接口就是Actuator提供的 health 端点接口。像我们引入DB依赖,Nacos依赖啥的,这些依赖实现了Actuator的health策略接口HealthIndicator,请求health端点的时候就会调用策略实现类检查健康状况。

health端点的返回会返回一个status,可以通过配置management.endpoint.health.show-details=always设置返回详细信息。

下边是一个详细信息的返回值。

{
    "components":{
        "db":{
            "components":{
                "dataSource":{
                    "details":{
                        "database":"MySQL",
                        "result":1,
                        "validationQuery":"/* ping */ SELECT 1"
                    },
                    "status":{
                        "code":"UP",
                        "description":""
                    }
                },
                "dataSource2":{
                    "details":{
                        "database":"MySQL",
                        "result":1,
                        "validationQuery":"/* ping */ SELECT 1"
                    },
                    "status":{
                        "code":"UP",
                        "description":""
                    }
                }
            },
            "status":{
                "code":"UP",
                "description":""
            }
        },
        "discoveryComposite":{
            "components":{
                "discoveryClient":{
                    "details":{
                        "services":[
                            "***",
                            "***",
                            "***-gateway"
                        ]
                    },
                    "status":{
                        "code":"UP",
                        "description":""
                    }
                }
            },
            "status":{
                "code":"UP",
                "description":""
            }
        },
        "diskSpace":{
            "details":{
                "total":"528309530624",
                "free":"463192977408",
                "threshold":10485760
            },
            "status":{
                "code":"UP",
                "description":""
            }
        },
        "mail":{
            "details":{
                "location":"10.************:25"
            },
            "status":{
                "code":"UP",
                "description":""
            }
        },
        "ping":{
            "details":{

            },
            "status":{
                "code":"UP",
                "description":""
            }
        },
        "refreshScope":{
            "details":{

            },
            "status":{
                "code":"UP",
                "description":""
            }
        }
    },
    "groups":[

    ],
    "status":{
        "code":"UP",
        "description":""
    }
}
复制代码

返回的Status的code编码有四种。

/**
 * 指示组件或子系统处于未知状态。
 */
public static final Status UNKNOWN = new Status("UNKNOWN");

/**
 * 指示组件或子系统按预期运行。
 */
public static final Status UP = new Status("UP");

/**
 * 指示组件或子系统发生了意外故障。
 */
public static final Status DOWN = new Status("DOWN");

/**
 * 指示组件或子系统已从服务中取出,不应再使用。
 */
public static final Status OUT_OF_SERVICE = new Status("OUT_OF_SERVICE");
复制代码

翻看源码看到了这四个编码与http状态码的关系,即 DOWN 和 OUT_OF_SERVICE 会返回http状态码 503,其他返回200状态码。

health端点如果异常,即可以通过详细信息定位到异常的组件!

Ich denke du magst

Origin juejin.im/post/7215253602204418104
Empfohlen
Rangfolge