fond de problème
Le téléphone mobile a reçu un message texte d'avertissement et l'interface de l'environnement en ligne est anormale ! ! ! Le contenu de l'alarme est qu'un certain code d'état de l'API de service externe est anormal, et le code d'état est 500. Le bon gars est allé sur la plate-forme PaaS (KuberSphere) pour vérifier à la première réaction, et a constaté qu'un pod du service redémarrait, et a continué à redémarrer après le redémarrage. À ce moment, un autre message de récupération d'alarme a été reçu (environ une minute après le message d'alarme) et le code d'état était 200. . . Cet article traite de cette question.
bilan de santé k8s
sonde k8s
Les sondes k8s sont des diagnostics périodiques effectués par le kubelet sur les conteneurs. Pour effectuer des diagnostics, le kubelet appelle le Handler implémenté par le conteneur . Il existe trois types de gestionnaires :
- ExecAction : exécute la commande spécifiée à l'intérieur du conteneur. Le diagnostic est considéré comme réussi si la commande se termine avec un code de retour de 0.
- CPSocketAction : Effectue une vérification TCP par rapport à l'adresse IP du conteneur sur le port spécifié. Le diagnostic est considéré comme réussi si le port est ouvert.
- HTTPGetAction : effectue une requête HTTP Get à l'adresse IP du conteneur sur le port et le chemin spécifiés. Un diagnostic est considéré comme réussi si la réponse a un code d'état supérieur ou égal à 200 et inférieur à 400.
sonde de contrôle de santé k8s
- livenessProbe (sonde de survie) : Il est utilisé pour déterminer si le conteneur est vivant (état d'exécution). Si la sonde livenessProbe détecte que le conteneur est malsain, le kubelet "tuera" le conteneur et effectuera le traitement correspondant selon la stratégie de redémarrage du conteneur. . Si un conteneur ne contient pas de sonde livenessProbe, alors kubelet pense que la valeur renvoyée par la sonde livenessProbe du conteneur sera toujours Success.
- readinessProbe (readiness probe) : utilisé pour déterminer si le service de conteneur est disponible (état Ready), et le Pod qui atteint l'état Ready peut recevoir des requêtes. Pour le pod géré par le service, la relation entre le service et le PodEndpoint sera également définie selon que le pod est prêt ou non. Si l'état Prêt devient Faux pendant le processus en cours d'exécution, le système l'isolera automatiquement de la liste des points de terminaison backend du service, puis ajoutera le pod restauré à l'état Prêt à la liste des points de terminaison backend.
- startupProbe (sonde de démarrage) : si startupProbe est configuré, les autres sondes seront interdites jusqu'à ce qu'elles réussissent, et aucune autre sonde ne sera effectuée après le succès. Il est plus adapté aux scénarios où le temps de démarrage du conteneur est long. Nécessite la version v1.18 ou supérieure de Kubernetes.
Identifiez le problème
Les vérifications de l'état que nous configurons sont les suivantes :
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
复制代码
Voici quelques significations de configuration comme suit :
configuration | signification |
---|---|
httpGet.path | obtenir le chemin de la requête |
httpGet.port | obtenir le port de requête |
httpGet.scheme | obtenir le protocole de requête |
initialDelaySeconds | Délai initial, en secondes, combien de temps un conteneur doit attendre après le démarrage avant de vérifier son état. |
timeoutSecondes | Timeout (en secondes), combien de temps attendre la fin de la sonde. Si le temps est dépassé, la sonde est considérée comme défaillante. La valeur par défaut est 1 seconde. La valeur minimale est 1. |
périodeSecondes | Fréquence d'exécution de la sonde (secondes), fréquence d'exécution de la sonde, en secondes. La valeur par défaut est de 10 secondes. La valeur minimale est 1. |
seuil de réussite | Seuil de santé, après l'échec de la détection, la détection réussie consécutive minimale est réussie. La valeur par défaut est 1. La valeur minimale est 1. Doit être 1 dans la sonde de vivacité et la sonde de démarrage. |
seuil d'échec | Seuil non sain, le nombre minimum d'échecs de sonde consécutifs requis pour que la sonde passe à l'état d'échec. |
Le document de configuration fourni par la société n'inclut pas la configuration de la sonde de démarrage. On devine que la version de k8s déployée ne prend pas en charge la sonde de démarrage.
De l'arrière-plan du problème, nous avons extrait quelques points clés :
- Un pod redémarre.
- Une fois le redémarrage du pod terminé, il continue à redémarrer.
- 告警短信大概一分钟后告警恢复。
到这里可以联想到,存活探针发送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端点如果异常,即可以通过详细信息定位到异常的组件!