Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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: «Udhëzuesi i ilustruar për strukturën e rrjetit në Kubernetes» dhe «Një hyrje në politikat rrjetore Kubernetes për specialistët e sigurisë».

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 edhe kemi folur.

PĂ«r shembull, plugin mĂ« i pĂ«rhapur nga ato Ă«shtĂ« Flannel — 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 NetworkPolicy API. 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: 5978

Ky kjo s’ështĂ« shembulli mĂ« i thjeshtĂ« nga dokumenti zyrtar 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).

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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

Në 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:
  - Egress

Duke 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 thuhet hapur nĂ« depot zyrtare. Atje pĂ«rmendet gjithashtu alternativa — projekti Open Source Calico, i cili zgjeron ndjeshĂ«m setin standard tĂ« API-sĂ« Kubernetes nĂ« aspektin e politikave rrjetore.

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

Njihemi me Calico: teoria

Plugin-i Calico mund të përdoret në integrimin me Flannel (nëpodprojektin Canal) 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, tĂ« kryera nga The New Stack:

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

Shumë zgjidhje të mëdha të menaxhuara me K8s, të tilla si Amazon EKS, Azure AKS, Google GKE 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 u shprehën 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. Për shembull:

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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ë kops, përmenden ndërtimi i rrjeteve Service Mesh (kjo është një shembull 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, të shkarkuar nga faqja zyrtare, 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:

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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

Ne 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 burimit me të njëjtin emër nga furnizimi Calico. 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:

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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

Në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:
      - 9100

Në 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Ă« dokumenti zyrtar (qasje tĂ« ngjashme mbajnĂ« edhe tĂ« tjerĂ«t — nĂ« veçanti, nĂ« artikullin e pĂ«rmendur mĂ« parĂ«).

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:

Calico për rrjetin në Kubernetes: njohje dhe pak nga përvoja

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:

  1. Podët me VPN planifikohen në nodin në mënyrë hostNetwork, domethënë në IP-në reale.
  2. 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).
  3. 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ë:

Burimi: habr.com

Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« đŸ”„ Bli njĂ« hosting tĂ« besueshĂ«m pĂ«r faqet me mbrojtje DDoS, VPS VDS serverĂ« | ProHoster