Использование IPv6 с Microk8s
Настройка двухстекового Microk8s гораздо проще, чем ожидалось.

Для части моего приложения, состоящего из нескольких проектов Docker-Compose, мне понадобился доступ к внешним сервисам, работающим только по протоколу IPv6. В предыдущих постах я писал, что уже перенес часть своего приложения с Docker на Microk8s (Kubernetes). Это та часть, которая требует доступа к внешним службам IPv6. Приложение Docker взаимодействует с приложением Microk8s с помощью NodePort или Ingress Controller.
Моя машина для разработки находится в локальной сети только с IPv4, и мое подключение к Интернету также IPv4. Я, конечно, не хочу менять подключение к интернету с IPv4 на IPv6.
В этом посте мы создадим тестовую среду IPv6, фактически двухстековую, где мы сможем запустить приложение в Microk8s , которое сможет получить доступ к фиктивной службе IPv6, запущенной на виртуальной машине, созданной с помощью VirtualBox.
Как обычно, я делаю это на Ubuntu 22.04 Desktop.
Об адресах IPv6
Хотя IPv6 не очень сложный, хорошие объяснения о нем можно найти в книге 'IPv6 Explained for Beginners', см. ссылки ниже, очень полезно.
Вкратце, IPv6-адрес состоит из 128 бит. Они делятся на сетевую часть и часть узла, каждая из которых имеет 64 бита. Из сети верхние 48 бит используются для маршрутизации в Интернете.
Здесь мы используем IPv6-документацию prefix, 2001:db8::/32. Из документа "Understanding the IPv6 Documentation Prefix: 2001:db8::/32", см. ссылки ниже: Это зарезервированный диапазон адресов IPv6, выделенный для использования в документации, примерах и учебных материалах. Этот диапазон prefix был выбран для того, чтобы исключить случайную маршрутизацию любых адресов, использующих его, в Интернет, тем самым предотвращая конфликты с реальными IPv6-адресами.
Это означает, что сетевая часть состоит из 32 бит. Для нашей сети мы добавим 'abcd:0012'.
Пример адреса узла в нашей сети:
2001:db8:abcd:12::1
Что является сокращением:
2001:0db8:abcd:0012:0000:0000:0000:0001
Префикс" - это то же самое, что маска в IPv4.
Включение и отключение IPv6 на Ubuntu
В Ubuntu мы можем включать и отключать настройки IPv6 с помощью команды sysctl. Для просмотра настроек:
sysctl -a 2>/dev/null | grep disable_ipv6
Давным-давно я отключил IPv6 на своей машине для разработки. Я добавил следующее:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1
В файл:
/etc/sysctl.conf
Теперь я должен снова закомментировать эти строки.
Мы также можем установить эти значения временно, например:
sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0
Чтобы снова загрузить все настройки, выполним команду:
sudo sysctl --system
Все значения 'disable_ipv6' должны быть равны '0'.
Также убедитесь, что файл:
/etc/hosts
содержит следующие строки, где ::1 - адрес loopback:
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Конфигурация машины разработки и VirtualBox
Машина разработки, Ubuntu Desktop, уже использовала IPv4, мне нужно было только добавить IPv6. У нас нет шлюза или DNS-сервера, поэтому мы просто прописали туда несколько случайных адресов.
Используя VirtualBox, мы создаем сервер Ubuntu 22.04. Мы назначаем следующие адреса для машины разработки и новой виртуальной машины:
Ubuntu 220.04 Desktop
Address: 2001:db8:abcd:12::1
Prefix: 64
Gateway: 2001:db8:abcd:12::2
DNS: Automatic
Routes: Automatic
Ubuntu 220.04 Server (Virtualbox)
Address: 2001:db8:abcd:12::1:1/64
Prefix: 64
Gateway: 2001:db8:abcd:12::2
DNS: Automatic
Routes: Automatic
На нашем сервере VirtualBox Ubuntu 22.04 мы используем 'Bridged Adapter' для работы в сети. В сервере Ubuntu 22.04 мы редактируем конфигурацию сети в:
/etc/netplan/00-installer-config.yaml
Contents:
network:
ethernets:
enp0s3:
dhcp4: no
dhcp6: no
addresses:
- 192.168.1.26/24
- 2001:db8:abcd:12::1:1/64
nameservers:
addresses:
- 192.168.1.2
- 2606:4700:4700::1111
routes:
- to: default
via: 192.168.1.1
- to: default
via: "2001:db8:abcd:12::2"
version: 2
Обратите внимание, что я включил сюда настройки IPv4. Я не знаю, включают ли настройки SSH-сервера по умолчанию IPv6. Теперь мы можем войти в систему, по крайней мере, через IPv4. После этого мы снова активируем его:
sudo netplan apply
На обеих машинах мы можем проверить IPv6-адреса:.
На машине разработки:
ip a | grep inet6
Результат:
inet6 ::1/128 scope host
inet6 2001:db8:abcd:12::1/64 scope global noprefixroute
inet6 fe80::fe11:314e:9bb4:73c1/64 scope link noprefixroute
...
На виртуальной машине:
ip a | grep inet6
Результат:
inet6 ::1/128 scope host
inet6 2001:db8:abcd:12::1:1/64 scope global
inet6 fe80::a00:27ff:feda:7026/64 scope link
...
Проверьте IPv6 на обеих машинах, и если они могут взаимодействовать
На обеих машинах мы можем запустить:
ping6 ::1
Результат:
64 bytes from ip6-localhost: icmp_seq=0 ttl=64 time=0,078 ms
64 bytes from ip6-localhost: icmp_seq=1 ttl=64 time=0,048 ms
64 bytes from ip6-localhost: icmp_seq=2 ttl=64 time=0,048 ms
На машине разработки мы пингуем виртуальную машину:
ping6 2001:db8:abcd:12::1:1
На виртуальной машине мы пингуем машину разработки:
ping6 2001:db8:abcd:12::1
Наконец, мы проверяем, можем ли мы запустить службу на виртуальной машине, и смотрим, можем ли мы получить доступ к этой службе.
На виртуальной машине мы запускаем 'netcat' и привязываем ее к IPv6-адресу:
nc -l 2001:db8:abcd:12::1:1 3492
На машине разработки запускаем 'telnet', набираем 'hello' и проверяем, передается ли эхо:
telnet -6 2001:db8:abcd:12::1:1 3492
Результат:
Trying 2001:db8:abcd:12::1:1...
Connected to 2001:db8:abcd:12::1:1.
Escape character is '^]'.
hello
^]
telnet> quit
Connection closed.
Работает, приятно.
Установка Microk8s с двойным стеком
Это оказалось гораздо проще, чем ожидалось. Я следовал инструкциям из поста "Как настроить сетевой Dual-stack", см. ссылки ниже.
На машине разработки сначала создаем файл:
/var/snap/microk8s/common/.microk8s.yaml
со следующим содержимым:
---
version: 0.1.0
extraCNIEnv:
IPv4_SUPPORT: true
IPv4_CLUSTER_CIDR: 10.3.0.0/16
IPv4_SERVICE_CIDR: 10.153.183.0/24
IPv6_SUPPORT: true
IPv6_CLUSTER_CIDR: fd02::/64
IPv6_SERVICE_CIDR: fd99::/108
extraSANs:
- 10.153.183.1
addons:
- name: dns
Примечание(и):
- Здесь мы включаем 'dns'. Если вы не сделали этого здесь, то должны сделать это после установки Microk8s!
- Здесь мы назначаем уникальные Local Addresses (ULA), они не могут быть маршрутизированы в публичный Интернет.
Затем мы устанавливаем Microk8s:
snap install microk8s --classic
Проверьте, назначены ли стручкам IPv4 и IPv6 адреса, например, запустив программу:
microk8s kubectl -n kube-system describe pod
Должно появиться что-то вроде этого для каждого стручка:
...
IPs:
IP: 10.3.105.121
IP: fd02::332e:7684:ac2:6979
...
Теперь запускаем BusyBox в Microk8s:
kubectl run -i -t busybox --image=busybox --restart=Never
После запуска мы можем проверить, был ли назначен IPv6-адрес:
cat /etc/hosts
Результат:
# Kubernetes-managed hosts file.
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.3.105.122 busybox
fd02::332e:7684:ac2:697a busybox
Тесты IPv6 с Microk8s
На машине разработки запустите слушателя 'netcat' :
nc -l 2001:db8:abcd:12::1 3491
Затем в терминале BusyBox пробуем подключиться и вводим сообщение:
telnet -6 2001:db8:abcd:12::1 3491
Результат:
Connected to 2001:db8:abcd:12::1
hello
^]
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
e
Теперь запустите слушатель 'netcat' на виртуальной машине:
nc -l 2001:db8:abcd:12::1:1 3492
Снова в BusyBox на машине разработки пытаемся подключиться:
telnet 2001:db8:abcd:12::1:1 3492
Не подключается! Этого следовало ожидать. Исходящий IPv6-трафик заблокирован.
Из заметки "Включение IPv6 для SC4SNMP", см. ссылки ниже: По умолчанию CNI, используемый для microk8s , - это Calico. Чтобы подсы могли выходить в интернет по IPv6, необходимо включить параметр natOutgoing в конфигурации ipv6 ip pool из Calico. Для его установки создайте yaml-файл со следующим содержимым:
# calico-ippool.yaml
---
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
name: default-ipv6-ippool
spec:
natOutgoing: true
Активировать:
microk8s kubectl apply -f calico-ippool.yaml
Остановите и запустите Microk8s:
microk8s stop
microk8s start
Теперь удалите и перезапустите BusyBox pod:
kubectl delete pod busybox
kubectl run -i -t busybox --image=busybox --restart=Never
Снова в BusyBox на машине разработки пробуем подключиться к листеру на виртуальной машине и набираем сообщение:
telnet 2001:db8:abcd:12::1:1 3492
Результат:
Connected to 2001:db8:abcd:12::1:1
hello
^]
Console escape. Commands are:
l go to line mode
c go to character mode
z suspend telnet
e exit telnet
e
Отлично, теперь все работает!
Подробнее о Calico и IP-пулах
Calico (Project Calico Documentation) - это решение open source для организации сетей и сетевой безопасности контейнеров, виртуальных машин и рабочих нагрузок на базе хоста.
Из статьи 'Microk8s - Configure Calico', см. ссылки ниже: В большинстве случаев [] для изменения конфигурации Calico необходимо внести исправления в развернутый cni.yaml, а затем заново применить его к кластеру.
Чтобы проверить api-ресурсы Calico:
kubectl api-resources | grep 'projectcalico.org'
Результат:
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
caliconodestatuses crd.projectcalico.org/v1 false CalicoNodeStatus
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
ipreservations crd.projectcalico.org/v1 false IPReservation
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
Получить IP-пулы:
kubectl get ippools
Результат:
NAME AGE
default-ipv4-ippool 11d
default-ipv6-ippool 11d
Описать IP-пулы:
kubectl describe IPPool
Результат:
Name: default-ipv4-ippool
Namespace:
Labels:
Annotations: projectcalico.org/metadata: {"uid":"421fa69c-6657-4bd3-8bba-a06681c33c82","creationTimestamp":"2024-11-21T14:11:25Z"}
API Version: crd.projectcalico.org/v1
Kind: IPPool
Metadata:
Creation Timestamp: 2024-11-21T14:11:25Z
Generation: 1
Resource Version: 108882
UID: 50e3ccfc-627d-42f8-aaa3-a61e6553f8ed
Spec:
Allowed Uses:
Workload
Tunnel
Block Size: 26
Cidr: 10.3.0.0/16
Ipip Mode: Never
Nat Outgoing: true
Node Selector: all()
Vxlan Mode: Always
Events:
Name: default-ipv6-ippool
Namespace:
Labels:
Annotations: projectcalico.org/metadata: {"uid":"8377dd46-681d-4dbd-88a4-86e04a1d52c3","creationTimestamp":"2024-11-21T14:11:25Z"}
API Version: crd.projectcalico.org/v1
Kind: IPPool
Metadata:
Creation Timestamp: 2024-11-21T14:11:25Z
Generation: 2
Resource Version: 1506748
UID: 49501699-831f-4317-9c9f-2d2b15168547
Spec:
Allowed Uses:
Workload
Tunnel
Block Size: 122
Cidr: fd02::/64
Ipip Mode: Never
Nat Outgoing: true
Node Selector: all()
Vxlan Mode: Always
Events:
Обратите внимание, что 'Nat Outgoing' имеет значение 'true' как для 'default-ipv4-ippool', так и для 'default-ipv6-ippool'.
Мы также можем использовать calicoctl. Но сначала мы должны установить его.
Чтобы получить текущую версию Calico, установите ее в Microk8s:
kubectl -n kube-system describe pod calico-kube-controllers-759cd8b574-wscp9 | grep Image
Результат:
Image: docker.io/calico/kube-controllers:v3.25.1
Image ID: docker.io/calico/kube-controllers@sha256:02c1232ee4b8c5a145c401ac1adb34a63ee7fc46b70b6ad0a4e068a774f25f8a
Это означает, что текущая версия Calico:
v3.25.1
Чтобы получить манифест calicoctl:
wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml
Активировать:
kubectl apply -f calicoctl.yaml
Проверить, работает ли она:
kubectl get pods -A
Результат:
NAMESPACE NAME READY STATUS RESTARTS AGE
...
kube-system calicoctl 1/1 Running 0 2m17s
...
Получить профили Calico:
kubectl exec -ti -n kube-system calicoctl -- /calicoctl get profiles -o wide
Результат:
NAME LABELS
projectcalico-default-allow
kns.default pcns.kubernetes.io/metadata.name=default,pcns.projectcalico.org/name=default
kns.ingress pcns.kubernetes.io/metadata.name=ingress,pcns.projectcalico.org/name=ingress
kns.kube-node-lease pcns.kubernetes.io/metadata.name=kube-node-lease,pcns.projectcalico.org/name=kube-node-lease
...
Создать псевдоним calicoctl:
alias calicoctl="kubectl exec -i -n kube-system calicoctl -- /calicoctl"
Теперь мы можем выполнить приведенную выше команду следующим образом:
calicoctl get profiles -o wide
Мы также можем использовать calicoctl для получения IP-пулов:
calicoctl get ippools
Результат:
NAME CIDR SELECTOR
default-ipv4-ippool 10.3.0.0/16 all()
default-ipv6-ippool fd02::/64 all()
Показать еще:
calicoctl get IPPool default-ipv6-ippool -o wide
Результат:
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv6-ippool fd02::/64 true Never Always false false all()
Мы можем удалить или создать IP-пул:
calicoctl delete ippool <ippool-to-delete>
cat <<EOF | calicoctl create -f -
- apiVersion: v1
kind: ipPool
metadata:
cidr: fd0e:c226:9228:fd1a::/64
spec: {}
EOF
Или заменить существующий IP-пул. Пример:
calicoctl replace -f - << EOF
apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv6-ippool
spec:
blockSize: 122
cidr: fd01::/64
ipipMode: Never
nodeSelector: all()
vxlanMode: Never
natOutgoing: true
EOF
Резюме
Мы создали среду тестирования IPv6 для приложений Microk8s , которые должны получать доступ к внешним службам IPv6. С помощью VirtualBox мы создали серверную виртуальную машину Ubuntu и включили IPv6 как на машине разработки, так и на виртуальной машине. Затем мы установили двухстековый Microk8s на машину разработки и включили исходящий IPv6-трафик. Теперь мы можем передать 'telnet' внутри Microk8s на машине разработки службе IPv6, запущенной на виртуальной машине.
Ссылки / кредиты
Building a multi-node IPv6-enabled bare-metal kubernetes cluster with microk8s, metallb, longhorn and VyOS
https://blog.mowoe.com/building-a-multi-node-ipv6-enabled-bare-metal-kubernetes-cluster-with-microk8s-metallb-longhorn-and-vyos.html
calicoctl user reference
https://docs.tigera.io/calico/latest/reference/calicoctl/overview
How to configure network Dual-stack
https://discuss.kubernetes.io/t/how-to-configure-network-dual-stack/24784
IPv6 Explained for Beginners
http://www.steves-internet-guide.com/ipv6-guide
IPv6 masquerading for egress on microk8s on EC2
https://www.checklyhq.com/blog/ipv6-masquerading-for-egress-on-microk8s-on-ec2
Kubernetes - IPv4/IPv6 dual-stack
https://kubernetes.io/docs/concepts/services-networking/dual-stack
Microk8s - Configure Calico
https://microk8s.io/docs/change-cidr
Understanding the IPv6 Documentation Prefix: 2001:db8::/32
https://ipv6.net/blog/understanding-the-ipv6-documentation-prefix-2001db8-32
Подробнее
Kubernetes Microk8s Networking
Недавний
- График временного ряда с Flask, Bootstrap и Chart.js
- Использование IPv6 с Microk8s
- Использование Ingress для доступа к RabbitMQ на кластере Microk8s
- Простая видеогалерея с Flask, Jinja, Bootstrap и JQuery
- Базовое планирование заданий с помощью APScheduler
- Коммутатор базы данных с HAProxy и HAProxy Runtime API
Большинство просмотренных
- Использование PyInstaller и Cython для создания исполняемого файла Python
- Уменьшение времени отклика на запросы на странице Flask SQLAlchemy веб-сайта
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Подключение к службе на хосте Docker из контейнера Docker
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов