Прим. прев.: тази статия, написана от SRE инженер в LinkedIn, детайлно описва онези „вътрешни магии“ в Kubernetes — по-точно, взаимодействието между CRI, CNI и kube-apiserver, — което се случва, когато на даден pod му е нужен IP адрес.
Едно от основните изисквания е, че всеки pod трябва да има собствен IP адрес и всеки друг pod в кластера трябва да може да се свърже с него по този адрес. Съществуват много мрежови „доставчици“ (Flannel, Calico, Canal и т.н.), които помагат за изпълнението на тази мрежова модел.
Когато току-що започвах да работя с Kubernetes, не ми беше съвсем ясно как подовете получават своите IP адреси. Дори след като разбрах как функционират отделните компоненти, беше трудно да си представя тяхното съвместно действие. Например, знаех за какво служат CNI плъгините, но не знаех как точно се извикват. Затова реших да напиша тази статия, за да споделя знанията си за различните мрежови компоненти и тяхната съвместна работа в кластера на Kubernetes, които позволяват на всеки pod да получи уникален IP адрес.
Съществуват различни начини за организиране на мрежовото взаимодействие в Kubernetes — подобно на различните варианти на изпълнителни среди (runtime) за контейнери. В това публикуване ще се използва за организиране на мрежата в кластера, а като изпълнителна среда — . Също така предполагам, че знаете как функционира мрежовото взаимодействие между контейнерите, затова ще засегна темата само накратко, единствено за контекст.
Някои основни понятия
Контейнери и мрежа: кратък обзор
В интернет има много отлични статии, които обясняват как контейнерите се свързват помежду си по мрежата. Затова ще направя само общ преглед на основните понятия и ще се огранича до един подход, свързан със създаването на Linux мост и инкапсулацията на пакети. Подробностите са опуснати, тъй като самата тема за мрежовото взаимодействие на контейнерите заслужава отделна статия. По-долу ще бъдат предоставени връзки към някои особено съдържателни и познавателни публикации.
Контейнери на един хост
Един от начините за организиране на свързаност по IP адреси между контейнери, работещи на един и същи хост, предвижда създаването на Linux мост. За целта в Kubernetes (и Docker) се създават виртуални устройства . Единият край на veth устройството е свързан към мрежовото пространство на името на контейнера, а другият — към в мрежата на хоста.
Всички контейнери на един хост имат един от краищата на veth, свързан към моста, чрез който те могат да комуникират помежду си по IP адреси. Linux мостът също има IP адрес и служи като шлюз за изходящия (egress) трафик от pod-овете, предназначен за други възли.

Контейнери на различни хостове
Инкапсулацията на пакети е един от начините, позволяващи на контейнерите на различни възли да комуникират помежду си по IP адреси. В Flannel за тази функция отговаря технологията , която "опакова" оригиналния пакет в UDP пакет и след това го изпраща на адреса.
В кластера Kubernetes Flannel създава устройство vxlan и съответно допълва таблицата за маршрути на всеки от възлите. Всеки пакет, предназначен за контейнер на друг хост, преминава през устройството vxlan и се инкапсулира в UDP пакет. На целта вложеният пакет се извлича и пренасочва към необходимия pod.

Забележка: Това е само един от начините за организиране на мрежовото взаимодействие между контейнерите.
Какво е CRI?
е плъгин, който позволява на kubelet да използва различни изпълними среди на контейнери. API CRI е вграден в различни изпълними среди, така че потребителите могат да избират runtime по собствено усмотрение.
Какво е CNI?
представлява за организиране на универсално мрежово решение за Linux контейнери. Освен това, той включва , отговарящи за различни функции при настройка на мрежата на pod-а. Плъгинът CNI е изпълним файл, който съответства на спецификацията (някои плъгини ще обсъдим по-долу).
Разпределение на подсетите на възлите за назначаване на IP адреси на pod-овете
Тъй като всеки pod в клъстера трябва да има IP адрес, е важно да се уверите, че този адрес е уникален. Това се постига чрез разпределяне на уникална подсетка на всеки възел, от която след това се назначават IP адреси на pod-овете на този възел.
Контролерът IPAM на възела
Когато nodeipam се предава като параметър на флага --controllers , той разпределя индивидуален подмрежов адрес (podCIDR) на всеки възел (т.е. диапазон IP адреси за мрежата на клъстера). Тъй като тези podCIDR не се припокриват, става възможно да се назначи уникален IP адрес на всеки pod.
На възел в Kubernetes се назначава podCIDR по време на първоначалната му регистрация в клъстера. За да промените podCIDR на възлите, е необходимо да ги дерегирате и след това да ги регистрирате отново, като в интервала извършите съответните промени в конфигурацията на управляващия слой на Kubernetes. Можете да извлечете podCIDR на възел с помощта на следната команда:
$ kubectl get no -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, среда за стартиране на контейнери и CNI плъгини: как всичко това работи
Планирането на pod на възел е свързано с изпълнението на множество подготовителни действия. В този раздел ще се съсредоточа само върху тези от тях, които са пряко свързани с конфигурирането на мрежата на pod.
Планирането на pod на определен възел задейства следната верига от събития:

Помощ: .
Взаимодействие между средата за стартиране на контейнери и CNI плъгините
Всеки мрежов доставчик има свой CNI плъгин. Средата за стартиране на контейнера го стартира, за да конфигурира мрежата за pod по време на неговото стартиране. В случай на containerd, стартирането на CNI плъгина се извършва от плъгина .
Всеки доставчик има свой агент. Той се инсталира на всички възли в Kubernetes и отговаря за мрежовата конфигурация на pod. Този агент идва или с конфигурацията на CNI, или самостоятелно я създава на възела. Конфигурацията помага на CRI плъгина да установи кой CNI плъгин да извиква.
Местоположението на CNI конфигурацията може да бъде настроено; по подразбиране тя се намира в /etc/cni/net.d/<config-file>. Администраторите на клъстера също отговарят за инсталирането на CNI плъгините на всеки възел в клъстера. Местоположението им също може да бъде настроено; директорията по подразбиране е /opt/cni/bin.
При използване на containerd пътищата за конфигурацията и бинарниците на плъгина могат да бъдат зададени в секцията [plugins."io.containerd.grpc.v1.cri".cni] в .
Тъй като използваме Flannel като мрежов доставчик, нека поговорим малко за неговата конфигурация:
- Flanneld (демон на Flannel) обикновено се инсталира в клъстера като DaemonSet с
install-cniв качеството на . Install-cniсъздава (/etc/cni/net.d/10-flannel.conflist) на всеки възел.- Flanneld създава vxlan устройство, извлича мрежови метаданни от API сървъра и следи за обновленията на подовете. Със създаването им той разпространява маршрути за всички подове из целия клъстер.
- Тези маршрути позволяват на подовете да се свързват помежду си по IP адреси.
За повече информация относно работата на Flannel, препоръчвам да се запознаете с линковете в края на статията.
Ето схемата на взаимодействие между плъгина Containerd CRI и плъгините CNI:

Както се вижда по-горе, kubelet извиква плъгина Containerd CRI, за да създаде под, а той от своя страна извиква плъгина CNI за настройка на мрежата на пода. В този процес CNI плъгинът на мрежовия доставчик извиква други основни CNI плъгини за настройка на различни аспекти на мрежата.
Взаимодействие между CNI плъгини
Съществуват различни CNI плъгини, чиято задача е да подпомагат настройването на мрежовото взаимодействие между контейнерите на хоста. В тази статия ще говорим за три от тях.
CNI плъгин Flannel
При използването на Flannel като мрежов доставчик, компонентът Containerd CRI извиква , използвайки конфигурационния файл 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 плъгин Flannel работи съвместно с Flanneld. По време на стартиране Flanneld извлича podCIDR и други свързани с мрежата подробности от API сървъра и ги записва в файл /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 плъгин Flannel използва данни от /run/flannel/subnet.env за настройка и извикване на CNI плъгина на моста (bridge).
CNI плъгин Bridge
Този плъгин се извиква с следната конфигурация:
{
"name": "cni0",
"type": "bridge",
"mtu": 1450,
"ipMasq": false,
"isGateway": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24"
}
}
При първото извикване той създава Linux мост с "name": "cni0", който се посочва в конфигурацията. След това за всеки под се създава двойка veth. Единият край се свързва с пространството за мрежа на контейнера, а другият влиза в Linux моста в мрежата на хоста. свързва всички контейнери на хоста към Linux моста в мрежата на хоста.
След приключване с настройката на двойката veth, плъгинът Bridge извиква локалния за хоста (host-local) CNI плъгин IPAM. Типът на IPAM плъгина може да бъде настроен в конфигурацията CNI, която плъгинът CRI използва за извикване на CNI плъгина Flannel.
Локалните за хоста IPAM плъгини CNI
Bridge CNI извиква с следната конфигурация:
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
IPAM плъгин на хост-локал (IP Aадрес Mуправление — управление 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. Ако греша в нещо, пожалуйста, свържете се с мен на или на адрес . Не се колебайте да се свържете, ако искате да обсъдим аспектите на тази статия или нещо друго. Ще се радвам да поговоря с вас!
Връзки
Контейнери и мрежа
Как работи Flannel
CRI и CNI
P.S. от преводача
Прочетете също в нашия блог:
- «»;
- «Илюстрировано ръководство за структурата на мрежата в Kubernetes»: , ;
- «».
Източник: habr.com
