Заўв. перав.: гэты артыкул, напісаны SRE-інжынерам з LinkedIn, у дэталях распавядае пра тую «ўнутраную магію» ў Kubernetes — дакладней, узаемадзеянне CRI, CNI і kube-apiserver, — што адбываецца, калі чарговаму pod'у патрабуецца прызначыць IP-адрас.
Адно з базавых патрабаванняў сеткавай мадэлі Kubernetes складаецца ў тым, што ў кожнага pod'а павінен быць свой уласны IP-адрас і любы іншы pod у кластары павінен мець магчымасць звязацца з ім па гэтым адрасе. Ёсць мноства сеткавых "правайдэраў" (Flannel, Calico, Canal і да т.п.), якія дапамагаюць рэалізаваць дадзеную сеткавую мадэль.
Калі я толькі пачынаў працаваць з Kubernetes, мне было не зусім ясна, як менавіта pod'ы атрымліваюць свае IP-адрасы. Нават з разуменнем, як функцыянуюць асобныя кампаненты, было складана ўявіць іх сумесную працу. Напрыклад, я ведаў, для чаго патрэбныя плагіны CNI, але не ўяўляў, як менавіта яны выклікаюцца. Таму вырашыў напісаць гэты артыкул, каб падзяліцца ведамі аб розных сеткавых кампанентах і іх сумеснай працы ў кластары Kubernetes, якія і дазваляюць кожнаму pod'у атрымаць свой унікальны IP-адрас.
Існуюць розныя спосабы арганізацыі сеткавага ўзаемадзеяння ў Kubernetes – аналагічна таму, як і розныя варыянты выкананых асяроддзяў (runtime) для кантэйнераў. У гэтай публікацыі будзе выкарыстоўвацца фланель для арганізацыі сеткі ў кластары, а ў якасці выкананага асяроддзя - Кантэйнер. Таксама я зыходжу са здагадкі, што вы ведаеце, як уладкована сеткавае ўзаемадзеянне паміж кантэйнерамі, таму толькі сцісла закрану яго, выключна для кантэксту.
Некаторыя базавыя паняцці
Кантэйнеры і сетка: кароткі агляд
У інтэрнэце дастаткова выдатных публікацый, якія тлумачаць, як кантэйнеры звязваюцца адзін з адным па сетцы. Таму правяду толькі агульны агляд асноўных паняццяў і абмяжуюся адным падыходам, які разумее стварэнне Linux-моста і інкапсуляцыю пакетаў. Падрабязнасці апушчаны, паколькі сама тэма сеткавага ўзаемадзеяння кантэйнераў заслугоўвае асобнага артыкула. Спасылкі на некаторыя асабліва змястоўныя і пазнавальныя публікацыі будуць прыведзены ніжэй.
Кантэйнеры на адным хасце
Адзін з спосабаў арганізацыі сувязі па IP-адрасам паміж кантэйнерамі, якія працуюць на адным і тым жа хасце, мяркуе стварэнне Linux-моста. Для гэтага ў Kubernetes (і Docker) ствараюцца віртуальныя прылады veth (virtual ethernet). Адзін канец veth-прылады падлучаецца да сеткавай прасторы імёнаў кантэйнера, іншы - да Linux-мосту у сетцы хаста.
Ва ўсіх кантэйнераў на адным хасце адзін з канцоў veth падлучаны да маста, праз які яны могуць злучацца сябар з сябрам па IP-адрасам. У Linux-моста таксама маецца IP-адрас, і ён выступае ў якасці шлюза для выходнага (egress) трафіку з pod'ов, прызначанага для іншых вузлоў.
Кантэйнеры на розных хастах
Інкапсуляцыя пакетаў - адзін са спосабаў, які дазваляе кантэйнерам на розных вузлах звязвацца адзін з адным па IP-адрасах. Ва Flannel за гэтую магчымасць адказвае тэхналогія vxlan, якая "упакоўвае" зыходны пакет у пакет UDP і затым адпраўляе яго па прызначэнні.
У кластары Kubernetes Flannel стварае прыладу vxlan і якая адпавядае выявай дапаўняе табліцу маршрутаў на кожным з вузлоў. Кожны пакет, прызначаны для кантэйнера на іншым хасце, праходзіць праз прыладу vxlan і інкапсулюецца ў пакет UDP. У пункце прызначэння ўкладзены пакет здабываецца і перанакіроўваецца на патрэбны pod.
Заўвага: Гэта толькі адзін са спосабаў арганізацыі сеткавага ўзаемадзеяння паміж кантэйнерамі.
Што такое CRI?
CRI (Container Runtime Interface) - Гэта ўбудова, які дазваляе kubelet'у выкарыстоўваць розныя выкананыя асяроддзі кантэйнераў. API CRI убудаваны ў розныя выкананыя асяроддзі, таму карыстачы могуць выбіраць runtime па сваім меркаванні.
Што такое CNI?
Праект CNI ўяўляе сабой спецыфікацыю для арганізацыі ўніверсальнага сеткавага рашэння для Linux-кантэйнераў. Акрамя таго, ён уключае ў сябе убудовы, якія адказваюць за розныя функцыі пры наладзе сеткі pod'а. Убудова CNI - гэта выкананы файл, якія адпавядаюць спецыфікацыі (некаторыя плагіны мы абмяркуем ніжэй).
Вылучэнне падсетак вузлам для прызначэння IP-адрасоў pod'ам
Паколькі кожны pod кластара павінен мець IP-адрас, важна пераканацца ў тым, каб гэты адрас быў унікальным. Гэта дасягаецца шляхам вылучэння кожнаму вузлу ўнікальнай падсеткі, з якой затым pod'ам на гэтым вузле прызначаюцца IP-адрасы.
Кантролер IPAM вузла
Калі nodeipam перадаецца ў якасці параметра сцяга --controllerskube-controller-manager'а, ён кожнаму вузлу вылучае асобную падсетку (podCIDR) з CIDR кластара (г.зн. дыяпазону IP-адрасоў для сеткі кластара). Паколькі гэтыя podCIDR'ы не перасякаюцца, становіцца магчымым кожнаму pod'у вылучыць унікальны IP-адрас.
Вузлу Kubernetes прысвойваецца podCIDR у момант яго пачатковай рэгістрацыі ў кластары. Каб змяніць podCIDR у вузлоў, неабходна іх дэрэгістраваць і затым паўторна зарэгістраваць, у прамежку занясучы адпаведныя змены ў канфігурацыю кіраўніка пласта Kubernetes. Вывесці podCIDR вузла можна з дапамогай наступнай каманды:
$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, серада запуску кантэйнера і плагіны CNI: як гэта ўсё працуе
Планаванне pod'а на вузел злучана з выкананнем мноства падрыхтоўчых дзеянняў. У гэтым раздзеле я сканцэнтруюся толькі на тых з іх, якія непасрэдна злучаны з наладай сеткі pod'а.
Планаванне pod'а на нейкі вузел запускае наступны ланцужок падзей:
Узаемадзеянне асяроддзя запуску кантэйнераў і плагінаў 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] в файле канфігурацыі containerd.
Паколькі мы выкарыстоўваем Flannel у якасці сеткавага правайдэра, давайце крыху пагаворым аб яго наладзе:
Flanneld (дэман Flannel'а) звычайна усталёўваецца ў кластар як DaemonSet з install-cni у якасці init-кантэйнера.
Install-cni стварае файл канфігурацыі CNI (/etc/cni/net.d/10-flannel.conflist) на кожным вузле.
Flanneld стварае прыладу vxlan, здабывае сеткавыя метададзеныя з API-сервера і сочыць за абнаўленнямі pod'аў. Па меры іх стварэння ён распаўсюджвае маршруты для ўсіх pod'аў па ўсім кластары.
Гэтыя маршруты і дазваляюць pod'ам звязвацца сябар з сябрам па IP-адрасам.
Для атрымання больш падрабязнай інфармацыі аб рабоце Flannel рэкамендую скарыстацца спасылкамі ў канцы артыкула.
Вось схема ўзаемадзеяння паміж убудовай Containerd CRI і ўбудовамі CNI:
Як відаць вышэй, kubelet выклікае плягін Containerd CRI, каб стварыць pod, а той ужо выклікае плягін CNI для налады сеткі pod'а. Пры гэтым CNI-убудова сеткавага правайдэра выклікае іншыя базавыя убудовы CNI для налады розных аспектаў сеткі.
Узаемадзеянне паміж CNI-плагінамі
Існуюць розныя плагіны CNI, задача якіх - дапамагчы наладзіць сеткавае ўзаемадзеянне паміж кантэйнерамі на хасце. У гэтым артыкуле размова пойдзе пра тры з іх.
CNI-плягін Flannel
Пры выкарыстанні Flannel у якасці сеткавага правайдэра кампанент Containerd CRI выклікае CNI-плягін Flannel, выкарыстоўваючы канфігурацыйны файл CNI /etc/cni/net.d/10-flannel.conflist.
CNI-плягін Flannel працуе сумесна з Flanneld. Падчас запуску Flanneld здабывае podCIDR і іншыя злучаныя з сеткай падрабязнасці з API-сервера і захоўвае іх у файл /run/flannel/subnet.env.
Пры першым выкліку ён стварае Linux-мост з «name»: «cni0», Што паказваецца ў канфігу. Затым для кожнага pod'а ствараецца пара veth. Адзін яе канец падлучаецца да сеткавай прасторы імёнаў кантэйнера, іншы ўваходзіць у Linux-мост у сеткі хаста. CNI-плягін Bridge падлучае ўсе кантэйнеры хаста да Linux-мосту ў сетцы хаста.
Скончыўшы з наладай пары veth, убудова Bridge выклікае лакальны для хаста (host-local) CNI-убудова IPAM. Тып IPAM-плагіна можна наладзіць у канфігу CNI, які плягін CRI выкарыстоўвае для выкліку CNI-плагіна Flannel.
Host-local IPAM-плягін (IPAдрас Management - кіраванне IP-адрасамі) вяртае IP-адрас для кантэйнера з падсеткі і захоўвае выдзелены IP на хасце ў дырэкторыі, указанай у раздзеле dataDir - /var/lib/cni/networks/<network-name=cni0>/<ip>. У гэтым файле ўтрымоўваецца ID кантэйнера, якому прысвоены дадзены IP-адрас.
Пры выкліку host-local IPAM-плагіна ён вяртае наступныя дадзеныя:
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 ці па адрасе [электронная пошта абаронена]. Не саромейцеся звяртацца, калі захочаце абмеркаваць аспекты гэтага артыкула ці што-небудзь іншае. Я з задавальненнем пагутару з вамі!