Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Tilgangur greinarinnar er að kynna lesandanum grunnatriði netkerfis og stjórnun netstefnu í Kubernetes, sem og þriðja aðila Calico viðbótina sem framlengir staðlaða möguleika. Á leiðinni verður sýnt fram á auðveld stillingu og suma eiginleika með því að nota raunveruleg dæmi úr rekstrarreynslu okkar.

Fljótleg kynning á Kubernetes netkerfi

Ekki er hægt að ímynda sér Kubernetes þyrping án nets. Við höfum þegar gefið út efni um grunnatriði þeirra: “Myndskreytt leiðarvísir um netkerfi í Kubernetes"Og"Kynning á netstefnu Kubernetes fyrir öryggissérfræðinga'.

Í tengslum við þessa grein er mikilvægt að hafa í huga að K8s sjálft ber ekki ábyrgð á nettengingu milli gáma og hnúta: fyrir þetta, CNI viðbætur (Gámanetviðmót). Meira um þetta hugtak við þeir sögðu mér líka.

Til dæmis er algengasta þessara viðbætur Flannel — veitir fulla nettengingu milli allra klasahnúta með því að hækka brýr á hverjum hnút, úthluta honum undirneti. Hins vegar er fullkomið og óreglubundið aðgengi ekki alltaf gagnlegt. Til að tryggja einhvers konar lágmarks einangrun í þyrpingunni er nauðsynlegt að grípa inn í uppsetningu eldveggsins. Í almennu tilvikinu er það sett undir stjórn sama CNI, sem er ástæðan fyrir því að öll afskipti þriðja aðila í iptables geta verið túlkuð rangt eða hunsuð með öllu.

Og „úr kassanum“ til að skipuleggja netstefnustjórnun í Kubernetes klasa er til staðar NetworkPolicy API. Þetta tilfang, dreift yfir valin nafnrými, getur innihaldið reglur til að aðgreina aðgang frá einu forriti til annars. Það gerir þér einnig kleift að stilla aðgengi á milli tiltekinna fræbelgja, umhverfis (nafnarýma) eða blokka af IP-tölum:

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: 5978

Þetta er ekki frumstæðasta dæmið um opinber skjöl getur í eitt skipti fyrir öll dregið úr lönguninni til að skilja rökfræðina um hvernig netstefnur virka. Hins vegar munum við enn reyna að skilja grunnreglur og aðferðir við að vinna umferðarflæði með netstefnu...

Það er rökrétt að það eru 2 tegundir af umferð: inn í belg (Ingress) og út úr honum (Egress).

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Reyndar er stjórnmálum skipt í þessa 2 flokka eftir stefnu hreyfingarinnar.

Næsta nauðsynlega eiginleiki er veljari; þann sem reglan gildir um. Þetta gæti verið belg (eða hópur belg) eða umhverfi (þ.e. nafnrými). Mikilvægt smáatriði: báðar tegundir þessara hluta verða að innihalda merki (merki í Kubernetes hugtökum) - þetta eru þau sem stjórnmálamenn starfa með.

Til viðbótar við takmarkaðan fjölda veljara sem sameinast með einhvers konar merki, er hægt að skrifa reglur eins og „Leyfa/neita öllu/allum“ í mismunandi afbrigðum. Í þessu skyni eru smíði formsins notuð:

  podSelector: {}
  ingress: []
  policyTypes:
  - Ingress

— í þessu dæmi er öllum belgjum í umhverfinu lokað fyrir komandi umferð. Andstæða hegðun er hægt að ná með eftirfarandi byggingu:

  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress

Svipað fyrir útleið:

  podSelector: {}
  policyTypes:
  - Egress

- til að slökkva á því. Og hér er það sem á að innihalda:

  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

Aftur að vali á CNI viðbót fyrir klasa, þá er rétt að taka það fram ekki öll netviðbætur styðja NetworkPolicy. Til dæmis, þegar nefnd Flannel veit ekki hvernig á að stilla netstefnur, sem það er sagt beint í opinberu geymslunni. Þar er einnig nefndur valkostur - Open Source verkefni Calico, sem stækkar umtalsvert staðlað sett Kubernetes API hvað varðar netstefnur.

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Að kynnast Calico: kenningu

Hægt er að nota Calico viðbótina í samþættingu við Flannel (undirverkefni Channel) eða sjálfstætt, sem nær yfir bæði nettengingar og framboðsstjórnunarmöguleika.

Hvaða tækifæri gefur notkun K8s „kassa“ lausnarinnar og API settið frá Calico?

Hér er það sem er innbyggt í NetworkPolicy:

  • stjórnmálamenn takmarkast af umhverfinu;
  • reglum er beitt á belg merkt með merkimiðum;
  • reglum er hægt að beita á belg, umhverfi eða undirnet;
  • reglur geta innihaldið samskiptareglur, nafngreindar eða táknrænar hafnarforskriftir.

Hér er hvernig Calico útvíkkar þessar aðgerðir:

  • Hægt er að beita stefnum á hvaða hlut sem er: belg, ílát, sýndarvél eða viðmót;
  • reglur geta innihaldið ákveðna aðgerð (bann, leyfi, skógarhögg);
  • Markmiðið eða uppspretta reglna getur verið höfn, úrval gátta, samskiptareglur, HTTP eða ICMP eiginleikar, IP eða undirnet (4. eða 6. kynslóð), hvaða val sem er (hnútar, vélar, umhverfi);
  • Að auki geturðu stjórnað umferð umferðar með því að nota DNAT stillingar og stefnu um framsendingu umferðar.

Fyrstu skuldbindingarnar á GitHub í Calico geymslunni eru aftur til júlí 2016, og ári síðar tók verkefnið leiðandi stöðu við að skipuleggja Kubernetes nettengingu - þetta sést til dæmis af niðurstöðum könnunarinnar, undir stjórn The New Stack:

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Margar stórar stýrðar lausnir með K8, eins og Amazon EKS, Azure AKS, Googlaðu GKE og aðrir fóru að mæla með því til notkunar.

Hvað frammistöðu varðar þá er allt frábært hér. Við prófun vörunnar sýndi þróunarteymið Calico fram á stjarnfræðilegan árangur, keyrði meira en 50000 gáma á 500 líkamlegum hnútum með sköpunarhraða upp á 20 gáma á sekúndu. Engin vandamál komu fram við mælingu. Svona niðurstöður voru tilkynnt þegar við birtingu fyrstu útgáfunnar. Óháðar rannsóknir sem einblína á afköst og auðlindanotkun staðfesta einnig að frammistaða Calico sé næstum jafn góð og Flannel. Til dæmis:

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Verkefnið er að þróast mjög hratt, það styður vinnu í vinsælum lausnum stýrðum K8s, OpenShift, OpenStack, það er hægt að nota Calico þegar þyrping er sett upp með sparka, það eru tilvísanir í byggingu Service Mesh net (hér er dæmi notað í tengslum við Istio).

Æfðu þig með Calico

Í almennu tilviki þess að nota vanillu Kubernetes kemur uppsetning CNI niður á að nota skrána calico.yaml, hlaðið niður af opinberu vefsíðunni, með því að nota kubectl apply -f.

Að jafnaði er núverandi útgáfa af viðbótinni samhæfð við nýjustu 2-3 útgáfur af Kubernetes: notkun í eldri útgáfum er ekki prófuð og er ekki tryggð. Samkvæmt þróunaraðilum keyrir Calico á Linux kjarna yfir 3.10 sem keyrir CentOS 7, Ubuntu 16 eða Debian 8, ofan á iptables eða IPVS.

Einangrun innan umhverfisins

Til að fá almennan skilning, skulum við skoða einfalt tilfelli til að skilja hvernig netstefnur í Calico merkingunni eru frábrugðnar venjulegum og hvernig aðferðin við að búa til reglur einfaldar læsileika þeirra og sveigjanleika í stillingum:

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Það eru 2 vefforrit notuð í þyrpingunni: í Node.js og PHP, eitt þeirra notar Redis. Til að loka fyrir aðgang að Redis frá PHP, en viðhalda tengingu við Node.js, skaltu bara beita eftirfarandi stefnu:

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: 6379

Í meginatriðum leyfðum við komandi umferð til Redis höfnarinnar frá Node.js. Og þeir bönnuðu greinilega ekki neitt annað. Um leið og NetworkPolicy birtist byrja allir vallarar sem nefndir eru í henni að vera einangraðir, nema annað sé tekið fram. Hins vegar eiga einangrunarreglurnar ekki við um aðra hluti sem valinn nær ekki yfir.

Dæmið notar apiVersion Kubernetes út úr kassanum, en ekkert kemur í veg fyrir að þú notir það auðlind með sama nafni frá Calico afhendingu. Setningafræðin þar er ítarlegri, svo þú þarft að endurskrifa regluna fyrir ofangreint tilvik á eftirfarandi formi:

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

Ofangreindar smíðar til að leyfa eða hafna allri umferð í gegnum venjulega NetworkPolicy API innihalda smíðar með sviga sem erfitt er að skilja og muna. Þegar um Calico er að ræða, til að breyta rökfræði eldveggsreglu í hið gagnstæða, breytirðu bara action: Allow á action: Deny.

Einangrun eftir umhverfi

Ímyndaðu þér núna aðstæður þar sem forrit býr til viðskiptamælingar til að safna í Prometheus og frekari greiningu með Grafana. Upphleðslan gæti innihaldið viðkvæm gögn, sem aftur er sjálfgefið að sjá opinberlega. Við skulum fela þessi gögn fyrir hnýsnum augum:

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Prometheus er að jafnaði settur í sérstakt þjónustuumhverfi - í dæminu verður það nafnarými eins og þetta:

apiVersion: v1
kind: Namespace
metadata:
  labels:
    module: prometheus
  name: kube-prometheus

Field metadata.labels þetta reyndist engin tilviljun. Eins og fyrr segir, namespaceSelector (sem og podSelector) starfar með merkimiðum. Þess vegna, til að leyfa að mælingar séu teknar úr öllum belgjum á tiltekinni höfn, verður þú að bæta við einhvers konar merki (eða taka úr þeim sem fyrir eru) og nota síðan stillingar eins og:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-metrics-prom
spec:
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          module: prometheus
    ports:
    - protocol: TCP
      port: 9100

Og ef þú notar Calico stefnur verður setningafræðin svona:

apiVersion: crd.projectcalico.org/v1
kind: NetworkPolicy
metadata:
  name: allow-metrics-prom
spec:
  ingress:
  - action: Allow
    protocol: TCP
    source:
      namespaceSelector: module == 'prometheus'
    destination:
      ports:
      - 9100

Almennt, með því að bæta við slíkum reglum fyrir sérstakar þarfir, geturðu verndað gegn illgjarnri eða óvart truflun á rekstri forrita í klasanum.

Besta aðferðin, samkvæmt höfundum Calico, er „Lokaðu á allt og opnaðu beinlínis það sem þú þarft“, skjalfest í opinber skjöl (aðrir fylgja svipaðri nálgun - sérstaklega í grein sem áður er nefnd).

Að nota fleiri Calico hluti

Leyfðu mér að minna þig á að í gegnum aukið sett af Calico API geturðu stjórnað framboði á hnútum, ekki takmarkað við belg. Í eftirfarandi dæmi með því að nota GlobalNetworkPolicy hæfileikinn til að senda ICMP beiðnir í þyrpingunni er lokaður (til dæmis, ping frá belg til hnút, á milli belg eða frá hnút í IP belg):

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

Í ofangreindu tilviki er enn mögulegt fyrir klasahnúta að „ná út“ hver til annars í gegnum ICMP. Og þetta mál er leyst með ráðum GlobalNetworkPolicy, sótt um aðila 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"]

VPN málið

Að lokum mun ég gefa mjög raunverulegt dæmi um notkun Calico aðgerða þegar um er að ræða samspil nálægt klasa, þegar staðlað sett af stefnum er ekki nóg. Til að fá aðgang að vefforritinu nota viðskiptavinir VPN göng og þessum aðgangi er vel stjórnað og takmarkaður við sérstakan lista yfir þjónustu sem er leyfð til notkunar:

Calico fyrir netkerfi í Kubernetes: kynning og smá reynsla

Viðskiptavinir tengjast VPN í gegnum venjulegt UDP tengi 1194 og, þegar þeir eru tengdir, taka við leiðum til þyrpinga undirneta fræbelgs og þjónustu. Allt undirnet er ýtt til að missa ekki þjónustu við endurræsingu og vistföngum breytt.

Gáttin í uppsetningunni er staðlað, sem setur smá blæbrigði á ferlið við að stilla forritið og flytja það í Kubernetes þyrpinguna. Til dæmis, í sama AWS birtist LoadBalancer fyrir UDP bókstaflega í lok síðasta árs á takmörkuðum lista yfir svæði, og NodePort er ekki hægt að nota vegna framsendingar þess á öllum klasahnútum og það er ómögulegt að skala fjölda netþjónstilvika fyrir bilunarmarkmiðum. Auk þess verður þú að breyta sjálfgefna svið hafna...

Eftir að hafa leitað í mögulegum lausnum var eftirfarandi valið:

  1. Pods með VPN eru áætlaðir fyrir hvern hnút inn hostNetwork, það er að segja til raunverulegrar IP.
  2. Þjónustan er sett utan í gegnum ClusterIP. Gátt er líkamlega sett upp á hnútnum, sem er aðgengilegt að utan með minniháttar fyrirvörum (skilyrt tilvist raunverulegs IP tölu).
  3. Að ákvarða hnútinn sem fræbelgrósin á er utan ramma sögu okkar. Ég segi bara að þú getur „neglt“ þjónustuna vel á hnút eða skrifað litla hliðarvagnaþjónustu sem mun fylgjast með núverandi IP tölu VPN þjónustunnar og breyta DNS skránum sem eru skráðar hjá viðskiptavinum - hver sem hefur nóg ímyndunarafl.

Frá sjónarhóli vegvísunar getum við auðkennt VPN viðskiptavin á einstakan hátt með IP tölu þess sem VPN netþjónninn gefur út. Hér að neðan er frumstætt dæmi um að takmarka aðgang slíks viðskiptavinar að þjónustu, sýnt á ofangreindri Redis:

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]

Hér er tenging við höfn 6379 stranglega bönnuð, en á sama tíma er rekstur DNS-þjónustunnar varðveittur, en virkni hennar verður oft fyrir skaða við gerð reglna. Vegna þess að, eins og áður hefur komið fram, þegar veljari birtist er sjálfgefin neitun regla beitt á hann nema annað sé tekið fram.

Niðurstöður

Þannig, með því að nota háþróaða API frá Calico, geturðu stillt á sveigjanlegan hátt og breytt leið í og ​​í kringum þyrpinguna. Almennt séð getur notkun þess litið út eins og að skjóta spörva með fallbyssu og innleiðing á L3 neti með BGP og IP-IP göngum lítur voðalega út í einfaldri Kubernetes uppsetningu á flatu neti... Hins vegar lítur tólið út að öðru leyti nokkuð hagkvæmt og gagnlegt. .

Að einangra klasa til að uppfylla öryggiskröfur er kannski ekki alltaf framkvæmanlegt og það er þar sem Calico (eða svipuð lausn) kemur til bjargar. Dæmin sem gefin eru í þessari grein (með minniháttar breytingum) eru notuð í nokkrum uppsetningum viðskiptavina okkar í AWS.

PS

Lestu líka á blogginu okkar:

Heimild: www.habr.com

Bæta við athugasemd