Tiempos de espera intermitentes o problemas de servidor al obtener acceso a la aplicación en AKS
En este artículo se describe cómo solucionar problemas de conectividad intermitentes que afectan a las aplicaciones hospedadas en un clúster de Azure Kubernetes Service (AKS).
Requisitos previos
La herramienta Dirección URL de cliente (cURL) o una herramienta de línea de comandos similar.
La herramienta Kubernetes kubectl o una herramienta similar para conectarse al clúster. Para instalar kubectl mediante la CLI de Azure, ejecute el comando az aks install-cli .
Síntomas
Cuando ejecuta un comando cURL, en ocasiones recibe un mensaje de error "Tiempo de espera". El resultado puede ser similar al texto siguiente:
$ # 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
Causa
Los tiempos de espera intermitentes sugieren problemas de rendimiento de componentes, en lugar de problemas de red.
En este escenario, es importante comprobar el uso y el estado de los componentes. Puedes usar la técnica de inside-out para comprobar el estado de los pods. Ejecute los comandos kubectl top y kubectl get , de la siguiente manera:
$ 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
El resultado muestra que el uso actual de los pods y nodos parece aceptable.
Aunque el pod está en estado Running , se produce un reinicio después de los primeros 108 segundos de la ejecución del pod. Esta ocurrencia puede indicar que algunos problemas afectan a los pods o contenedores que se ejecutan en el pod.
Si el problema persiste, el estado del pod cambia después de algún tiempo:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-deployment-fc94b7f98-m9z2l 1/2 CrashLoopBackOff 42 3h53m
En este ejemplo se muestra que se Ready cambia el estado y hay varios reinicios del pod. Uno de los contenedores está en CrashLoopBackOff estado.
Esta situación se produce porque el contenedor produce un error después de iniciarse y, a continuación, Kubernetes intenta reiniciar el contenedor para forzarlo a que comience a funcionar. Sin embargo, si el problema persiste, la aplicación sigue fallando después de que se ejecute durante algún tiempo. Kubernetes finalmente cambia el estado a CrashLoopBackOff.
Para comprobar los registros del pod, ejecute los siguientes comandos de registros kubectl :
$ 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
Las entradas de registro se realizaron la vez anterior en que se ejecutaba el contenedor. La existencia de estas entradas sugiere que la aplicación se hizo iniciar, pero se cerró debido a algunos problemas.
El siguiente paso es comprobar los eventos del pod ejecutando el comando 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
Observaciones:
El código de salida es 137. Para obtener más información acerca de los códigos de salida, consulta referencia de ejecución de Docker y Códigos de salida con significados especiales.
El motivo de terminación es
OOMKilled.El límite de memoria especificado para el contenedor es 500 Mi.
Puede saber a partir de los eventos que el contenedor está siendo muerto porque supera los límites de memoria. Cuando se alcanza el límite de memoria del contenedor, la aplicación se vuelve intermitentemente inaccesible y el contenedor se elimina y se reinicia.
Solución
Puede quitar el límite de memoria y supervisar la aplicación para determinar la cantidad de memoria que realmente necesita. Después de conocer el uso de memoria, puede actualizar los límites de memoria en el contenedor. Si el uso de memoria sigue aumentando, determine si hay una pérdida de memoria en la aplicación.
Para obtener más información acerca de cómo planear recursos para cargas de trabajo en el Servicio De Kubernetes de Azure, consulte Procedimientos recomendados de administración de recursos.