1. Introduction
Dans ce tutoriel, nous allons parler des https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/de KKernernetes .[ sondes ]et montrons comment nous pouvons exploiter le HealthIndicator.html[ HealthIndicator pour avoir une vue précise de l’état de notre application.
Pour les besoins de ce didacticiel, nous allons utiliser une expérience pré-existante avec Spring Boot Actuator , Kubernetes et Docker .
2. Kubernetes sondes
Kubernetes définit deux sondes différentes que nous pouvons utiliser pour vérifier périodiquement si tout fonctionne comme prévu: liveness et readiness .
2.1. Vive et Disponibilité
-
Avec les sondes Liveness et Readiness , Kubelet peut agir dès qu’il détecte que quelque chose ne va pas et réduit les temps d’arrêt de notre application. **
Les deux sont configurés de la même manière, mais ils ont une sémantique différente et Kubelet effectue différentes actions en fonction de celle qui est déclenchée:
-
Readiness - Readiness vérifie si notre Pod est prêt à démarrer
recevoir du trafic. Notre Pod est prêt lorsque tous ses conteneurs sont prêt ** Liveness - Contrairement à leadiness , liveness vérifie si notre Pod
devrait être redémarré. Il peut détecter les cas d’utilisation où notre application est en cours d’exécution mais dans un état où elle est incapable de progresser. par exemple, il est dans l’impasse
Nous configurons les deux types de sonde au niveau du conteneur:
apiVersion: v1
kind: Pod
metadata:
name: goproxy
labels:
app: goproxy
spec:
containers:
- name: goproxy
image: k8s.gcr.io/goproxy:0.1
ports:
- containerPort: 8080
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds: 2
failureThreshold: 1
successThreshold: 1
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
timeoutSeconds: 2
failureThreshold: 1
successThreshold: 1
Nous pouvons configurer un certain nombre de champs pour contrôler plus précisément le comportement de nos sondes:
-
initialDelaySeconds - Après avoir créé le conteneur, ** attend
_n secondes avant d’initier la vérification periodSeconds_ - À quelle fréquence cette analyse doit-elle être exécutée , par défaut
10 secondes; le minimum est de 1 seconde timeoutSeconds - Combien de temps attendons-nous ** avant de temporiser la sonde,
défaut à 1 seconde; le minimum est encore 1 seconde failureThreshold - Essayez n fois avant d’abandonner ** . Dans le cas
de la lecture, notre pod sera marqué comme non prêt, alors que d’abandonner dans le cas de liveness signifie le redémarrage du Pod . Le défaut ici est 3 échecs, avec le minimum étant 1 successThreshold - Ceci est le nombre minimum de visites consécutives
succès pour que la sonde soit considérée comme ayant réussi après un échec ** . La valeur par défaut est 1 succès et son minimum est 1
Dans ce cas , nous avons opté pour une sonde tcp , mais il existe d’autres types de sondes que nous pouvons également utiliser.
2.2. Sonde t ypes
Selon notre cas d’utilisation, un type de sonde peut s’avérer plus utile qu’un autre. Par exemple, si notre conteneur est un serveur Web, l’utilisation d’une sonde http pourrait être plus fiable qu’une sonde tcp .
Heureusement, Kubernetes a trois types de sondes que nous pouvons utiliser:
-
exec - Exécute les instructions bash dans notre conteneur . Pour
Par exemple, vérifiez qu’un fichier spécifique existe. Si l’instruction renvoie un code d’échec, la sonde échoue tcpSocket - Essaie d’établir une connexion tcp au conteneur,
en utilisant le port spécifié . Si la connexion n’est pas établie, le sonde échoue httpGet - Envoie une requête HTTP GET au serveur en cours d’exécution
dans le conteneur et en écoutant sur le port spécifié. Tout code supérieur ou égal à 200 et inférieur à 400 indique un succès
Il est important de noter que les sondes HTTP ont des champs supplémentaires, en plus de ceux mentionnés précédemment:
-
hôte - Nom d’hôte auquel se connecter, valeur par défaut de l’IP de notre pod
-
scheme - Schéma à utiliser pour se connecter, HTTP ou HTTPS ,
avec le défaut étant HTTP path ** - Le chemin d’accès au serveur Web
-
httpHeaders - En-têtes personnalisés à définir dans la demande
-
port - Nom ou numéro du port auquel accéder dans le conteneur
3. Printemps Actionneur et Kubernetes Auto-guérison Capacités
Maintenant que nous avons une idée générale sur la façon dont Kubernetes__ est capable de détecter si notre application est dans un état défectueux, voyons comment nous pouvons tirer avantage de l’Acteur un œil attentif non seulement sur notre application mais aussi sur ses dépendances! **
Aux fins de ces exemples, nous allons utiliser Minikube .
3.1. Actionneur et son __HealthIndicator __s
Considérant que Spring a un certain nombre de __HealthIndicator s prêts à être utilisés, refléter l’état de certaines dépendances de notre application par rapport aux sondes de Kubernetes est aussi simple que d’ajouter le Actuator dépendance à notre pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.2. Exemple de vivacité
Commençons par une application qui démarrera normalement et après 30 secondes sera transition en a cassé état .
Nous allons émuler un état défaillant en creating un HealthIndicator qui vérifie si une variable boolean est true .
Nous initialiserons la variable à true , puis nous planifierons une tâche pour la remplacer par false après 30 secondes:
@Component
public class CustomHealthIndicator implements HealthIndicator {
private boolean isHealthy = true;
public CustomHealthIndicator() {
ScheduledExecutorService scheduled =
Executors.newSingleThreadScheduledExecutor();
scheduled.schedule(() -> {
isHealthy = false;
}, 30, TimeUnit.SECONDS);
}
@Override
public Health health() {
return isHealthy ? Health.up().build() : Health.down().build();
}
}
Avec notre HealthIndicator en place, nous devons dockerize notre application:
FROM openjdk:8-jdk-alpine
RUN mkdir -p/usr/opt/service
COPY target/** .jar/usr/opt/service/service.jar
EXPOSE 8080
ENTRYPOINT exec java -jar/usr/opt/service/service.jar
Ensuite, nous créons notre template Kubernetes :
apiVersion: apps/v1
kind: Deployment
metadata:
name: liveness-example
spec:
...
spec:
containers:
- name: liveness-example
image: dbdock/liveness-example:1.0.0
...
readinessProbe:
httpGet:
path:/health
port: 8080
initialDelaySeconds: 10
timeoutSeconds: 2
periodSeconds: 3
failureThreshold: 1
livenessProbe:
httpGet:
path:/health
port: 8080
initialDelaySeconds: 20
timeoutSeconds: 2
periodSeconds: 8
failureThreshold: 1
-
Nous utilisons une sonde httpGet pointant vers le point de terminaison de la santé de l’actionneur. ** Toute modification de l’état de notre application (et de ses dépendances) se reflétera sur la salubrité de notre déploiement.
Après avoir déployé notre application sur Kubernetes , nous pourrons voir les deux sondes en action: après environ 30 secondes, notre Pod sera marqué comme non prêt et retiré de la rotation; Quelques secondes plus tard, le Pod est redémarré.
Nous pouvons voir les événements de notre Pod exécutant kubectl describe pod liveness-example :
Warning Unhealthy 3s (x2 over 7s) kubelet, minikube Readiness probe failed: HTTP probe failed ...
Warning Unhealthy 1s kubelet, minikube Liveness probe failed: HTTP probe failed ...
Normal Killing 0s kubelet, minikube Killing container with id ...
3.3. Exemple de préparation
Dans l’exemple précédent, nous avons vu comment utiliser un HealthIndicator pour refléter l’état de notre application sur la santé d’un déploiement de Kubernetes .
Utilisons-le sur un cas d’utilisation différent: supposons que notre application a besoin de un bit de heure avant il peut recevoir le trafic . Par exemple, il doit charger un fichier en mémoire et valider son contenu.
C’est un bon exemple du moment où nous pouvons tirer parti d’une sonde readiness .
Modifions les modèles HealthIndicator et Kubernetes à partir de l’exemple précédent et adaptons-les à ce cas d’utilisation:
@Component
public class CustomHealthIndicator implements HealthIndicator {
private boolean isHealthy = false;
public CustomHealthIndicator() {
ScheduledExecutorService scheduled =
Executors.newSingleThreadScheduledExecutor();
scheduled.schedule(() -> {
isHealthy = true;
}, 40, TimeUnit.SECONDS);
}
@Override
public Health health() {
return isHealthy ? Health.up().build() : Health.down().build();
}
}
Nous initialisons la variable à false et, après 40 secondes, une tâche s’exécutera et la définissons sur true.
Ensuite, nous dockérisons et déployons notre application en utilisant le modèle suivant:
apiVersion: apps/v1
kind: Deployment
metadata:
name: readiness-example
spec:
...
spec:
containers:
- name: readiness-example
image: dbdock/readiness-example:1.0.0
...
readinessProbe:
httpGet:
path:/health
port: 8080
initialDelaySeconds: 40
timeoutSeconds: 2
periodSeconds: 3
failureThreshold: 2
livenessProbe:
httpGet:
path:/health
port: 8080
initialDelaySeconds: 100
timeoutSeconds: 2
periodSeconds: 8
failureThreshold: 1
Bien que similaires, il y a quelques changements dans la configuration des sondes que nous devons signaler:
-
Puisque nous savons que notre application a besoin d’environ 40 secondes pour devenir
prêt à recevoir du trafic, nous avons augmenté le initialDelaySeconds de notre sonde readiness à 40 secondes De même, nous avons augmenté le initialDelaySeconds ** de
notre liveness sonde jusqu’à 100 secondes pour éviter d’être tué prématurément par Kubernetes
S’il n’a toujours pas terminé après 40 secondes, il lui reste environ 60 secondes pour terminer. Après cela, notre sonde liveness va démarrer et redémarrer le Pod.
4. Conclusion
Dans cet article, nous avons parlé des sondes Kubernetes et de la façon dont nous pouvons utiliser l’actionneur de Spring pour améliorer la surveillance de l’état de nos applications.
La mise en œuvre complète de ces exemples est disponible à l’adresse over sur Github .