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

Verwendung von IPv6 mit Microk8s

Die Konfiguration von Dual-Stack Microk8s ist viel einfacher als erwartet.

3 Dezember 2024
post main image
https://www.pexels.com/@sedanur-kunuk-78972032

Für einen Teil meiner Anwendung, die aus mehreren Docker-Compose-Projekten besteht, benötigte ich Zugang zu externen IPv6-only-Diensten. In früheren Beiträgen schrieb ich, dass ich bereits einen Teil meiner Anwendung von Docker nach Microk8s (Kubernetes) verschoben habe. Dies ist der Teil, der den Zugang zu den externen IPv6-Diensten erfordert. Die Anwendung Docker kommuniziert mit der Anwendung Microk8s über einen NodePort oder Ingress Controller.

Mein Entwicklungsrechner befindet sich in einem lokalen IPv4-Netzwerk, und meine Internetverbindung ist ebenfalls IPv4. Ich möchte auf keinen Fall meine ISP-Verbindung von IPv4 auf IPv6 umstellen.

In diesem Beitrag erstellen wir eine IPv6-, genauer gesagt eine Dual-Stack-Testumgebung, in der wir eine Anwendung in Microk8s ausführen können, die auf einen IPv6-Dummy-Dienst zugreifen kann, der auf einer mit VirtualBox erstellten virtuellen Maschine läuft.

Wie immer mache ich dies auf Ubuntu 22.04 Desktop.

Über IPv6-Adressen

Obwohl nicht sehr komplex, finden sich gute Erklärungen zu IPv6 in 'IPv6 Explained for Beginners', siehe Links unten, sehr hilfreich.

Kurz gesagt, eine IPv6-Adresse besteht aus 128 Bits. Diese sind in einen Netzwerk- und einen Knoten-Teil aufgeteilt, die jeweils 64 Bits haben. Vom Netzwerkteil werden die oberen 48 Bits für das Routing über das Internet verwendet.

Hier verwenden wir die IPv6-Dokumentation prefix, 2001:db8::/32. Aus dem Dokument "Understanding the IPv6 Documentation Prefix: 2001:db8::/32", siehe Links unten: Dies ist ein reservierter Bereich von IPv6-Adressen, der für die Verwendung in Dokumentationen, Beispielen und Lehrmaterialien vorgesehen ist. Dieser prefix wurde gewählt, um sicherzustellen, dass Adressen, die ihn verwenden, nicht versehentlich ins Internet geroutet werden und somit Konflikte mit realen IPv6-Adressen vermieden werden.

Das bedeutet, dass der Netzwerkteil 32-Bit lang ist. Für unser Netzwerk fügen wir 'abcd:0012' hinzu.

Beispieladresse eines Knotens in unserem Netzwerk:

2001:db8:abcd:12::1

Das ist die Abkürzung für:

2001:0db8:abcd:0012:0000:0000:0000:0001

Das 'Präfix' ist wie die Maske in IPv4.

Aktivieren und Deaktivieren von IPv6 auf Ubuntu

In Ubuntu können wir IPv6-Einstellungen mit dem Befehl sysctl aktivieren und deaktivieren. Um die Einstellungen zu sehen:

sysctl -a 2>/dev/null | grep disable_ipv6

Vor langer Zeit habe ich IPv6 auf meinem Entwicklungsrechner deaktiviert. Ich habe Folgendes hinzugefügt:

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

In die Datei:

/etc/sysctl.conf

Jetzt muss ich diese Zeilen wieder auskommentieren.

Wir können diese Werte auch temporär setzen, Beispiel:

sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0

Um alle Einstellungen wieder zu laden, geben wir den Befehl:

sudo sysctl --system

Alle 'disable_ipv6' Werte sollten '0' sein.

Stellen Sie außerdem sicher, dass die Datei:

/etc/hosts

die folgenden Zeilen enthält, wobei ::1 die Loopback-Adresse ist:

::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

Konfiguration der Entwicklungsmaschine und des VirtualBox

Der Entwicklungsrechner, Ubuntu Desktop, verwendete bereits IPv4, ich musste nur noch IPv6 hinzufügen. Wir haben weder ein Gateway noch einen DNS-Server, also setzen wir dort einfach ein paar zufällige Adressen ein.
Mit VirtualBox erstellen wir einen Ubuntu 22.04 Server. Wir weisen dem Entwicklungsrechner und der neuen virtuellen Maschine die folgenden Adressen zu:

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

Auf unserem VirtualBox Ubuntu 22.04 Server verwenden wir den 'Bridged Adapter' für die Vernetzung. In Ubuntu 22.04 Server, bearbeiten wir die Netzwerkkonfiguration in:

/etc/netplan/00-installer-config.yaml

Inhalt:

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

Beachten Sie, dass ich hier IPv4-Einstellungen angegeben habe. Ich weiß nicht, ob die Standardeinstellungen des SSH-Servers IPv6 enthalten. Jetzt können wir uns zumindest über IPv4 anmelden. Wenn das erledigt ist, aktivieren wir ihn wieder:

sudo netplan apply

Auf beiden Rechnern können wir die IPv6-Adressen überprüfen:.

Auf dem Entwicklungsrechner:

ip a | grep inet6

Ergebnis:

    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 
    ...

Auf dem virtuellen Rechner:

ip a | grep inet6

Ergebnis:

    inet6 ::1/128 scope host 
    inet6 2001:db8:abcd:12::1:1/64 scope global 
    inet6 fe80::a00:27ff:feda:7026/64 scope link 
    ...

Prüfen Sie IPv6 auf beiden Rechnern und ob sie kommunizieren können

Auf beiden Rechnern können wir laufen:

ping6 ::1

Ergebnis:

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

Auf dem Entwicklungsrechner pingen wir den virtuellen Rechner an:

ping6 2001:db8:abcd:12::1:1

Auf der virtuellen Maschine pingen wir die Entwicklungsmaschine an:

ping6 2001:db8:abcd:12::1

Schließlich prüfen wir, ob wir einen Dienst auf der virtuellen Maschine ausführen können und ob wir auf diesen Dienst zugreifen können.

Auf dem virtuellen Rechner starten wir 'netcat' und binden ihn an die IPv6-Adresse:

nc -l 2001:db8:abcd:12::1:1 3492

Auf dem Entwicklungsrechner starten wir 'telnet', geben 'hello' ein und prüfen, ob es ein Echo gibt:

telnet -6 2001:db8:abcd:12::1:1 3492

Ergebnis:

Trying 2001:db8:abcd:12::1:1...
Connected to 2001:db8:abcd:12::1:1.
Escape character is '^]'.
hello
^]
telnet> quit
Connection closed.

Funktioniert, gut.

Installation von Microk8s mit einem Dual-Stack

Dies erwies sich als viel einfacher als erwartet. Ich folgte den Anweisungen aus dem Beitrag 'How to configure network Dual-stack', siehe Links unten.

Auf dem Entwicklungsrechner erstellen wir zunächst eine Datei:

/var/snap/microk8s/common/.microk8s.yaml

mit dem folgenden Inhalt:

---
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

Hinweis(e):

  • Hier aktivieren wir 'dns'. Wenn Sie dies hier nicht tun, dann müssen Sie dies nach der Installation von Microk8s tun!
  • Hier weisen wir Unique Local Addresses (ULA) zu, sie können nicht über das öffentliche Internet geroutet werden.

Dann installieren wir Microk8s:

snap install microk8s --classic

Prüfen Sie, ob die Pods eine IPv4- und eine IPv6-Adresse zugewiesen bekommen, z. B. durch Ausführen:

microk8s kubectl -n kube-system describe pod

Dort sollte für jeden Pod etwas Ähnliches angezeigt werden:

...
IPs:
  IP:           10.3.105.121
  IP:           fd02::332e:7684:ac2:6979
...

Jetzt starten wir BusyBox in Microk8s:

kubectl run -i -t busybox --image=busybox --restart=Never

Sobald sie läuft, können wir überprüfen, ob eine IPv6-Adresse zugewiesen wurde:

cat /etc/hosts

Ergebnis:

# 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-Tests mit Microk8s

Starten Sie auf dem Entwicklungsrechner einen 'netcat' -Listener:

nc -l 2001:db8:abcd:12::1 3491

Dann versuchen wir im BusyBox-Terminal, eine Verbindung herzustellen, und geben eine Nachricht ein:

telnet -6 2001:db8:abcd:12::1 3491

Ergebnis:

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

Starten Sie nun den 'netcat' -Listener auf der virtuellen Maschine:

nc -l 2001:db8:abcd:12::1:1 3492

In BusyBox auf dem Entwicklungsrechner versuchen wir erneut, eine Verbindung herzustellen:

telnet 2001:db8:abcd:12::1:1 3492

Es wird keine Verbindung hergestellt! Dies war zu erwarten. Ausgehender IPv6-Verkehr wird blockiert.

Aus dem Beitrag 'Enabling IPv6 for SC4SNMP', siehe Links unten: Der für microk8s verwendete Standard-CNI ist Calico. Damit Pods das Internet über IPv6 erreichen können, müssen Sie den Parameter natOutgoing in der ipv6 ip pool configuration von Calico aktivieren. Um ihn zu setzen, erstellen Sie die yaml-Datei mit dem folgenden Inhalt:

# calico-ippool.yaml
---
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  name: default-ipv6-ippool
spec:
  natOutgoing: true

Zum Aktivieren:

microk8s kubectl apply -f calico-ippool.yaml

Stoppen und starten Sie Microk8s:

microk8s stop
microk8s start

Entfernen Sie nun den BusyBox-Pod und starten Sie ihn neu:

kubectl delete pod  busybox
kubectl run -i -t busybox --image=busybox --restart=Never

Wiederum in BusyBox auf dem Entwicklungsrechner versuchen wir, uns mit dem Lister in der virtuellen Maschine zu verbinden und eine Nachricht einzugeben:

telnet 2001:db8:abcd:12::1:1 3492

Ergebnis:

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

Großartig, jetzt funktioniert es!

Mehr über Calico und IP-Pools

Calico (Project Calico Documentation) ist eine open source Netzwerk- und Netzwerksicherheitslösung für Container, virtuelle Maschinen und native hostbasierte Workloads.

Ab 'Microk8s - Configure Calico', siehe Links unten: In den meisten Fällen [] besteht die Möglichkeit, die Calico-Konfiguration zu ändern, darin, die bereitgestellte cni.yaml zu patchen und sie dann erneut auf den Cluster anzuwenden.

So überprüfen Sie die Calico-Api-Ressourcen:

kubectl api-resources | grep 'projectcalico.org'

Ergebnis:

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

So erhalten Sie die IP-Pools:

kubectl get ippools

Ergebnis:

NAME                  AGE
default-ipv4-ippool   11d
default-ipv6-ippool   11d

So beschreiben Sie die IP-Pools:

kubectl describe IPPool

Ergebnis:

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:           

Beachten Sie, dass "Nat Outgoing" sowohl für das "default-ipv4-ippool" als auch für das "default-ipv6-ippool" "true" ist.

Wir können auch calicoctl verwenden. Aber zuerst müssen wir es installieren.

Um die aktuelle Version von Calico zu erhalten, installieren Sie in Microk8s:

kubectl -n kube-system describe pod calico-kube-controllers-759cd8b574-wscp9 | grep Image

Ergebnis:

    Image:          docker.io/calico/kube-controllers:v3.25.1
    Image ID:       docker.io/calico/kube-controllers@sha256:02c1232ee4b8c5a145c401ac1adb34a63ee7fc46b70b6ad0a4e068a774f25f8a

Dies bedeutet, dass die aktuelle Version von Calico ist:

v3.25.1

Um das calicoctl-Manifest zu erhalten:

wget https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/calicoctl.yaml

Zum Aktivieren:

kubectl apply -f calicoctl.yaml

Um zu überprüfen, ob es läuft:

kubectl get pods -A

Resultat:

NAMESPACE     NAME                                       READY   STATUS    RESTARTS        AGE
...
kube-system   calicoctl                                  1/1     Running   0               2m17s
...

Um die Calico-Profile zu erhalten:

kubectl exec -ti -n kube-system calicoctl  -- /calicoctl get profiles -o wide

Ergebnis:

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     
...

Um einen calicoctl-Alias zu erstellen:

alias calicoctl="kubectl exec -i -n kube-system calicoctl -- /calicoctl"

Jetzt können wir den obigen Befehl wie folgt ausführen:

calicoctl get profiles -o wide

Wir können calicoctl auch verwenden, um die IP-Pools zu erhalten:

calicoctl get ippools

Ergebnis:

NAME                  CIDR          SELECTOR   
default-ipv4-ippool   10.3.0.0/16   all()      
default-ipv6-ippool   fd02::/64     all()      

Um mehr anzuzeigen:

calicoctl get IPPool default-ipv6-ippool -o wide

Ergebnis:

NAME                  CIDR        NAT    IPIPMODE   VXLANMODE   DISABLED   DISABLEBGPEXPORT   SELECTOR   
default-ipv6-ippool   fd02::/64   true   Never      Always      false      false              all()      

Wir können einen IP-Pool löschen und erstellen:

calicoctl delete ippool <ippool-to-delete>

cat <<EOF | calicoctl create -f -
- apiVersion: v1
  kind: ipPool
  metadata:
          cidr: fd0e:c226:9228:fd1a::/64
  spec: {}
EOF

Oder einen bestehenden IP-Pool ersetzen. Beispiel:

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

Zusammenfassung

Wir haben eine IPv6-Testumgebung für Microk8s -Anwendungen erstellt, die auf externe IPv6-Dienste zugreifen müssen. Mit VirtualBox haben wir eine virtuelle Ubuntu -Server-Maschine erstellt und IPv6 sowohl auf der Entwicklungsmaschine als auch auf der virtuellen Maschine aktiviert. Dann haben wir Dual-Stack Microk8s auf dem Entwicklungsrechner installiert und den ausgehenden IPv6-Verkehr aktiviert. Jetzt können wir 'telnet' innerhalb von Microk8s auf dem Entwicklungsrechner mit einem IPv6-Dienst verbinden, der auf dem virtuellen Rechner läuft.

Links / Impressum

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

Einen Kommentar hinterlassen

Kommentieren Sie anonym oder melden Sie sich zum Kommentieren an.

Kommentare

Eine Antwort hinterlassen

Antworten Sie anonym oder melden Sie sich an, um zu antworten.