angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Использование IPv6 с Microk8s

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

3 декабря 2024
post main image
https://www.pexels.com/@sedanur-kunuk-78972032

Для части моего приложения, состоящего из нескольких проектов 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

Оставить комментарий

Комментируйте анонимно или войдите в систему, чтобы прокомментировать.

Комментарии

Оставьте ответ

Ответьте анонимно или войдите в систему, чтобы ответить.