
Qëllimi i këtij artikulli është të njohë lexuesin me baza të ndërveprimit rrjetor dhe menaxhimit të politikave rrjetore në Kubernetes, si dhe me pluginin e jashtëm Calico, i cili zgjeron funksionalitetet standarde. Gjatë këtij procesi do të demonstrohen lehtësitë e konfigurimit dhe disa karakteristika me shembuj realë nga përvoja jonë.
Një hyrje e shpejtë në strukturën e rrjetit Kubernetes
Klusteri Kubernetes është i paimagjinueshëm pa një rrjet. Ne tashmë kemi publikuar materiale mbi bazat e tyre: «» dhe «».
Në kontekstin e këtij artikulli është e rëndësishme të theksohet se për lidhshmërinë rrjetore midis konteinerëve dhe nodëve nuk është përgjegjës vetë K8s: për këtë përdoren lloje të ndryshme pluginash CNI (Container Networking Interface). Më shumë rreth kësaj koncepte ne .
PĂ«r shembull, plugin mĂ« i pĂ«rhapur nga ato Ă«shtĂ« â siguron lidhshmĂ«ri tĂ« plotĂ« rrjetore midis tĂ« gjitha nyjeve tĂ« grupit pĂ«rmes ngritjes sĂ« urave nĂ« çdo nyje, duke i caktuar njĂ« nĂ«ndeg. MegjithatĂ«, disponueshmĂ«ria e plotĂ« dhe e paanshme nuk Ă«shtĂ« gjithmonĂ« e dobishme. PĂ«r tĂ« ofruar njĂ« minimum izolimi nĂ« grupe, Ă«shtĂ« e nevojshme tĂ« ndĂ«rhyhet nĂ« konfigurimin e firewall-it. NĂ« pĂ«rgjithĂ«si, kjo Ă«shtĂ« lĂ«nĂ« nĂ«n menaxhimin e atij CNI, gjĂ« qĂ« do tĂ« thotĂ« se çdo pĂ«rpjekje tjetĂ«r pĂ«r tĂ« ndĂ«rhyrĂ« nĂ« iptables mund tĂ« interpretohet gabim ose tĂ« injorohet krejtĂ«sisht.
Dhe "nga kutia" për të organizuar menaxhimin e politikave rrjetore në grupin Kubernetes ofrohen . Ky burim, që zgjerohet në hapësirat e zgjedhura, mund të përmbajë rregulla për të kufizuar aksesin nga aplikacione të ndryshme. Ai gjithashtu lejon konfigurimin e disponueshmërisë midis pod-ave të caktuar, mjediseve (hapësirave emri) ose grupeve të IP adresave:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978Ky kjo sâĂ«shtĂ« shembulli mĂ« i thjeshtĂ« nga mund tĂ« largohet njĂ«herĂ« e pĂ«rgjithmonĂ« dĂ«shira pĂ«r tĂ« kuptuar logjikĂ«n e politikave rrnetwork. MegjithatĂ«, do tĂ« pĂ«rpiqemi tĂ« kuptojmĂ« parimet dhe metodat kryesore tĂ« pĂ«rpunimit tĂ« trafikut pĂ«rmes politikave rrnetwork...
ĂshtĂ« logjike qĂ« ka 2 tipa trafiku: ai qĂ« hyn nĂ« pod (Ingress) dhe ai qĂ« del nga ai (Egress).

Përkatësisht, politika ndahet në këto 2 kategori sipas drejtimit të lëvizjes.
Atributi tjetĂ«r i detyrueshĂ«m Ă«shtĂ« selektori; ai ku aplikohet rregulli. Kjo mund tĂ« jetĂ« pod (ose grup podâesh) ose ambienti (pra, hapĂ«sira emĂ«rtimi). NjĂ« detaj i rĂ«ndĂ«sishĂ«m: tĂ« dyja kĂ«to lloje objektesh duhet tĂ« pĂ«rmbajnĂ« njĂ« etiketĂ« (etiketĂ« nĂ« terminologjinĂ« Kubernetes) â me tĂ« cilat punojnĂ« politikat.
Përveç numrit të përfundimtare të selektorëve të bashkuar nga një etiketë, ekziston mundësia për të shkruar rregulla si "Lejo/ndalo gjithçka/njësi" në variacione të ndryshme. Përdoren struktura të tilla si:
podSelector: {}
ingress: []
policyTypes:
- Ingressâ nĂ« kĂ«tĂ« shembull, gjithçkaje pod nĂ« mjedis i mbyllet trafiku i ardhshĂ«m. NjĂ« sjellje tĂ« kundĂ«rt mund tĂ« arrihet me kĂ«tĂ« strukturĂ«:
podSelector: {}
ingress:
- {}
policyTypes:
- IngressNë mënyrë të ngjashme për trafikun e daljes:
podSelector: {}
policyTypes:
- Egressâ pĂ«r ta çaktivizuar. Dhe ja çfarĂ« pĂ«r ta aktivizuar:
podSelector: {}
egress:
- {}
policyTypes:
- EgressDuke u kthyer nĂ« zgjedhjen e plugin-it CNI pĂ«r klastri, vlen tĂ« theksohet se nuk çdo plugin rrjeti mbĂ«shtet funksionimin me NetworkPolicy. PĂ«r shembull, Flannel-i i pĂ«rmendur mĂ« parĂ« nuk mund tĂ« konfigurojĂ« politikat rrjetore, pĂ«r tĂ« cilĂ«n nĂ« depot zyrtare. Atje pĂ«rmendet gjithashtu alternativa â projekti Open Source , i cili zgjeron ndjeshĂ«m setin standard tĂ« API-sĂ« Kubernetes nĂ« aspektin e politikave rrjetore.

Njihemi me Calico: teoria
Plugin-i Calico mund të përdoret në integrimin me Flannel (nëpodprojektin ) ose vetë, duke mbuluar si funksionet për sigurinë e lidhjes në rrjet, ashtu edhe mundësitë për menaxhimin e disponibilitetit.
Cilat janë mundësitë që ofron përdorimi i një zgjidhje të tipit 'box' K8s dhe grupit të API-ve nga Calico?
Ja se çfarë është e integruar në NetworkPolicy:
- politikat janë të kufizuara në ambientin;
- politikat zbatohen në pod-et e etiketuar;
- rregullat mund të zbatohen në pod-e, ambiente ose subnet-e;
- rregullat mund të përmbajnë protokolle, gjithashtu emra ose referenca simbolike për portat.
Ja se si Calico i zgjeron këto funksione:
- politikat mund të zbatohen në çdo objekt: pod, konteiner, makinë virtuale ose interface;
- rregullat mund të përmbajnë një veprim të caktuar (ndalimi, lejo, regjistrim);
- si një qëllim ose burim rregullash mund të jetë një port, diapazon portesh, protokolle, karakteristika HTTP ose ICMP, IP ose subnet (generata 4 ose 6), çdo selektor (nody, hostesh, ambiente);
- për më tepër, mund të rregullohet kalimi i trafikut përmes konfigurimeve DNAT dhe politikave të kalimit të trafikut.
Komitet e para nĂ« GitHub nĂ« depin Calico datojnĂ« nga korriku 2016, dhe vetĂ«m njĂ« vit mĂ« vonĂ«, projekti zuri pozita dominuese nĂ« organizimin e lidhjeve tĂ« rrjetit Kubernetes â kĂ«tĂ« e tregojnĂ«, pĂ«r shembull, rezultatet e anketave, :

Shumë zgjidhje të mëdha të menaxhuara me K8s, të tilla si , , dhe të tjera, filluan të rekomandojnë përdorimin e tij.
Sa i përket performancës, këtu gjithçka është e shkëlqyer. Gjatë testimit të produktit të tyre, ekipi zhvillues i Calico demonstroi tregues astronomikë, duke përgatitur më shumë se 50000 kontejnerë në 500 node fizikë me një shpejtësi krijimi prej 20 kontejnerësh në sekondë. Nuk u identifikuan probleme gjatë zgjerimit. Këto rezultate mënyrë të pari gjatë njoftimit të versionit të parë. Studime të pavarura, të orientuara ndaj kapacitetit dhe konsumin e burimeve, po ashtu konfirmojnë performancën e Calico, e cila është pothuajse e barabartë me Flannel. :

Projekti po zhvillohet shumë shpejt, mbështetet nga puna në zgjidhjet popullore të menaxhuara K8s, OpenShift, OpenStack, dhe ka mundësi të përdorim Calico gjatë vendosjes së një klasteri me anë të , përmenden ndërtimi i rrjeteve Service Mesh ( përdorimi i përbashkët me Istio).
Praktika me Calico
Në përgjithësi, përdorimi i Kubernetes vanilla kërkon instalimin e CNI që reduktohet në aplikimin e skedarit calico.yaml, , përmes kubectl apply -f.
Si rregull, versioni aktual i pluginit është kompatibil me 2-3 versionet e fundit të Kubernetes: funskionaliteti në versionet më të vjetra nuk testohet dhe nuk garantohet. Sipas deklaratave të zhvilluesve, Calico funksionon në bërthamën Linux më të lartë se 3.10 nën menaxhimin e CentOS 7, Ubuntu 16 ose Debian 8, mbi iptables ose IPVS.
Izolimi brenda ambientit
Për një kuptim të përgjithshëm, le të shqyrtojmë një rast të thjeshtë për të kuptuar se si ndryshojnë politikat rrjetore në notacionin Calico nga standardet dhe si qasja ndaj përbërjes së rregullave e thjeshton lexueshmërinë dhe fleksibilitetin e konfiguratave:

Në klaster janë vendosur 2 aplikacione web: një në Node.js dhe një në PHP, - njëri prej të cilave përdor Redis. Për të mbyllur qasjen në Redis nga PHP, duke ruajtur lidhshmërinë me Node.js, mjafton të aplikoni politikën e mëposhtme:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-redis-nodejs
spec:
podSelector:
matchLabels:
service: redis
ingress:
- from:
- podSelector:
matchLabels:
service: nodejs
ports:
- protocol: TCP
port: 6379Ne vendosim lehtësisht që të lejohet trafik i hyrës për portin Redis nga Node.js. Dhe dukshëm nuk ndalojmë asgjë tjetër. Sapo shfaqet NetworkPolicy, të gjithë selektorët e përmendur në të fillojnë të izolojnë, përveç nëse përndryshe është e përcaktuar. Rregullat e izolimit nuk zbatohen në objekte të tjera që nuk mbulohen nga selektori.
Në shembull përdoret apiVersion i Kubernetes, por asgjë nuk e ndalon përdorimin e . Sintaksa atje është më e gjerë, kështu që do të nevojitet të rishkruhet rregulli për rastin e përshkruar më sipër në këtë formë:
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: allow-redis-nodejs
spec:
selector: service == 'redis'
ingress:
- action: Allow
protocol: TCP
source:
selector: service == 'nodejs'
destination:
ports:
- 6379 Konstruksionet e përmendura më lart për lehtësimin ose ndalimin e të gjithë trafikut përmes API-t të zakonshëm të NetworkPolicy përmbajnë konstruksione të ndërlikuara për t'u kuptuar dhe mbajtur mend. Në rastin e Calico, për të ndryshuar logjikën e funksionimit të rregullit të firewall-it, është e mjaftueshme të ndryshoni veprimi: Lejo në veprimi: Ndaloi.
Izolimi sipas ambientit
Tani imagjinoni një situatë ku aplikacioni gjeneron metrika biznesi për t'u mbledhur në Prometheus dhe për analizë të mëtejshme përmes Grafana. Në eksport mund të përfshihen të dhëna të ndjeshme, të cilat për default janë përsëri të disponueshme për shikim të përgjithshëm. Le të mbyllim këto të dhëna nga sy të huaj:

Prometheus, si rregull, Ă«shtĂ« vendosur nĂ« njĂ« ambient shĂ«rbimi tĂ« veçantĂ« â nĂ« kĂ«tĂ« rast, do tĂ« jetĂ« namespace e kĂ«tij lloji:
apiVersion: v1
kind: Namespace
metadata:
labels:
module: prometheus
name: kube-prometheus Fusha metadata.labels nĂ« kĂ«tĂ« rast nuk Ă«shtĂ« rastĂ«sore. Siç pĂ«rmendĂ«m mĂ« sipĂ«r, namespaceSelector (si dhe podSelector) operon me etiketa. Prandaj, pĂ«r tĂ« lejuar marrjen e metrike nga tĂ« gjithĂ« podâĂ«t nĂ« njĂ« port tĂ« caktuar, do tĂ« duhet tĂ« shtoni ndonjĂ« etiketĂ« (ose tĂ« merrni nga ato ekzistuese), dhe pastaj tĂ« aplikoni njĂ« konfigurim si:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-metrics-prom
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
module: prometheus
ports:
- protocol: TCP
port: 9100Nëse përdoren politici Calico, sintaksa do të jetë si më poshtë:
apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
name: allow-metrics-prom
spec:
ingress:
- action: Allow
protocol: TCP
source:
namespaceSelector: module == 'prometheus'
destination:
ports:
- 9100Në përgjithësi, duke shtuar këtë lloj politikash për nevoja specifike, mund të mbrohen aplikacionet në klaster nga ndërhyrjet e keqdashura ose të rastësishme.
Praktika mĂ« e mirĂ«, sipas krijuesve tĂ« Calico, Ă«shtĂ« qasja "Ndaloni gjithçka dhe hapni qartĂ« atĂ« qĂ« Ă«shtĂ« e nevojshme", e cila Ă«shtĂ« e dokumentuar nĂ« (qasje tĂ« ngjashme mbajnĂ« edhe tĂ« tjerĂ«t â nĂ« veçanti, nĂ« ).
Përdorimi i objekteve shtesë Calico
Dua të kujtoj se përmes setit të zgjeruar të API Calico, mund të rregullohet aksesibiliteti i nodave, pa u kufizuar vetëm në pod-at. Në shembullin e ardhshëm, përmes GlobalNetworkPolicy mbyllet mundësia e kalimit të kërkesave ICMP në klaster (për shembull, ping nga një pod në nod, midis pod-ave ose nga nod në IP të pod-it):
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: block-icmp
spec:
order: 200
selector: all()
types:
- Ingress
- Egress
ingress:
- action: Deny
protocol: ICMP
egress:
- action: Deny
protocol: ICMP Në rastin e mësipërm, mbetet mundësia që nyjat e klasterit të "arrijnë" njëra-tjetrën përmes ICMP. Dhe ky problem zgjidhet me mjete GlobalNetworkPolicy, e aplikuar në entitetin HostEndpoint:
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: deny-icmp-kube-02
spec:
selector: "role == 'k8s-node'"
order: 0
ingress:
- action: Allow
protocol: ICMP
egress:
- action: Allow
protocol: ICMP
---
apiVersion: crd.projectcalico.org/v1
kind: HostEndpoint
metadata:
name: kube-02-eth0
labels:
role: k8s-node
spec:
interfaceName: eth0
node: kube-02
expectedIPs: ["192.168.2.2"]Rasti i VPN
Më në fund, do të jap një shembull të vërtetë të përdorimit të funksioneve Calico për rastin e ndërveprimit përreth klasterit, kur grupi standard i politikave është i pamjaftueshëm. Për qasje në aplikacionin web nga klientët përdoret një tunel VPN, dhe kjo qasje është e kontrolluar dhe e kufizuar rreptësisht ndaj një liste specifike të shërbimeve të lejuara:

Klientët lidhën me VPN përmes portit standard UDP 1194 dhe, gjatë lidhjes, marrin rrugët për subnetet klaster të podëve dhe shërbimeve. Subnetet shtyhen tërësisht për të mos humbur shërbimet gjatë rinisjeve dhe ndërrimit të adresave.
Porti në konfigurim është standard, që sjell disa nuanca në procesin e konfigurimit të aplikacionit dhe transferimin e tij në klasterin Kubernetes. Për shembull, në AWS LoadBalancer për UDP është bërë disponibël vetëm në fund të vitit të kaluar në një listë të kufizuar regjesh, dhe NodePort nuk mund të përdoret për shkak se transferohet në të gjitha nodet e klasterit dhe është e pamundur të rritet numri i instancave të serverit për qëllime qëndrueshmërie. Gjithashtu, do të duhet të ndryshohet diapazoni i porteve që zgjidhet nga default...
Si rezultat i shqyrtimit të zgjidhjeve të mundshme, u zgjodh kjo:
- Podët me VPN planifikohen në nodin në mënyrë
hostNetwork, domethënë në IP-në reale. - Shërbimi nxirret jashtë përmes
ClusterIP. NĂ« nodin fizikisht ngrihet njĂ« port qĂ« Ă«shtĂ« i aksesueshĂ«m nga jashtĂ« me disa rezervime tĂ« vogla (vendosja e njĂ« adrese IP reale). - PĂ«rcaktimi i nodit ku Ă«shtĂ« ngjitur pod-i i tejkalon tregimin tonĂ«. Do tĂ« thosha vetĂ«m se mund tĂ« lidhni ngushtĂ« shĂ«rbimin me nodin ose tĂ« shkruani njĂ« shĂ«rbim tĂ« vogĂ«l anĂ«sor qĂ« do tĂ« mbikĂ«qyrĂ« adresĂ«n aktuale IP tĂ« shĂ«rbimit VPN dhe do tĂ« rregullojĂ« regjistrimet DNS tĂ« shkruara nga klientĂ«t â sipas imagjinatĂ«s sĂ« secilit.
Nga pikëpamja e ruterimit, ne mund ta identifikojmë qartë klientin nën VPN përmes adresës së tij IP, që jepet nga serveri VPN. Më poshtë është një shembull primitiv i kufizimit të aksesit të tillë klienti në shërbime, një ilustërim mbi Redis-in e përmendur më lart:
apiVersion: crd.projectcalico.org/v1
kind: HostEndpoint
metadata:
name: vpnclient-eth0
labels:
role: vpnclient
environment: production
spec:
interfaceName: "*"
node: kube-02
expectedIPs: ["172.176.176.2"]
---
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: vpn-rules
spec:
selector: "role == 'vpnclient'"
order: 0
applyOnForward: true
preDNAT: true
ingress:
- action: Deny
protocol: TCP
destination:
ports: [6379]
- action: Allow
protocol: UDP
destination:
ports: [53, 67]Këtu ndalohet me forcë lidhja në portin 6379, por shërbimi DNS vazhdon të funksionojë, i cili shpesh ndikohet negativisht nga rregullat që krijohen. Sepse, siç u përmend më parë, në rast se shfaqet një selektor, ndaj tij aplikohet një politikë ndaluese e paracaktuar, përveç nëse është specifikuar ndryshe.
Përfundimet
Në këtë mënyrë, me ndihmën e API-së së avancuar të Calico, mund të konfigurohet fleksibël dhe të ndryshohet dinamik rrugëzimi brenda dhe rreth klasterit. Në përgjithësi, përdorimi i tij mund të duket si të qitsh me një armë të madhe në pëllëmbë, dhe implementimi i një rrjeti L3 me tunel BGP dhe IP-IP duket monstrous në një instalim të thjeshtë të Kubernetes në një rrjet të sheshtë⊠Megjithatë, në anën tjetër, gjithsesi është mjeti mjaft funksional dhe i dobishëm.
Izolimi i klasterit për të përmbushur kërkesat e sigurisë nuk mund të realizohet gjithmonë, dhe në këto raste ndihmon Calico (ose një zgjidhje të ngjashme). Shembujt e dhënë në artikull (me disa modifikime) përdoren në disa instalime të klientëve tanë në AWS.
P.S.
Lexoni gjithashtu në blogun tonë:
- «»;
- «Udhëzuesi ilustruar për ndërtimin e rrjetit në Kubernetes»: , ;
- «».
Burimi: habr.com
