В целях тестирования решил развернуть Kubernetes-кластер, состоящий из 1 Control Plane и 2 Worker-нод на виртуальных машинах в VirtualBox (использовал Ubuntu Server). Для развертывания использовал kubeadm.
Казалось бы, никаких проблем возникнуть не должно, но в итоге пришлось потратить несколько часов на отладку возникшей проблемы. Рассказываю по порядку, как и что происходило.
Виртуальную машину изначально настроил в сетевом режиме Bridge (Сетевой мост) через Wi-Fi. То есть она в локальной домашней сети определяется как отдельное устройство и получает собственный IP-адрес (к примеру, 192.168.0.17). Изначально этот вариант кажется самым удобным, так как виртуальные машины могут напрямую общаться друг с другом и доступны с хоста. Однако здесь всплыл нюанс, из-за которого сетевой мост над Wi-Fi показал себя с неожиданной стороны.
Подготовка репозитория
sudo apt update # обновляем индексы sudo apt install -y apt-transport-https ca-certificates curl gpg # качаем пакеты для использования apt-репозитория k8s # Скачиваем публичный ключ и конвертируем из Base64 в бинарный файл curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg # Добавляем apt-репозиторий echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt update # снова обновляем индексы
После этого выполняем команду для установки необходимых пакетов:
sudo apt-get install -y kubelet kubeadm kubectl
И тут мы упираемся в мертвую стену:
Get:1 https://prod-cdn.packages.k8s.io/repositories/isv:/kubernetes:/core:/stable:/v1.36/deb kubeadm 1.36.3-1.1 [12.6 MB] 1% [1 kubeadm 98.3 kB/12.6 MB 1%] 2,609 B/s 1h 19min 35s
В интерфейсе apt скачивание замирает ровно на 1% (98.3 kB) и скорость падает до нуля. При проверке того же файла через чистый curl процесс намертво застревает еще раньше — ровно на 16 КБ (15 981–16 384 байт), что соответствует размеру одного TLS-кадра. Процесс просто висит до таймаута.
Первичная диагностика: Ping, Traceroute, Curl
Начинаем проверять базовую связность:
r9888@k8s-worker-2:~$ ping prod-cdn.packages.k8s.io PING dkhzw6k7x6ord.cloudfront.net (3.164.68.57) 56(84) bytes of data. 64 bytes from server-3-164-68-57.hel51.r.cloudfront.net (3.164.68.57): icmp_seq=1 ttl=248 time=77.9 ms 4 packets transmitted, 4 received, 0% packet loss
Пинг идет идеально. Запускаем traceroute prod-cdn.packages.k8s.io: пакеты доходят до европейских магистралов (twelve99.net), после чего начинаются звездочки * * *.
Пробуем сделать обычный curl:
r9888@k8s-worker-2:~$ curl prod-cdn.packages.k8s.io <?xml version="1.0" encoding="UTF-8"?> <Error><Code>AccessDenied</Code><Message>Access Denied</Message></Error>
Сервер отвечает мгновенно! То есть базовая связность, DNS и мелкие HTTP-запросы работают.
Самое интересное: на хостовой Windows все качается мгновенно (и с VPN, и без). И этот баг воспроизводится на всех виртуальных машинах в режиме Bridge, но исчезает в режиме NAT.
Гипотеза 1: Проблема в MTU или роутере
Первое подозрение — размер кадра (MTU). На некоторых участках сети большие пакеты могут отбрасываться.
Пробуем уменьшить MTU сначала до 1350, а затем до 1200:
sudo ip link set dev enp0s3 mtu 1200 curl -LO "https://prod-cdn.packages.k8s.io/repositories/isv:/kubernetes:/core:/stable:/v1.36/deb/amd64/kubeadm_1.36.4-1.1_amd64.deb"
Результат тот же: застревание на 15 981 байтах. Уменьшение MTU вообще ничего не изменило.
Раздача мобильного интернета с телефона (USB-Tethering) в режиме Bridge также не решила проблему. Значит, домашний провайдер и роутер ни при чем.
Гипотеза 2: В виртуалке вообще ничего нельзя скачать через Bridge
Проверяем скачивание тяжелых файлов с других CDN прямо из этой же виртуальной машины:
curl -LO https://get.helm.sh/helm-v3.17.0-linux-amd64.tar.gz # 16.6 MB -> Успешно (7.6 MB/s) curl -LO https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip # 69.8 MB -> Успешно (17.1 MB/s) curl -LO "https://corretto.aws/downloads/latest/amazon-corretto-21-x64-linux-jdk.tar.gz" # 199 MB -> Успешно (21.6 MB/s) curl -LO "https://apt.datadoghq.com/pool/d/da/datadog-agent_7.50.0-1_amd64.deb" # 385 MB -> Успешно (22.5 MB/s) curl -LO "https://dl.k8s.io/release/v1.31.0/bin/linux/amd64/kubeadm" # 55 MB (бинарник K8s) -> Успешно
Парадокс: огромные файлы на 400 МБ качаются со скоростью 22 МБ/с. Бинарники Kubernetes с dl.k8s.io качаются без проблем. А зависание происходит исключительно на .deb репозитории prod-cdn.packages.k8s.io.
Дампы трафика (Wireshark + tcpdump + nstat)
Чтобы докопаться до истины, организуем захват трафика одновременно на двух сторонах:
В виртуалке запускаем
sudo tcpdump -i enp0s3 -n host prod-cdn.packages.k8s.io -w vm_traffic.pcapи проверяем счетчики ошибок ядраnstat -az | grep -i CsumErrors.На Windows-хосте запускаем Wireshark с фильтром
ip.addr == 3.164.240.15.
Счетчик TcpInCsumErrors в Linux остался равен 0. Это на 100% доказало, что ядро Linux не отбрасывает пакеты из-за битых контрольных сумм.
А вот в Wireshark есть некоторые полезные данные:
Начало соединения: Успешно проходит TCP 3-way handshake и TLS 1.3 рукопожатие. Виртуалка забирает первые ~25 КБ данных и подтверждает их (
Ack=25684).Точка обрыва: Виртуалка отправляет серверу служебный пакет размером всего 31 байт с флагами
[PSH, ACK](Seq=1894, Len=31).Мертвая блокировка (Deadlock): После этого пакета входящий поток данных останавливается. Виртуалка 9 раз подряд уходит в
[TCP Retransmission], пытаясь переотправить этот служебный кадр, но сервер CloudFront его не получает и встает в ожидание.
Итоговый (возможно) вердикт
Здесь уточню, что я не профессиональный сетевик, так что я до сих пор точно не знаю в чем проблема, и до конца мне ее решить не получилось. Если у вас есть какие-то варианты решения проблемы или вы уже сталкивались с чем-то похожим, пожалуйста, пишите!
Проблема вероятно вызвана узкоспецифичным сбоем на стыке трех факторов, хотя это и не точно:
Ограничения Wi-Fi Bridge (IEEE 802.11): Стандарт Wi-Fi не рассчитан на передачу пакетов с разных MAC-адресов через один радиоканал. Драйвер моста VirtualBox подменяет MAC-адрес виртуалки (
192.168.0.13) «на лету».Тихий сброс PSH/ACK кадров: При обращении к конкретному Edge-узлу CloudFront исходящие мелкие кадры с флагом
PSH, ACKот вторичного виртуального MAC-адреса тихо сбрасываются адаптером или роутером при плотном обмене данными.Строгий TCP-профиль CDN: Данный сервер использует жесткий профиль (TCP BBR / strict SACK или что-то подобное). В отличие от обычных веб-серверов, при потере кадра
PSH, ACKон не снижает скорость и не пытается перезапросить данные «плавно», а мгновенно переходит в режим ожидания.
В итоге я решил отказаться от чистого Bridge для выхода в интернет. Настроить на виртуалках два адаптера: NAT (для доступа в интернет и скачивания пакетов) + Host-Only (для внутренней сети кластера).
Кроме этой проблемы, через несколько часов работы у меня также почему-то стала зависать виртуальная машина с control-plane. У нее просто переставал отвечать экран секунд через 30-40 после запуска, при этом по сети подключиться к ней тоже нельзя, но про это я напишу потом, после того, как попробую с этим как-то разобраться.
Спасибо за прочтение!
andreymal
Дальше даже читать не надо, сразу понятно, что это роскомнадзор
andreymal
Вот про «и без» категорически не верю, потому что у меня на двух разных хостах с двумя разными интернет-провайдерами тоже ничего не качается
Ставлю на то, что автор поста на самом деле имеет постоянно включенный VPN в винде, но забыл или не заметил