Периодические ожидания или проблемы с сервером при доступе к приложению в AKS

В этой статье описывается устранение периодических проблем с подключением, влияющих на приложения, размещенные в кластере Служба Azure Kubernetes (AKS).

Предварительные требования

  • Средство URL-адреса клиента (cURL) или аналогичное средство командной строки.

  • Средство Kubernetes kubectl или аналогичное средство для подключения к кластеру. Чтобы установить kubectl с помощью Azure CLI, выполните команду az aks install-cli .

Симптомы

При выполнении команды cURL иногда появляется сообщение об ошибке "Истекло время ожидания". Выходные данные могут выглядеть следующим образом:

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

Причина

Периодические тайм-ауты указывают на проблемы с производительностью компонентов, а не проблемы с сетью.

В этом сценарии важно проверка использование и работоспособность компонентов. Для проверка состояния модулей pod можно использовать метод "внутренний выход". Выполните команды kubectl top и kubectl get следующим образом:

$ 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

В выходных данных показано, что текущее использование модулей pod и узлов является приемлемым.

Хотя модуль pod находится в Running состоянии , после первых 108 секунд выполнения pod выполняется одна перезагрузка. Это может указывать на то, что некоторые проблемы влияют на модули pod или контейнеры, выполняемые в pod.

Если проблема не исчезнет, состояние pod изменится через некоторое время:

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

В этом примере показано, что Ready состояние изменено, и существует несколько перезапусков pod. Один из контейнеров находится в CrashLoopBackOff состоянии.

Эта ситуация возникает из-за сбоя контейнера после запуска, а затем Kubernetes пытается перезапустить контейнер, чтобы заставить его начать работу. Однако если проблема не исчезнет, приложение продолжит завершать сбой после запуска в течение некоторого времени. Kubernetes в конечном итоге изменяет состояние на CrashLoopBackOff.

Чтобы проверка журналы для модуля pod, выполните следующие команды 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

Записи журнала были сделаны при предыдущем запуске контейнера. Наличие этих записей свидетельствует о том, что приложение действительно было запущено, но оно было закрыто из-за некоторых проблем.

Следующим шагом является проверка событий pod, выполнив команду 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

Наблюдения:

По событиям можно определить, что контейнер уничтожается из-за превышения ограничений памяти. При достижении предельного объема памяти контейнера приложение становится периодически недоступным, а контейнер будет уничтожен и перезапущен.

Решение

Вы можете удалить ограничение памяти и отслеживать приложение, чтобы определить, сколько памяти ему фактически требуется. После изучения использования памяти можно обновить ограничения памяти в контейнере. Если использование памяти продолжает увеличиваться, определите, произошла ли утечка памяти в приложении.

Дополнительные сведения о планировании ресурсов для рабочих нагрузок в Служба Azure Kubernetes см. в статье Рекомендации по управлению ресурсами.

Свяжитесь с нами для получения помощи

Если у вас есть вопросы или вам нужна помощь, создайте запрос в службу поддержки или обратитесь за поддержкой сообщества Azure. Вы также можете отправить отзыв о продукте в сообщество отзывов Azure.