Контейнер Wireguard не позволяет проводить проверки состояния для контейнера-сайдкара.

Вопрос или проблема

Мне нужно предоставить сервис wireguard в Kubernetes через AWS Network Load Balancer.

Load Balancer не будет направлять трафик на мой pod с wireguard, пока не пройдут проверки работоспособности. Поскольку AWS Load Balancers не поддерживают проверки работоспособности UDP, а wireguard работает на UDP, я прикрепил простой TCP-сервис к pod’у с wireguard, но он недоступен и, следовательно, проверки работоспособности не проходят.

Вот соответствующий фрагмент спецификации деплоймента в yaml.

    spec:
      containers:
        - name: "wireguard"
          image: "linuxserver/wireguard:latest"
          ports:
            - containerPort: 51820
              protocol: UDP
          securityContext:
            privileged: true
            capabilities:
              add:
                - NET_ADMIN
        - name: healthcheck
          image: istio/tcp-echo-server:latest
          imagePullPolicy: IfNotPresent
          args: [ "9000", "hello" ]
          ports:
          - containerPort: 9000

Если я исключу контейнер wireguard или закомментирую часть NET_ADMIN, чтобы убедиться, что конфигурация сети не изменилась, я смогу успешно достичь pod с проверкой работоспособности, запустив, например, следующее:

kubectl run -i --rm --restart=Never dummy --image=busybox -- sh -c "echo world | nc wireguard-service.wg-test 9000"
hello world

В логах контейнера wireguard я вижу, что выполняются следующие команды. Я подозреваю, что в конфигурации маршрутизации узла что-то изменяется, так что порт 9000 становится недоступным.

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.11.0.1/16 dev wg0
[#] ip link set mtu 1450 up dev wg0
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
[#] iptables-restore -n
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
[#] sysctl -w -q net.ipv4.ip_forward=1

Я пробовал добавлять iptables -A INPUT -p tcp --dport 9000 -j ACCEPT и iptables -A FORWARD -p tcp --dport 9000 -j ACCEPT, но безуспешно.
Что я упускаю?

Ответ или решение

Чтобы решить проблему, связанную с невозможностью прохождения healthcheck для Wireguard контейнера через вспомогательный (sidecar) контейнер в Kubernetes, необходимо рассмотреть несколько аспектов и шагов настройки. Давайте разберем теорию, пример и применение для решения этой проблемы.

Теория

Wireguard — это современный, высокопроизводительный и безопасный VPN-протокол, который работает через UDP. Однако, AWS Network Load Balancer (NLB) не поддерживает проверку состояния (healthcheck) на уровне UDP. Для обеспечения корректной работы NLB с Wireguard необходимо использовать подходы, которые предусматривают промежуточные healthcheck over TCP.

Основные проблемы возникают из-за того, что Wireguard вносит изменения в конфигурацию сети, которые могут блокировать доступ к другому контейнеру, ответственному за TCP healthcheck. Эти изменения включают добавление сетевых интерфейсов, маршрутизацию и конфигурации iptables, которые могут помешать маршрутизации трафика, предназначенного для TCP порта healthcheck контейнера.

Пример

В примерном YAML манифесте деплоймента, предоставленном в вопросе, вы уже добавили TCP healthcheck контейнер в виде sidecar. Однако конфигурация Wireguard контейнера изменяет сетевую топологию под таким образом, что делает порт 9000 недоступным.

Текущая конфигурация Wireguard контейнера может содержать следующие команды, которые вызывают проблему:

ip link add wg0 type wireguard
wg setconf wg0 /dev/fd/63
ip -4 address add 10.11.0.1/16 dev wg0
ip link set mtu 1450 up dev wg0
wg set wg0 fwmark 51820
ip -4 route add 0.0.0.0/0 dev wg0 table 51820
ip -4 rule add not fwmark 51820 table 51820
ip -4 rule add table main suppress_prefixlength 0
sysctl -q net.ipv4.conf.all.src_valid_mark=1
iptables-restore -n
iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sysctl -w -q net.ipv4.ip_forward=1

Основная проблема заключается в изменении таблиц маршрутизации и правил iptables, которые могут блокировать доступ к порту 9000.

Применение

  1. Разделение сетевых пространств: Рассмотрите возможность использования Network Namespaces или сетевого изолятора, чтобы убедиться, что изменения, которые Wireguard приносит в сетевые настройки, изолированы и не влияют на другие контейнеры.

  2. Настройка iptables:

    • Проверьте и измените правила iptables, чтобы обеспечить маршрутизацию трафика к TCP порту.
    • Попробуйте добавить следующие правила:
      iptables -A PREROUTING -t mangle -p tcp --dport 9000 -j MARK --set-mark 51820
      iptables -A OUTPUT -t mangle -p tcp --sport 9000 -j MARK --set-mark 51820
      iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
  3. Проверка маршрутизации: Убедитесь, что правило ip -4 rule add table main suppress_prefixlength 0 действительно необходимо. Оно может блокировать весь внешнюю маршрутизацию для других портов.

  4. Использование Host Network: Вместо использования под-сетей Kubernetes, настройте Wireguard контейнер на использование Host Network. Это может снизить количество изменений, необходимых в конфигурации сетевого стека.

  5. Отладка сетевых проблем: Используйте инструменты, такие как tcpdump или iptables-save для подробного анализа движения пакетов и идентификации блокирующих правил.

  6. Обновление конфигурации Load Balancer: Проверьте возможность использования другого механизма healthcheck, например HTTP код возврата от пинг-сервера, который будет проксироовать запросы на порт 9000.

  7. Логирование и мониторинг: Настройте логирование, чтобы детально отслеживать изменения и прохождение пакетов через iptables, позволяющее определить точные места, где происходит блокировка.

Соблюдение этих рекомендаций может помочь вам в корректной настройке контейнеров в Kubernetes и обеспечении доступности вашего Wireguard сервиса через AWS NLB. Если проблема сохраняется, может потребоваться более детальный анализ сетевых конфигураций и взаимодействий контейнеров.

Оцените материал
Добавить комментарий

Капча загружается...