Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Artikli eesmärk on tutvustada lugejale Kubernetese võrgustamise ja võrgupoliitikate haldamise põhitõdesid, aga ka kolmanda osapoole Calico pistikprogrammi, mis laiendab standardseid võimalusi. Selle käigus demonstreeritakse konfigureerimise lihtsust ja mõningaid funktsioone, kasutades meie kasutuskogemusest pärinevaid reaalseid näiteid.

Kubernetese võrguseadme kiire tutvustus

Kubernetese klastrit ei saa ette kujutada ilma võrguta. Oleme juba avaldanud materjale nende põhitõdede kohta: "Illustreeritud juhend Kubernetese võrgu loomiseks"Ja"Sissejuhatus Kubernetese võrgupoliitikasse turbeprofessionaalidele'.

Selle artikli kontekstis on oluline märkida, et K8s ise ei vastuta konteinerite ja sõlmede vahelise võrguühenduse eest: selleks on erinevad CNI pistikprogrammid (Container Networking Interface). Lisateavet selle kontseptsiooni kohta me nad ütlesid mulle ka.

Näiteks kõige levinum neist pluginatest on Flanell — pakub täielikku võrguühendust kõigi klastri sõlmede vahel, tõstes sildu igale sõlmele, määrates sellele alamvõrgu. Täielik ja reguleerimata juurdepääs ei ole aga alati kasulik. Klastris minimaalse isolatsiooni tagamiseks on vaja sekkuda tulemüüri konfiguratsiooni. Üldjuhul on see sama CNI kontrolli all, mistõttu võib mis tahes kolmanda osapoole sekkumisi iptablesis tõlgendada valesti või üldse ignoreerida.

Ja Kubernetese klastris pakutakse võrgupoliitika haldamise korraldamiseks "kastist väljas". NetworkPolicy API. See valitud nimeruumide vahel jaotatud ressurss võib sisaldada reegleid, mis eristavad juurdepääsu ühelt rakenduselt teisele. Samuti võimaldab see konfigureerida juurdepääsetavust konkreetsete kaustade, keskkondade (nimeruumide) või IP-aadresside plokkide vahel:

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

See ei ole kõige primitiivsem näide ametlik dokumentatsioon võib lõplikult heidutada soovi mõista võrgupoliitika toimimise loogikat. Püüame siiski mõista võrgupoliitikate abil liiklusvoogude töötlemise põhiprintsiipe ja meetodeid...

On loogiline, et liiklust on 2 tüüpi: sisenev (sisenemine) ja sealt väljuv (Egress).

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Tegelikult jaguneb poliitika liikumissuuna alusel nendesse kahte kategooriasse.

Järgmine nõutav atribuut on selektor; see, kelle suhtes reegel kehtib. See võib olla pod (või kaunade rühm) või keskkond (st nimeruum). Oluline detail: mõlemat tüüpi need objektid peavad sisaldama silti (etikett Kubernetese terminoloogias) – need on need, millega poliitikud tegutsevad.

Lisaks piiratud arvule valijatele, mida ühendab mingi silt, on võimalik erinevates variatsioonides kirjutada reegleid nagu “Luba/keela kõik/kõik”. Sel eesmärgil kasutatakse vormi konstruktsioone:

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

- selles näites on kõik keskkonnas olevad kaustad sissetuleva liikluse eest blokeeritud. Vastupidise käitumise saab saavutada järgmise konstruktsiooniga:

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

Samamoodi väljaminevate suhete jaoks:

  podSelector: {}
  policyTypes:
  - Egress

- selle väljalülitamiseks. Ja siin on, mida lisada:

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

Tulles tagasi klastri CNI-plugina valiku juurde, väärib märkimist mitte iga võrgu pistikprogramm ei toeta NetworkPolicyt. Näiteks juba mainitud Flannel ei oska konfigureerida võrgupoliitikaid, mis see on otse öeldud ametlikus hoidlas. Seal on mainitud ka alternatiivi – avatud lähtekoodiga projekti Calico, mis laiendab märkimisväärselt Kubernetes API-de standardset komplekti võrgupoliitika osas.

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Calicoga tutvumine: teooria

Calico pistikprogrammi saab kasutada integreerituna Flanneliga (alamprojekt Kanal) või iseseisvalt, hõlmates nii võrguühenduse kui ka saadavuse halduse võimalusi.

Milliseid võimalusi pakub K8s "kastiga" lahenduse ja Calico API komplekti kasutamine?

NetworkPolicysse on sisse ehitatud järgmine:

  • poliitikud on keskkonna poolt piiratud;
  • poliitikat kohaldatakse siltidega märgistatud kaunadele;
  • reegleid saab rakendada kaubikutele, keskkondadele või alamvõrkudele;
  • reeglid võivad sisaldada protokolle, nimelisi või sümboolseid pordi spetsifikatsioone.

Calico neid funktsioone laiendab järgmiselt.

  • poliitikaid saab rakendada mis tahes objektile: kaustale, konteinerile, virtuaalmasinale või liidesele;
  • reeglid võivad sisaldada konkreetset toimingut (keeld, luba, logimine);
  • reeglite sihtmärk või allikas võib olla port, portide vahemik, protokollid, HTTP või ICMP atribuudid, IP või alamvõrk (4. või 6. põlvkond), mis tahes selektorid (sõlmed, hostid, keskkonnad);
  • Lisaks saate DNAT seadete ja liikluse edastamise poliitikate abil reguleerida liikluse läbimist.

Esimesed kohustused GitHubil Calico repositooriumis pärinevad 2016. aasta juulist ning aasta hiljem võttis projekt Kubernetese võrguühenduse korraldamisel juhtiva positsiooni – sellest annavad tunnistust näiteks uuringu tulemused, dirigeeris The New Stack:

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Paljud suured hallatavad lahendused K8-dega, nt Amazon EKS, Azure AKS, Google GKE ja teised hakkasid seda soovitama kasutada.

Mis puudutab jõudlust, siis siin on kõik suurepärane. Oma toote testimisel demonstreeris Calico arendusmeeskond astronoomilist jõudlust, käitades enam kui 50000 500 konteinerit 20 füüsilises sõlmes loomiskiirusega XNUMX konteinerit sekundis. Skaleerimisega probleeme ei tuvastatud. Sellised tulemused kuulutati välja juba esimese versiooni väljakuulutamisel. Sõltumatud uuringud, mis keskenduvad läbilaskevõimele ja ressursside tarbimisele, kinnitavad ka, et Calico jõudlus on peaaegu sama hea kui Flanneli oma. Näiteks:

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Projekt areneb väga kiiresti, see toetab tööd populaarsetes lahendustes, mida hallatakse K8s, OpenShift, OpenStack, klastri juurutamisel on võimalik kasutada Calico lööma, on viiteid Service Meshi võrkude ehitamisele (siin on näide kasutatakse koos Istioga).

Harjutage Calicoga

Vanilje Kubernetese kasutamisel taandub CNI installimine faili kasutamisele calico.yaml, alla laaditud ametlikult veebisaidilt, kasutades kubectl apply -f.

Reeglina ühildub pistikprogrammi praegune versioon Kubernetese 2-3 uusima versiooniga: vanemate versioonide toimimist ei testita ja see ei ole garanteeritud. Arendajate sõnul töötab Calico Linuxi tuumadel, mis on vanemad kui 3.10 ja kus töötab CentOS 7, Ubuntu 16 või Debian 8, lisaks iptablesile või IPVS-ile.

Isolatsioon keskkonnas

Üldise arusaamise huvides vaatleme lihtsat juhtumit, et mõista, kuidas Calico tähistuses olevad võrgupoliitikad erinevad standardsetest ja kuidas reeglite loomise lähenemisviis lihtsustab nende loetavust ja konfiguratsiooni paindlikkust:

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Klastris on juurutatud 2 veebirakendust: Node.js ja PHP, millest üks kasutab Redist. PHP-lt Redisele juurdepääsu blokeerimiseks, säilitades samas ühenduse Node.js-iga, rakendage lihtsalt järgmist reeglit.

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

Põhimõtteliselt lubasime Node.js-ist Redise porti sissetuleva liikluse. Ja nad selgelt ei keelanud midagi muud. Niipea kui NetworkPolicy ilmub, hakkavad kõik selles mainitud valijad olema isoleeritud, kui pole teisiti määratud. Samas ei kehti isolatsioonireeglid teistele objektidele, mida valija ei hõlma.

Näide kasutab apiVersion Kubernetes karbist välja, kuid miski ei takista seda kasutamast Calico tarne samanimeline ressurss. Sealne süntaks on üksikasjalikum, seega peate ülaltoodud juhtumi reegli järgmisel kujul ümber kirjutama:

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

Eespool nimetatud konstruktsioonid kogu liikluse lubamiseks või keelamiseks tavalise NetworkPolicy API kaudu sisaldavad sulgudega konstruktsioone, mida on raske mõista ja meelde jätta. Calico puhul tulemüürireegli loogika vastupidiseks muutmiseks lihtsalt muutke action: Allow edasi action: Deny.

Isolatsioon keskkonna poolt

Kujutage nüüd ette olukorda, kus rakendus genereerib ärimõõdikuid Prometheuse kogumiseks ja Grafana abil edasiseks analüüsiks. Üleslaadimine võib sisaldada tundlikke andmeid, mis on vaikimisi taas avalikult vaadatavad. Peidame need andmed uudishimulike pilkude eest:

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Prometheus paigutatakse reeglina eraldi teeninduskeskkonda - näites on see selline nimeruum:

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

Väli metadata.labels see ei osutunud juhuks. Nagu eelnevalt mainitud, namespaceSelector (sama hästi kui podSelector) töötab siltidega. Seetõttu peate konkreetse pordi kõigist kaustadest mõõdikute võtmiseks lisama mingisuguse sildi (või võtma olemasolevatelt) ja seejärel rakendama konfiguratsiooni, näiteks:

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

Ja kui kasutate Calico eeskirju, on süntaks järgmine:

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

Üldiselt saate seda tüüpi poliitikate lisamisega konkreetsete vajaduste jaoks kaitsta pahatahtliku või juhusliku sekkumise eest klastris olevate rakenduste töös.

Calico loojate sõnul on parim tava lähenemisviis „Blokeeri kõik ja ava selgesõnaliselt see, mida vajate”, mis on dokumenteeritud ametlik dokumentatsioon (teised järgivad sarnast lähenemist – eelkõige in juba mainitud artikkel).

Täiendavate Calico objektide kasutamine

Lubage mul teile meelde tuletada, et Calico API-de laiendatud komplekti kaudu saate reguleerida sõlmede saadavust, mitte ainult kaunadega. Järgmises näites kasutades GlobalNetworkPolicy ICMP-päringute edastamise võimalus klastris on suletud (nt pingid podist sõlme, kaustade vahel või sõlmest IP-poodi):

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

Ülaltoodud juhul on klastri sõlmedel siiski võimalik ICMP kaudu üksteisega ühendust võtta. Ja see probleem lahendatakse vahenditega GlobalNetworkPolicy, rakendatakse olemile 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-i juhtum

Lõpetuseks toon väga reaalse näite Calico funktsioonide kasutamisest klastrilähedase interaktsiooni puhul, kui standardsest poliitikakomplektist ei piisa. Veebirakendusele juurdepääsemiseks kasutavad kliendid VPN-tunnelit ja see juurdepääs on rangelt kontrollitud ja piiratud konkreetse kasutamiseks lubatud teenuste loendiga:

Calico Kubernetese võrgu loomiseks: tutvustus ja väike kogemus

Kliendid ühenduvad VPN-iga standardse UDP-pordi 1194 kaudu ja saavad ühenduse korral marsruute kaunade ja teenuste klastri alamvõrkudesse. Terved alamvõrgud lükatakse edasi, et mitte kaotada teenuseid taaskäivitamise ja aadresside muutmise ajal.

Konfiguratsioonis olev port on standardne, mis seab rakenduse konfigureerimise ja Kubernetese klastrisse ülekandmise protsessile mõningaid nüansse. Näiteks samas AWS-is ilmus LoadBalancer for UDP sõna otseses mõttes eelmise aasta lõpus piiratud regioonide loendis ja NodePorti ei saa kasutada selle edastamise tõttu kõigis klastri sõlmedes ja serveri eksemplaride arvu skaleerimine on võimatu. veataluvuse eesmärkidel. Lisaks peate muutma portide vaikevahemikku ...

Võimalike lahenduste otsimise tulemusena valiti järgmine:

  1. VPN-iga moodulid on ajastatud iga sõlme kohta hostNetworkst tegelikule IP-le.
  2. Teenus postitatakse väljaspool läbi ClusterIP. Sõlmele on füüsiliselt paigaldatud port, mis on väljastpoolt ligipääsetav väikeste reservatsioonidega (reaalse IP-aadressi tingimuslik olemasolu).
  3. Sõlme kindlaksmääramine, millel kaun tõusis, jääb meie loo ulatusest välja. Ütlen lihtsalt, et saate teenuse tihedalt sõlme külge "naelutada" või kirjutada väikese külgkorvi teenuse, mis jälgib VPN-teenuse praegust IP-aadressi ja redigeerib klientidega registreeritud DNS-kirjeid - kellel on piisavalt kujutlusvõimet.

Marsruutimise vaatenurgast saame VPN-kliendi ainulaadselt tuvastada VPN-serveri väljastatud IP-aadressi järgi. Allpool on primitiivne näide sellise kliendi teenustele juurdepääsu piiramisest, mida illustreerib ülalmainitud 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]

Siin on ühenduse loomine pordiga 6379 rangelt keelatud, kuid samal ajal säilib DNS-teenuse toimimine, mille toimimine reeglite koostamisel üsna sageli kannatab. Kuna, nagu eelnevalt mainitud, rakendatakse valija ilmumisel sellele vaikekeelupoliitikat, kui pole teisiti määratud.

Tulemused

Seega saate Calico täiustatud API abil paindlikult konfigureerida ja dünaamiliselt muuta marsruutimist klastris ja selle ümbruses. Üldiselt võib selle kasutamine välja näha nagu kahuriga varblaste tulistamist ning BGP ja IP-IP tunnelitega L3 võrgu rakendamine näeb Kubernetese lihtsas installatsioonis lamedale võrgule koletu välja... Samas näeb tööriist muidu üsna elujõuline ja kasulik välja .

Turvanõuetele vastava klastri isoleerimine ei pruugi alati olla teostatav ja siin tuleb appi Calico (või sarnane lahendus). Selles artiklis toodud näiteid (väiksemate muudatustega) kasutatakse meie klientide mitmes AWS-i installis.

PS

Loe ka meie blogist:

Allikas: www.habr.com

Lisa kommentaar