Partager via


Problèmes de délai d’attente ou de serveur intermittents lors de l’accès à l’application sur AKS

Cet article explique comment résoudre les problèmes de connectivité intermittents qui affectent vos applications hébergées sur un cluster Azure Kubernetes Service (AKS).

Prerequisites

  • Outil d’URL client (cURL) ou d’un outil en ligne de commande similaire.

  • L’outil Kubernetes kubectl ou un outil similaire pour se connecter au cluster. Pour installer kubectl à l’aide d’Azure CLI, exécutez la commande az aks install-cli .

Symptômes

Lorsque vous exécutez une commande cURL, vous recevez occasionnellement un message d’erreur « Délai d’expiration ». La sortie peut ressembler au texte suivant :

$ # One connection is successful, which results in a HTTP 200 response.
$ curl -Iv http://20.62.x.x
*   Trying 20.62.x.x:80...
* Connected to 20.62.x.x (20.62.x.x) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK

$ # Another connection is unsuccessful, because it gets timed out.
$ curl -Iv http://20.62.x.x
*   Trying 20.62.x.x:80...
* connect to 20.62.x.x port 80 failed: Timed out
* Failed to connect to 20.62.x.x port 80 after 21050 ms: Timed out
* Closing connection 0
curl: (28) Failed to connect to 20.62.x.x port 80 after 21050 ms: Timed out

$ # Then the next connection is again successful.
$ curl -Iv http://20.62.x.x
*   Trying 20.62.x.x:80...
* Connected to 20.62.x.x (20.62.x.x) port 80 (#0)
...
...
< HTTP/1.1 200 OK
HTTP/1.1 200 OK

Cause

Les délais d’attente intermittents suggèrent des problèmes de performances de composant, plutôt que des problèmes de mise en réseau.

Dans ce scénario, il est important de vérifier l’utilisation et l’intégrité des composants. Vous pouvez utiliser la technique d’intérieur pour vérifier l’état des pods. Exécutez les commandes kubectl top et kubectl get , comme suit :

$ kubectl top pods  # Check the health of the pods and the nodes.
NAME                            CPU(cores)   MEMORY(bytes)
my-deployment-fc94b7f98-m9z2l   1m           32Mi

$ kubectl top nodes
NAME                                CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
aks-agentpool-42617579-vmss000000   120m         6%     2277Mi          49%

$ kubectl get pods  # Check the state of the pod.
NAME                            READY   STATUS    RESTARTS   AGE
my-deployment-fc94b7f98-m9z2l   2/2     Running   1          108s

La sortie indique que l’utilisation actuelle des pods et des nœuds semble acceptable.

Bien que le pod soit dans l’état Running , un redémarrage se produit après les 108 premières secondes du pod en cours d’exécution. Cette occurrence peut indiquer que certains problèmes affectent les pods ou conteneurs qui s’exécutent dans le pod.

Si le problème persiste, l’état du pod change après un certain temps :

$ kubectl get pods
NAME                            READY   STATUS             RESTARTS   AGE
my-deployment-fc94b7f98-m9z2l   1/2     CrashLoopBackOff   42         3h53m

Cet exemple montre que l’état Ready est modifié et qu’il existe plusieurs redémarrages du pod. L’un des conteneurs est dans CrashLoopBackOff l’état.

Cette situation se produit parce que le conteneur échoue après le démarrage, puis Kubernetes tente de redémarrer le conteneur pour le forcer à commencer à fonctionner. Toutefois, si le problème persiste, l’application continue d’échouer après son exécution pendant un certain temps. Kubernetes modifie finalement l’état en CrashLoopBackOff.

Pour vérifier les journaux d’activité du pod, exécutez les commandes de journaux kubectl suivantes :

$ kubectl logs my-deployment-fc94b7f98-m9z2l
error: a container name must be specified for pod my-deployment-fc94b7f98-m9z2l, choose one of: [webserver my-app]

$ # Since the pod has more than one container, the name of the container has to be specified.
$ kubectl logs my-deployment-fc94b7f98-m9z2l -c webserver
[...] [mpm_event:notice] [pid 1:tid 140342576676160] AH00489: Apache/2.4.52 (Unix) configured -- resuming normal operations
[...] [core:notice] [pid 1:tid 140342576676160] AH00094: Command line: 'httpd -D FOREGROUND'
10.244.0.1 - - ... "GET / HTTP/1.1" 200 45
10.244.0.1 - - ... "GET /favicon.ico HTTP/1.1" 404 196
10.244.0.1 - - ... "-" 408 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "HEAD / HTTP/1.1" 200 -
10.244.0.1 - - ... "POST /boaform/admin/formLogin HTTP/1.1" 404 196

$ # The webserver container is running fine. Check the logs for other container (my-app).
$ kubectl logs my-deployment-fc94b7f98-m9z2l -c my-app

$ # No logs observed. The container could be starting or be in a transition phase.
$ # So logs for the previous execution of this container can be checked using the --previous flag:
$ kubectl logs my-deployment-fc94b7f98-m9z2l -c my-app --previous
<Some Logs from the container>
..
..
Started increasing memory

Les entrées de journal ont été effectuées la fois précédente que le conteneur a été exécuté. L’existence de ces entrées suggère que l’application a démarré, mais elle a fermé en raison de certains problèmes.

Vérifiez le service associé au déploiement et essayez de curler l’adresse IP du cluster du service à partir du cluster pour identifier le problème :

$ kubectl get svc # Check the service associated with deployment 
NAME                    TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
kubernetes              ClusterIP      10.0.0.1      <none>         443/TCP        3h21m
my-deployment-service   LoadBalancer   10.0.136.71   20.62.x.x      80:30790/TCP   21m

L’étape suivante consiste à vérifier les événements du pod en exécutant la commande kubectl describe :

$ kubectl describe pod my-deployment-fc94b7f98-m9z2l
Name:         my-deployment-fc94b7f98-m9z2l
Namespace:    default
...
...
Labels:       app=my-pod
...
...
Containers:
  webserver:
 ...
 ...
  my-app:
    Container ID:   containerd://a46e5062d53039d0d812c57c76b740f8d1ffb222de35203575bf8e4d10d6b51e
    Image:          my-repo/my-image:latest
    Image ID:       docker.io/my-repo/my-image@sha256:edcc4bedc7b...
    State:          Running
      Started:      <Start Date>
    Last State:     Terminated
      Reason:       OOMKilled
      Exit Code:    137
    Ready:          True
    Restart Count:  44
    Limits:
      memory:  500Mi
    Requests:
      cpu:        250m
      memory:     500Mi
...
...
Events:
  Type     Reason   Age                     From     Message
  ----     ------   ----                    ----     -------
  Normal   Pulling  49m (x37 over 4h4m)     kubelet  Pulling image "my-repo/my-image:latest"
  Warning  BackOff  4m10s (x902 over 4h2m)  kubelet  Back-off restarting failed container

Observations :

  • Le code de sortie est 137. Pour plus d’informations sur les codes de sortie, consultez la référence d’exécution Docker et les codes de sortie avec des significations spéciales.

  • La raison de l’arrêt est OOMKilled.

  • La limite de mémoire spécifiée pour le conteneur est de 500 Mi.

Vous pouvez indiquer à partir des événements que le conteneur est en cours de mort, car il dépasse les limites de mémoire. Lorsque la limite de mémoire du conteneur est atteinte, l’application devient inaccessible par intermittence et le conteneur est tué et redémarré.

Note

Nous vous recommandons de configurer des sondes liveness, readiness et startup dans votre définition de pod. Selon le comportement de votre application, cette configuration peut aider à récupérer l’application à partir de problèmes inattendus. Soyez prudent lors de la configuration des sondes liveness.

Solution

Vous pouvez supprimer la limite de mémoire et surveiller l’application pour déterminer la quantité de mémoire dont elle a réellement besoin. Après avoir appris l’utilisation de la mémoire, vous pouvez mettre à jour les limites de mémoire sur le conteneur. Si l’utilisation de la mémoire continue d’augmenter, déterminez s’il existe une fuite de mémoire dans l’application.

Pour plus d’informations sur la planification des ressources pour les charges de travail dans Azure Kubernetes Service, consultez les meilleures pratiques de gestion des ressources.

Contactez-nous pour obtenir de l’aide

Pour toute demande ou assistance, créez une demande de support ou posez une question au support de la communauté Azure. Vous pouvez également soumettre des commentaires sur les produits à la communauté de commentaires Azure.