У меня есть управляемый кластер Kubernetes в Azure (AKS). Есть один модуль, на котором запущена простая веб-служба, которая отвечает на вызовы REST API извне и вызывает сервер Kubernetes API. Эти звонки составляют список и создают рабочие места.
Для AKS у меня есть «продвинутая» (Azure CNI) сеть с настраиваемой таблицей маршрутизации, которая перенаправляет трафик на виртуальное устройство - это настройка моей компании.
Я использую официальный клиент Python для Kubernetes. Звонки выглядят так:
config.load_incluster_config()
k8s_batch_api_client = client.BatchV1Api()
jobs = k8s_batch_api_client.list_namespaced_job(namespace = 'default')
Так что ничего особенного.
В большинстве случаев все работает нормально. Однако время от времени сервер API Kubernetes просто не отвечает на запросы, поэтому веб-сервис моего модуля перезапускается после тайм-аута (он запускает gunicorn
-на основе веб-сервера).
Я установил tcpdump
на моем модуле и обнюхивал TCP-трафик. Я не фанат нетворкинга, так что потерпите меня.
Клиент Python поддерживает пул TCP-соединений (используя urllib3
библиотека). И кажется, что сервер API Kubernetes просто молча «теряет» TCP-соединение, просто больше не реагирует, не закрывая соединение.
В Wireshark я вижу это для рабочего запроса-ответа:
2438 09:41:50,796695 10.214.140.39 192.168.0.1 TLSv1.3 1614 Application Data
2439 09:41:50,798552 192.168.0.1 10.214.140.39 TCP 66 443 → 56480 [ACK]
2440 09:41:50,804064 192.168.0.1 10.214.140.39 TLSv1.3 2196 Application Data
10.214.140.39
это моя капсула, 192.168.0.1
- это сервер API Kubernetes. Здесь мы видим запрос и ответ.
Но потом:
2469 09:48:48,853533 10.214.140.39 192.168.0.1 TLSv1.3 1580 Application Data
2470 09:48:48,853604 10.214.140.39 192.168.0.1 TLSv1.3 1279 Application Data
2471 09:48:48,868222 10.214.140.39 192.168.0.1 TCP 1279 [TCP Retransmission] 56480 → 443 [PSH, ACK]
2472 09:48:49,076276 10.214.140.39 192.168.0.1 TCP 1452 [TCP Retransmission] 56480 → 443 [ACK]
... lots of retransmissions...
Я не вижу FIN
TCP-пакет от сервера API Kubernetes (что означает, что сервер хочет закрыть соединение).
После перезапуска (2 минуты повторных передач -> перезагрузка) мой модуль может сразу установить соединение с сервером API, поэтому сам сервер API не будет перегружен.
Это же приложение работает без каких-либо проблем в моем локальном кластере Minikube (но, конечно, там только один узел, поэтому не совсем репрезентативный).
Как я могу изучить проблему дальше? Может ли это быть вызвано клиентской стороной (моим модулем или клиентом Python)? Есть ли какие-то особые настройки, которые я должен изменить в AKS или на стороне клиента, чтобы этого избежать? Это похоже на «ошибку сервера» или «проблему сети»?