Настройка WireGuard-шлюзов для подключения внешних узлов к кластеру
Сервис Yandex Managed Service for Kubernetes позволяет подключать в качестве узлов кластера Kubernetes серверы, расположенные вне Yandex Cloud. Для подключения необходимо организовать сетевую связность между удаленной сетью, в которой расположен внешний сервер, и облачной сетью, в которой находится кластер Managed Service for Kubernetes. Это можно сделать с помощью VPN.
Ниже рассматривается пример организации сетевой связности с помощью протокола WireGuard
Перед началом работы
-
Создайте основную облачную сеть с тремя подсетями в разных зонах доступности.
-
В основной сети создайте кластер Managed Service for Kubernetes с высокодоступным типом мастера.
Для создания внешней группы узлов кластер Managed Service for Kubernetes должен работать в туннельном режиме. Он включается только при создании кластера.
-
Установите kubectl
и настройте его на работу с созданным кластером. -
В основной сети создайте виртуальную машину Compute Cloud с публичным IP-адресом и назовите ее
VM-1
. На этой ВМ будет настроен основной WireGuard-шлюз. -
Создайте дополнительную облачную сеть с одной подсетью.
-
В дополнительной сети создайте виртуальную машину Compute Cloud с публичным IP-адресом и назовите ее
VM-2
. На этой ВМ будет настроен дополнительный WireGuard-шлюз.
Настройка групп безопасности
-
В основной сети создайте группу безопасности и назначьте ее
VM-1
. Добавьте в группу правила:Исходящий трафикВходящий трафикОписание Диапазон портов Протокол Назначение CIDR блоки any
0-65535
Любой
CIDR
0.0.0.0/0
Описание Диапазон портов Протокол Источник CIDR блоки icmp
0-65535
ICMP
CIDR
0.0.0.0/0
ssh
22
TCP
CIDR
0.0.0.0/0
wireguard
51821
UDP
CIDR
<публичный_адрес_VM-2>/32
VM-2-subnet
0-65535
Любой
CIDR
<CIDR_подсети_VM-2>
-
В дополнительной сети создайте группу безопасности и назначьте ее
VM-2
. Добавьте в группу правила:Исходящий трафикВходящий трафикОписание Диапазон портов Протокол Назначение CIDR блоки any
0-65535
Любой
CIDR
0.0.0.0/0
Описание Диапазон портов Протокол Источник CIDR блоки icmp
0-65535
ICMP
CIDR
0.0.0.0/0
ssh
22
TCP
CIDR
0.0.0.0/0
wireguard
51822
UDP
CIDR
<публичный_адрес_VM-1>/32
k8s-VM-1-subnets
0-65535
Любой
CIDR
<CIDR_основной_подсети1>
,<CIDR_основной_подсети2>
,<CIDR_основной_подсети3>
cluster&services
0-65535
Любой
CIDR
<CIDR_кластера>
,<CIDR_сервисов>
-
В группу безопасности кластера и групп узлов Managed Service for Kubernetes добавьте правило:
Входящий трафикОписание Диапазон портов Протокол Источник CIDR блоки VM-2-subnet
0-65535
Любой
CIDR
<CIDR_подсети_VM-2>
Настройка маршрутизации
-
Настройте маршрутизацию для основного WireGuard-шлюза:
-
В основной сети создайте таблицу маршрутизации и добавьте в нее статический маршрут:
- Префикс назначения — укажите CIDR подсети, где расположена
VM-2
. - IP-адрес — укажите внутренний IP-адрес
VM-1
.
- Префикс назначения — укажите CIDR подсети, где расположена
-
Привяжите таблицу маршрутизации ко всем подсетям основной сети.
-
-
Настройте маршрутизацию для дополнительного WireGuard-шлюза:
-
В дополнительной сети создайте таблицу маршрутизации.
-
Добавьте для таблицы маршрутизации статический маршрут:
- Префикс назначения — укажите CIDR подсети, где расположена
VM-1
. - IP-адрес — укажите внутренний IP-адрес
VM-2
.
Повторите этот шаг для каждой подсети основной сети.
- Префикс назначения — укажите CIDR подсети, где расположена
-
Привяжите таблицу маршрутизации к подсети, в которой расположена
VM-2
.
-
Настройка WireGuard-шлюзов
-
Настройте основной WireGuard-шлюз:
-
Подключитесь к
VM-1
по SSH. -
Установите WireGuard:
sudo apt update && sudo apt install wireguard
-
Сгенерируйте и сохраните ключи шифрования:
wg genkey | sudo tee vm1_private.key | wg pubkey | sudo tee vm1_public.key > /dev/null wg genkey | sudo tee vm2_private.key | wg pubkey | sudo tee vm2_public.key > /dev/null
В текущей директории будут созданы четыре файла:
vm1_private.key
— содержит закрытый ключ шифрования дляVM-1
.vm1_public.key
— содержит открытый ключ шифрования дляVM-1
.vm2_private.key
— содержит закрытый ключ шифрования дляVM-2
.vm2_public.key
— содержит открытый ключ шифрования дляVM-2
.
-
Создайте конфигурационный файл
wg0.conf
:sudo nano /etc/wireguard/wg0.conf
-
Добавьте в него конфигурацию:
[Interface] PrivateKey = <содержимое_файла_vm1_private.key> Address = 10.0.0.1/32 ListenPort = 51821 PreUp = sysctl -w net.ipv4.ip_forward=1 [Peer] PublicKey = <содержимое_файла_vm2_public.key> Endpoint = <публичный_адрес_VM-2>:51822 AllowedIPs = <CIDR_подсети_VM-2>, 10.0.0.2/32 PersistentKeepalive = 15
Подробнее о параметрах конфигурации
.Сохраните изменения и закройте файл.
-
Примените конфигурацию:
sudo systemctl restart wg-quick@wg0
-
-
Настройте дополнительный WireGuard-шлюз:
-
Подключитесь к
VM-2
по SSH. -
Установите WireGuard:
sudo apt update && sudo apt install wireguard
-
Создайте конфигурационный файл
wg0.conf
:sudo nano /etc/wireguard/wg0.conf
-
Добавьте в него конфигурацию:
[Interface] PrivateKey = <содержимое_файла_vm2_private.key> Address = 10.0.0.2/32 ListenPort = 51822 PreUp = sysctl -w net.ipv4.ip_forward=1 [Peer] PublicKey = <содержимое_файла_vm1_public.key> Endpoint = <публичный_адрес_VM-1>:51821 AllowedIPs = <CIDR_основной_подсети1>, <CIDR_основной_подсети2>, <CIDR_основной_подсети3>, 10.0.0.1/32 PersistentKeepalive = 15
Подробнее о параметрах конфигурации
.Сохраните изменения и закройте файл.
-
Примените конфигурацию:
sudo systemctl restart wg-quick@wg0
-
-
Проверьте статус соединения на обеих ВМ:
sudo wg show
latest handshake
в выводе команды означает, что соединение установлено:... latest handshake: 3 seconds ago ...
-
Настройте MTU на обеих ВМ:
ETH_NIC=eth0 sudo iptables -t mangle -A FORWARD -i ${ETH_NIC} -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360 sudo iptables -t mangle -A FORWARD -o ${ETH_NIC} -p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 -j TCPMSS --set-mss 1360 echo "net.ipv4.ip_no_pmtu_disc = 1" | sudo tee -a /etc/sysctl.conf sudo sysctl -p /etc/sysctl.conf
Важно
Если оставить значение MTU по умолчанию, возможны потери сетевого трафика.
-
Подключите
VM-2
к кластеру Managed Service for Kubernetes в качестве внешнего узла.
Решение проблем
docker-ce
и containerd
на внешнем узле
Ошибка при работе с пакетами Чтобы диагностировать и исправить ошибку:
-
Посмотрите список служб, которые работают некорректно:
sudo systemctl --failed
Результат:
UNIT LOAD ACTIVE SUB DESCRIPTION docker.socket loaded failed failed Docker Socket for the API LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type. 1 loaded units listed.
-
Проверьте состояние
docker.socket
:sudo systemctl status docker.socket
Результат:
docker.socket - Docker Socket for the API Loaded: loaded (/lib/systemd/system/docker.socket; disabled; vendor preset: enabled) Active: failed (Result: exit-code) since Tue 2024-02-10 09:53:37 UTC; 6s ago Triggers: ● docker.service Listen: /run/docker.sock (Stream) CPU: 1ms Feb 10 09:53:37 ext-node systemd[1]: Starting Docker Socket for the API... Feb 10 09:53:37 ext-node systemd[7052]: docker.socket: Failed to resolve group docker: No such process Feb 10 09:53:37 ext-node systemd[1]: docker.socket: Control process exited, code=exited, status=216/GROUP Feb 10 09:53:37 ext-node systemd[1]: docker.socket: Failed with result 'exit-code'. Feb 10 09:53:37 ext-node systemd[1]: Failed to listen on Docker Socket for the API.
-
Посмотрите ошибки в системных логах:
sudo journalctl -xe
Результат:
... Feb 10 09:56:40 ext-node maintainer[19298]: E: Sub-process /usr/bin/dpkg returned an error code (1) ...
-
Переустановите пакеты и исправьте ошибки:
sudo apt install -f
-
Когда установщик спросит, что делать с файлом
config.toml
, введитеN
, чтобы оставить текущую версию файла.