Jak pod w Kubernetes otrzymuje adres IP

Przyp. tłum.: Ten artykuł, napisany przez inżyniera SRE z LinkedIn, szczegółowo opisuje „wewnętrzną magię” w Kubernetes — dokładniej, interakcję CRI, CNI i kube-apiserver — co się dzieje, gdy pod potrzebuje przydzielenia adresu IP.

Jednym z podstawowych wymagań modelu sieciowego Kubernetes jest to, że każdy pod musi mieć swój własny adres IP, a każdy inny pod w klastrze powinien móc się z nim skontaktować pod tym adresem. Istnieje wiele „dostawców sieciowych” (Flannel, Calico, Canal itp.), którzy pomagają zrealizować ten model sieciowy.

Kiedy zaczynałem pracować z Kubernetes, nie do końca rozumiałem, jak dokładnie pod'y otrzymują swoje adresy IP. Nawet zrozumienie, jak działają poszczególne komponenty, utrudniało wyobrażenie sobie ich wspólnej pracy. Na przykład wiedziałem, do czego służą wtyczki CNI, ale nie rozumiałem, jak dokładnie są wywoływane. Postanowiłem więc napisać ten artykuł, aby podzielić się wiedzą na temat różnych komponentów sieciowych i ich współdziałania w klastrze Kubernetes, które umożliwiają każdemu pod'owi uzyskanie unikalnego adresu IP.

Istnieją różne sposoby organizacji interakcji sieciowej w Kubernetes — podobnie jak różne opcje środowisk uruchomieniowych (runtime) dla kontenerów. W tej publikacji będziemy korzystać z Flannel do organizacji sieci w klastrze, a jako środowisko uruchomieniowe — Containerd. Zakładam również, że wiesz, jak działa interakcja sieciowa między kontenerami, dlatego tylko krótko to omówię, jedynie w celu kontekstu.

Kilka podstawowych pojęć

Kontenery i sieć: krótki przegląd

W Internecie jest wiele doskonałych publikacji wyjaśniających, jak kontenery łączą się ze sobą w sieci. Dlatego przeprowadzę tylko ogólny przegląd podstawowych pojęć i ograniczę się do jednego podejścia, które polega na stworzeniu mostu Linux i enkapsulacji pakietów. Szczegóły pominięto, ponieważ temat interakcji sieciowej kontenerów zasługuje na osobny artykuł. Poniżej zostaną podane linki do niektórych szczególnie treściwych i pouczających publikacji.

Kontenery na jednym hoście

Jednym ze sposobów organizacji komunikacji za pomocą adresów IP między kontenerami działającymi na tym samym hoście jest utworzenie mostu Linux. W tym celu w Kubernetes (i Dockerze) tworzone są wirtualne urządzenia veth (wirtualny ethernet). Jeden koniec urządzenia veth jest podłączony do przestrzeni nazw sieci kontenera, a drugi – do mostu Linux w sieci hosta.

Wszystkie kontenery na jednym hoście mają jeden koniec veth podłączony do mostu, przez który mogą się ze sobą komunikować za pomocą adresów IP. Most Linux ma również adres IP, który pełni rolę bramy dla wychodzącego ruchu (egress) z podów skierowanego do innych węzłów.

Jak pod w Kubernetes otrzymuje adres IP

Kontenery na różnych hostach

Enkapsulacja pakietów to jeden ze sposobów, który pozwala kontenerom na różnych węzłach komunikować się nawzajem za pomocą adresów IP. W Flannel za tę funkcjonalność odpowiada technologia vxlan, która „opakowuje” oryginalny pakiet w pakiet UDP, a następnie wysyła go do celu.

W klastrze Kubernetes Flannel tworzy urządzenie vxlan i odpowiednio uzupełnia tabelę tras na każdym z węzłów. Każdy pakiet przeznaczony dla kontenera na innym hoście przechodzi przez urządzenie vxlan i jest enkapsulowany w pakiet UDP. W miejscu docelowym wewnętrzny pakiet jest wyodrębniany i przekazywany do odpowiedniego poda.

Jak pod w Kubernetes otrzymuje adres IP
Uwaga: To tylko jeden ze sposobów organizacji interakcji sieciowych między kontenerami.

Co to jest CRI?

CRI (Container Runtime Interface) to wtyczka, która umożliwia kubeletowi korzystanie z różnych środowisk wykonawczych kontenerów. Interfejs API CRI jest wbudowany w różne środowiska wykonawcze, dzięki czemu użytkownicy mogą wybierać runtime według własnego uznania.

Co to jest CNI?

Projekt CNI to specyfikację organizacja uniwersalnego rozwiązania sieciowego dla kontenerów Linux. Ponadto obejmuje wtyczki, które odpowiadają za różne funkcje podczas konfiguracji sieci poda. Wtyczka CNI to plik wykonywalny, który odpowiada specyfikacji (niektóre wtyczki omówimy poniżej).

Przydzielanie podsieci węzłom do przypisywania adresów IP podom

Ponieważ każdy pod klastra musi mieć adres IP, ważne jest, aby mieć pewność, że ten adres jest unikalny. Osiąga się to poprzez przydzielenie każdemu węzłowi unikalnej podsieci, z której następnie przypisywane są adresy IP podom na tym węźle.

Kontroler IPAM węzła

Kiedy nodeipam jest przekazywany jako parametr flagi --controllers zarządcy kube-controller-manager, przydziela on każdemu węzłowi osobną podsieć (podCIDR) z CIDR klastra (tzn. zakres adresów IP dla sieci klastra). Ponieważ te podCIDR-y się nie pokrywają, można przydzielić każdemu podowi unikalny adres IP.

Węzeł Kubernetes otrzymuje podCIDR w momencie jego rejestracji w klastrze. Aby zmienić podCIDR węzłów, należy je wyrejestrować, a następnie zarejestrować ponownie, w międzyczasie wprowadzając odpowiednie zmiany w konfiguracji warstwy zarządzającej Kubernetes. PodCIDR węzła można uzyskać za pomocą następującego polecenia:

$ kubectl get no  -o json | jq '.spec.podCIDR'
10.244.0.0/24

Kubelet, środowisko uruchomieniowe kontenera i wtyczki CNI: jak to wszystko działa

Planując pod na węźle, wykonuje się szereg przygotowawczych działań. W tej sekcji skupię się tylko na tych, które bezpośrednio związane są z konfiguracją sieci podu.

Planowanie poda na określonym węźle uruchamia następującą sekwencję wydarzeń:

Jak pod w Kubernetes otrzymuje adres IP

Informacja: Architektura wtyczek CRI Containerd.

Interakcja środowiska uruchomieniowego kontenerów i wtyczek CNI

Każdy dostawca sieci ma swoją własną wtyczkę CNI. Środowisko uruchomieniowe kontenera uruchamia ją, aby skonfigurować sieć dla poda w trakcie jego uruchamiania. W przypadku containerd, uruchamianiem wtyczki CNI zajmuje się wtyczka Containerd CRI.

Każdy dostawca ma swojego agenta. Jest on instalowany na wszystkich węzłach Kubernetes i odpowiada za konfigurację sieci podów. Ten agent występuje albo w zestawie z konfiguracją CNI, albo samodzielnie ją tworzy na węźle. Konfiguracja pomaga wtyczce CRI określić, którą wtyczkę CNI wywołać.

Lokalizację pliku konfiguracyjnego CNI można skonfigurować; domyślnie znajduje się w /etc/cni/net.d/<config-file>. Administratorzy klastra odpowiadają również za instalację wtyczek CNI na każdym węźle klastra. Ich lokalizacja jest również konfigurowalna; domyślny folder to /opt/cni/bin.

Podczas korzystania z containerd ścieżki do pliku konfiguracyjnego i binariów wtyczki można określić w sekcji [plugins."io.containerd.grpc.v1.cri".cni] do pliku konfiguracyjnym containerd.

Ponieważ używamy Flannel jako dostawcy sieci, porozmawiajmy trochę o jego konfiguracji:

  • Flanneld (demon Flannela) zazwyczaj instaluje się w klastrze jako DaemonSet z install-cni jako kontenera init.
  • Install-cni tworzy pliki konfiguracyjnego CNI (/etc/cni/net.d/10-flannel.conflist) na każdym węźle.
  • Flanneld tworzy urządzenie vxlan, pobiera metadane sieciowe z API serwera i monitoruje aktualizacje podów. W miarę ich tworzenia rozprowadza trasy dla wszystkich podów w całym klastrze.
  • Te trasy pozwalają podom komunikować się ze sobą za pomocą adresów IP.

Aby uzyskać więcej informacji na temat działania Flannel, polecam skorzystać z linków na końcu artykułu.

Oto schemat interakcji między pluginem Containerd CRI a pluginami CNI:

Jak pod w Kubernetes otrzymuje adres IP

Jak widać powyżej, kubelet wywołuje plugin Containerd CRI, aby stworzyć pod, a ten potem wywołuje plugin CNI do skonfigurowania sieci podu. Przy tym plugin dostawcy CNI wywołuje inne podstawowe pluginy CNI do skonfigurowania różnych aspektów sieci.

Interakcja między pluginami CNI

Istnieje wiele pluginów CNI, których zadaniem jest pomoc w skonfigurowaniu interakcji sieciowej między kontenerami na hoście. W tym artykule omówię trzy z nich.

Plugin CNI Flannel

Przy użyciu Flannel jako dostawcy sieci komponent Containerd CRI wywołuje Plugin CNI Flannel, używając pliku konfiguracyjnego CNI /etc/cni/net.d/10-flannel.conflist.

$ cat /etc/cni/net.d/10-flannel.conflist
{
  "name": "cni0",
  "plugins": [
    {
      "type": "flannel",
      "delegate": {
         "ipMasq": false,
        "hairpinMode": true,
        "isDefaultGateway": true
      }
    }
  ]
}

Plugin CNI Flannel współpracuje z Flanneld. Podczas uruchamiania Flanneld pobiera podCIDR i inne powiązane szczegóły dotyczące sieci z API serwera i zapisuje je w pliku /run/flannel/subnet.env.

FLANNEL_NETWORK=10.244.0.0/16 
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450 
FLANNEL_IPMASQ=false

Plugin CNI Flannel wykorzystuje dane z /run/flannel/subnet.env do skonfigurowania i wywołania pluginu CNI mostu (bridge).

Plugin CNI Bridge

Ten plugin jest wywoływany z następującą konfiguracją:

{
  "name": "cni0",
  "type": "bridge",
  "mtu": 1450,
  "ipMasq": false,
  "isGateway": true,
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24"
  }
}

Podczas pierwszego wywołania tworzy most Linux z "name": "cni0", co jest podane w konfiguracji. Następnie dla każdego podu tworzona jest para veth. Jeden jej koniec jest podłączany do przestrzeni nazw kontenera, drugi wchodzi do mostu Linux w sieci hosta. Plugin CNI Bridge podłącza wszystkie kontenery hosta do mostu Linux w sieci hosta.

Po zakończeniu konfiguracji pary veth, plugin Bridge wywołuje lokalny plugin IPAM dla hosta (host-local) CNI. Typ pluginu IPAM można skonfigurować w pliku konfiguracyjnym CNI, którego plugin CRI używa do wywołania pluginu CNI Flannel.

Lokalne pluginy IPAM CNI

Plugin CNI Bridge wywołuje lokalny plugin IPAM dla hosta CNI z następującą konfiguracją:

{
  "name": "cni0",
  "ipam": {
    "type": "host-local",
    "subnet": "10.244.0.0/24",
    "dataDir": "/var/lib/cni/networks"
  }
}

Wtyczka IPAM host-local (IP Aadres Mzarządzanie — zarządzanie adresami IP) zwraca adres IP dla kontenera z podsieci i zachowuje przypisany adres IP na hoście w katalogu podanym w sekcji dataDir/var/lib/cni/networks/<network-name=cni0>/<ip>. Ten plik zawiera identyfikator kontenera, któremu przypisano dany adres IP.

Podczas wywoływania wtyczki IPAM host-local zwraca następujące dane:

{
  "ip4": {
    "ip": "10.244.4.2",
    "gateway": "10.244.4.3"
  },
  "dns": {}
}

Podsumowanie

Kube-controller-manager przypisuje każdemu węzłowi podCIDR. Pod’y każdego węzła otrzymują adresy IP z przestrzeni adresowej w przydzielonym zakresie podCIDR. Ponieważ podCIDR’y węzłów się nie pokrywają, wszystkie pod’y otrzymują unikalne adresy IP.

Administrator klastra Kubernetes konfiguruje i instaluje kubelet, środowisko uruchamiania kontenerów, agenta dostawcy sieci oraz kopiuje wtyczki CNI na każdy węzeł. Podczas uruchamiania agent dostawcy sieci generuje konfigurację CNI. Gdy pod jest planowany na węzeł, kubelet wywołuje wtyczkę CRI do jego utworzenia. Następnie, jeśli używane jest containerd, wtyczka CRI Containerd wywołuje wtyczkę CNI określoną w konfiguracji CNI, aby skonfigurować sieć pod’a. W rezultacie pod otrzymuje adres IP.

Zajęło mi trochę czasu, aby zrozumieć wszystkie subtelności i zawirowania tych interakcji. Mam nadzieję, że zdobyte doświadczenie pomoże Ci lepiej zrozumieć, jak działa Kubernetes. Jeśli w czymś się mylę, proszę, skontaktuj się ze mną w Twitter lub pod adresem hello@ronaknathani.com. Nie krępuj się, aby się skontaktować, jeśli chcesz omówić aspekty tego artykułu lub coś innego. Z przyjemnością skontaktuję się z Tobą!

Linki

Kontenery i sieć

Jak działa Flannel

CRI i CNI

P.S. od tłumacza

Przeczytaj także na naszym blogu:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster