Compartilhar via


Tempos limite intermitentes ou problemas de servidor ao acessar o aplicativo no AKS

Este artigo descreve como solucionar problemas de conectividade intermitente que afetam seus aplicativos hospedados em um cluster do AKS (Serviço de Kubernetes do Azure).

Pré-requisitos

  • A ferramenta URL do cliente (cURL) ou uma ferramenta de linha de comando semelhante.

  • A ferramenta kubectl do Kubernetes ou uma ferramenta semelhante para se conectar ao cluster. Para instalar o kubectl usando a CLI do Azure, execute o comando az aks install-cli .

Sintomas

Ao executar um comando cURL, você ocasionalmente recebe uma mensagem de erro "Tempo limite". A saída pode ser semelhante ao seguinte texto:

$ # 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

Motivo

Tempos limite intermitentes sugerem problemas de desempenho de componentes, em oposição a problemas de rede.

Nesse cenário, é importante verificar o uso e a integridade dos componentes. Você pode usar a técnica de dentro para fora para verificar o status dos pods. Execute os comandos kubectl top e kubectl get , da seguinte maneira:

$ 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

A saída mostra que o uso atual dos pods e nós parece ser aceitável.

Embora o pod esteja no Running estado, uma reinicialização ocorre após os primeiros 108 segundos da execução do pod. Essa ocorrência pode indicar que alguns problemas afetam os pods ou contêineres executados no pod.

Se o problema persistir, o status do pod será alterado após algum tempo:

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

Este exemplo mostra que o Ready estado foi alterado e há várias reinicializações do pod. Um dos contêineres está no CrashLoopBackOff estado.

Essa situação ocorre porque o contêiner falha após a inicialização e, em seguida, o Kubernetes tenta reiniciar o contêiner para forçá-lo a começar a funcionar. No entanto, se o problema persistir, o aplicativo continuará falhando após ser executado por algum tempo. O Kubernetes eventualmente altera o status para CrashLoopBackOff.

Para verificar os logs do pod, execute os seguintes comandos kubectl logs :

$ 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

As entradas de log foram feitas na vez anterior em que o contêiner foi executado. A existência dessas entradas sugere que o aplicativo foi iniciado, mas foi fechado devido a alguns problemas.

Verifique o serviço associado à implantação e tente curl o IP do cluster de dentro do cluster para identificar o problema:

$ 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

A próxima etapa é verificar os eventos do pod executando o 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

Observações:

  • O código de saída é 137. Para obter mais informações sobre códigos de saída, consulte a referência de execução do Docker e Códigos de saída com significados especiais.

  • O motivo da rescisão é OOMKilled.

  • O limite de memória especificado para o contêiner é de 500 Mi.

Você pode dizer pelos eventos que o contêiner está sendo morto porque está excedendo os limites de memória. Quando o limite de memória do contêiner é atingido, o aplicativo fica intermitentemente inacessível e o contêiner é encerrado e reiniciado.

Observação

Recomendamos configurar testes de atividade, preparação e inicialização na definição do pod. Dependendo do comportamento do aplicativo, essa configuração pode ajudar a recuperar o aplicativo de problemas inesperados. Seja cauteloso ao configurar testes de atividade.

Solução

Você pode remover o limite de memória e monitorar o aplicativo para determinar quanta memória ele realmente precisa. Depois de aprender o uso de memória, você pode atualizar os limites de memória no contêiner. Se o uso de memória continuar a aumentar, determine se há um vazamento de memória no aplicativo.

Para obter mais informações sobre como planejar recursos para cargas de trabalho no Serviço de Kubernetes do Azure, consulte práticas recomendadas de gerenciamento de recursos.

Entre em contato conosco para obter ajuda

Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.