Kako pod v Kubernetesu pridobi IP-naslov

Op. prev.: ta članek, ki ga je napisal SRE inženir iz LinkedIn, podrobno opisuje to "notranjo magijo" v Kubernetesu — natančneje, interakcijo CRI, CNI in kube-apiserverja — kar se zgodi, ko novemu podu potrebuje dodelitev IP-naslova.

Eden osnovnih zahtev omrežnega modela Kubernetes je, da ima vsak pod svoj lastni IP-naslov ter da se lahko vsak drug pod v klasterju poveže z njim preko tega naslova. Obstaja številni mrežni "ponudniki" (Flannel, Calico, Canal itd.), ki pomagajo uresničiti ta omrežni model.

Ko sem začel delati z Kubernetesom, mi ni bilo povsem jasno, kako točno podi pridobijo svoje IP-naslove. Tudi z razumevanjem delovanja posameznih komponent je bilo težko predstavljati njihovo skupno delovanje. Na primer, vedel sem, za kaj so potrebni CNI vtičniki, a si nisem predstavljal, kako točno se kličejo. Zato sem se odločil napisati ta članek, da delim znanje o različnih omrežnih komponentah in njihovem skupnem delovanju v Kubernetes klasterju, ki omogoča vsakemu podu, da pridobi svoj edinstveni IP-naslov.

Obstajajo različni načini organizacije omrežnega delovanja v Kubernetesu — podobno kot obstajajo različne možnosti izvajalnih okolij (runtime) za kontejnerje. V tej objavi bo uporabljen Flannel za organizacijo omrežja v klasterju, kot izvajalno okolje pa Containerd. Prav tako izhajam iz predpostavke, da veste, kako deluje omrežno delovanje med kontejnerji, zato bom le na kratko obravnaval to temo, zgolj za kontekst.

Nekaj osnovnih pojmov

Kontejnerji in omrežje: kratek pregled

Na internetu je dovolj odličnih objav, ki razlagajo, kako se kontejnerji med seboj povezujejo preko omrežja. Zato bom izvedel le splošen pregled osnovnih pojmov in se omejil na en pristop, ki predvideva ustvarjanje Linux mostu in enkapsulacijo paketov. Podrobnosti so izpuščene, saj je sama tema omrežnega delovanja kontejnerjev vredna posebne objave. Povezave do nekaterih še posebej vsebinsko bogatih in poučnih objav bodo navedene spodaj.

Kontejnerji na enem gostitelju

Ena od možnosti organizacije povezave prek IP naslovov med kontejnerji, ki delujejo na istem gostitelju, vključuje ustvarjanje Linux mostu. Za to v Kubernetes (in Docker) ustvarimo virtualne naprave veth (virtual ethernet). En konec veth naprave je povezan z omrežnim imenskim prostorom kontejnerja, drugi pa z Linux mostom v omrežju gostitelja.

Vsi kontejnerji na istem gostitelju imajo en konec veth povezan z mostom, prek katerega lahko komunicirajo med seboj prek IP naslovov. Linux most ima tudi IP naslov in deluje kot prehod za odhodne (egress) podatkovne tokove iz podov, namenjene drugim vozliščem.

Kako pod v Kubernetesu pridobi IP-naslov

Kontejnerji na različnih gostiteljih

Inkapitulacija paketov je ena od možnosti, ki omogoča kontejnerjem na različnih vozliščih komuniciranje med seboj prek IP naslovov. V Flannel za to možnost skrbi tehnologija vxlan, ki "zapakira" izvorni paket v UDP paket in ga nato pošlje na cilj.

V Kubernetes grozdu Flannel ustvari vxlan napravo in ustrezno dopolnjuje tabelo usmerjanja na vsakem od vozlišč. Vsak paket, namenjen kontejnerju na drugem gostitelju, prehaja skozi vxlan napravo in je inkapsuliran v UDP paket. Na cilju se vgrajen paket izvleče in preusmeri na ustrezen pod.

Kako pod v Kubernetesu pridobi IP-naslov
Opomba: To je le ena od možnosti organizacije omrežne komunikacije med kontejnerji.

Kaj je CRI?

CRI (Container Runtime Interface) je vtičnik, ki omogoča kubeletu uporabo različnih izvršilnih okolij kontejnerjev. API CRI je vgrajen v različna izvršilna okolja, zato lahko uporabniki izberejo runtime po svoji želji.

Kaj je CNI?

Projekt CNI predstavlja specifikacijo za organizacijo univerzalne omrežne rešitve za Linux kontejnerje. Poleg tega vključuje vtičnike, ki so odgovorni za različne funkcionalnosti pri nastavitvi omrežja pod-a. CNI vtičnik je izvršljiva datoteka, ki ustreza specifikaciji (nekateri vtičniki bodo obravnavani spodaj).

Dodelitev podom IP naslovov s podmrežami vozlišč

Ker mora imeti vsak pod v grozdu IP naslov, je pomembno zagotoviti, da je ta naslov edinstven. To se doseže z dodelitvijo vsaki vozlišči edinstvene podmreže, iz katere nato podom na tem vozlišču dodelijo IP naslove.

Kontroler IPAM vozlišča

Ko nodeipam предоставляется в качестве параметра флага --controllers kube-controller-manager'а, он каждому узлу выделяет отдельную подсеть (podCIDR) из CIDR кластера (т.е. диапазона IP-адресов для сети кластера). Поскольку эти podCIDR'ы не пересекаются, становится возможным каждому pod'у выделить уникальный IP-адрес.

Узлу Kubernetes присваивается podCIDR в момент его начальной регистрации в кластере. Чтобы изменить podCIDR у узлов, необходимо их дерегистрировать и затем повторно зарегистрировать, в промежутке внеся соответствующие изменения в конфигурацию управляющего слоя Kubernetes. Вывести podCIDR узла можно с помощью следующей команды:

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

Kubelet, среда запуска контейнера и плагины CNI: как это все работает

Планирование pod'а на узел связано с выполнением множества подготовительных действий. В этом разделе я сконцентрируюсь только на тех из них, которые непосредственно связаны с настройкой сети pod'а.

Планирование pod'а на некий узел запускает следующую цепочку событий:

Kako pod v Kubernetesu pridobi IP-naslov

Справка: Архитектура CRI-плагинов Containerd.

Взаимодействие среды запуска контейнеров и плагинов CNI

У каждого сетевого провайдера имеется свой плагин CNI. Runtime контейнера запускает его, чтобы сконфигурировать сеть для pod'a в процессе его запуска. В случае containerd запуском CNI-плагина занимается плагин Containerd CRI.

При этом у каждого провайдера есть свой агент. Он устанавливается во все узлы Kubernetes и отвечает за сетевую настройку pod'ов. Этот агент идет либо в комплекте с конфигом CNI, либо самостоятельно создает его на узле. Конфиг помогает CRI-плагину установить, какой плагин CNI вызывать.

Местонахождение конфига CNI можно настроить; по умолчанию он лежит в /etc/cni/net.d/<config-file>. Администраторы кластера также отвечают за установку плагинов CNI на каждый узел кластера. Их местонахождение также настраивается; директория по умолчанию — /opt/cni/bin.

При использовании containerd пути для конфига и бинарников плагина можно задать в разделе [plugins."io.containerd.grpc.v1.cri".cni] u файле конфигурации containerd.

Поскольку мы используем Flannel в качестве сетевого провайдера, давайте немного поговорим о его настройке:

  • Flanneld (демон Flannel'а) обычно устанавливается в кластер как DaemonSet с install-cni в качестве init-контейнера.
  • Install-cni создает файл конфигурации CNI (/etc/cni/net.d/10-flannel.conflist) на каждом узле.
  • Flanneld ustvari vxlan napravo, pridobiva omrežne metapodatke z API strežnika in spremlja posodobitve podov. Ko se ti ustvarjajo, širi poti za vse pode po celem klastru.
  • Te poti omogočajo podom, da se med seboj povezujejo po IP naslovih.

Za podrobnejše informacije o delovanju Flannel priporočam, da si ogledate povezave na koncu članka.

Tukaj je shema interakcije med vtičnikom Containerd CRI in vtičniki CNI:

Kako pod v Kubernetesu pridobi IP-naslov

Kot je razvidno zgoraj, kubelet pokliče vtičnik Containerd CRI, da ustvari pod, ta pa nato pokliče vtičnik CNI za nastavitev omrežja poda. Pri tem vtičnik omrežnega ponudnika CNI pokliče druge osnovne vtičnike CNI za nastavitev različnih vidikov omrežja.

Interakcija med CNI vtičniki

Obstajajo različni vtičniki CNI, katerih naloga je pomagati pri nastavitvi omrežne interakcije med kontejnerji na gostitelju. V tem članku bomo govorili o treh od njih.

CNI vtičnik Flannel

Pri uporabi Flannela kot omrežnega ponudnika, komponenta Containerd CRI pokliče CNI vtičnik Flannel, pri čemer uporablja konfiguracijsko datoteko 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
      }
    }
  ]
}

CNI vtičnik Flannel deluje skupaj s Flanned. Med zagonom Flanned pridobi podCIDR in druge s omrežjem povezane podrobnosti iz API strežnika in jih shranjuje v datoteko /run/flannel/subnet.env.

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

CNI vtičnik Flannel uporablja podatke iz /run/flannel/subnet.env za nastavitev in klicanje CNI vtičnika mosta (bridge).

CNI vtičnik Bridge

Ta vtičnik se kliče s sledečo konfiguracijo:

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

Ob prvem klicu ustvari Linux most z "name": "cni0", kar je določeno v konfiguraciji. Nato se za vsak pod ustvari par veth. Ena konec se priključi na omrežni prostor imen kontejnerja, drugi del pa vstopi v Linux most v omrežju gostitelja. CNI vtičnik Bridge povezuje vse kontejnerje gostitelja z Linux mostom v omrežju gostitelja.

Ko konča z nastavitvijo para veth, vtičnik Bridge pokliče lokalni za gostitelja (host-local) CNI vtičnik IPAM. Vrsta IPAM vtičnika se lahko nastavi v konfiguraciji CNI, ki jo vtičnik CRI uporablja za klicanje CNI vtičnika Flannel.

Lokalni IPAM vtičniki CNI

Bridge CNI pokliče lokalni IPAM vtičnik CNI s sledečo konfiguracijo:

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

IPAM-плагин на базе хоста (IP Aадрес Управление — управление IP-адресами) возвращает IP-адрес для контейнера из подсети и сохраняет выделенный IP на хосте в директории, указанной в разделе dataDir — /var/lib/cni/networks/<network-name=cni0>/<ip>. В этом файле содержится ID контейнера, которому присвоен данный IP-адрес.

При вызове IPAM-плагина на базе хоста он возвращает следующие данные:

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

Резюме

Kube-controller-manager каждому узлу присваивает podCIDR. Pod’ы каждого узла получают IP-адреса из пространства адресов в выделенном диапазоне podCIDR. Поскольку podCIDR’ы узлов не пересекаются, все pod’ы получают уникальные IP-адреса.

Администратор кластера Kubernetes настраивает и устанавливает kubelet, среду запуска контейнеров, агента сетевого провайдера и копирует плагины CNI на каждый узел. Во время старта агент сетевого провайдера генерирует конфиг CNI. Когда pod планируется на узел, kubelet вызывает CRI-плагин для его создания. Далее, если используется containerd, плагин Containerd CRI вызывает CNI-плагин, указанный в конфиге CNI, для настройки сети pod’а. В результате pod получает IP-адрес.

Мне потребовалось некоторое время, чтобы разобраться во всех тонкостях и нюансах всех этих взаимодействий. Надеюсь, полученный опыт поможет и вам лучше понять, как работает Kubernetes. Если я в чем-то ошибаюсь, пожалуйста, свяжитесь со мной в Twitter или по адресу hello@ronaknathani.com. Не стесняйтесь обращаться, если захотите обсудить аспекты этой статьи или что-нибудь другое. Я с удовольствием пообщаюсь с вами!

Povezave

Контейнеры и сеть

Как работает Flannel

CRI и CNI

P.S. od prevajalca

Preberite tudi na našem blogu:

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster