Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

U scopu di l'articulu hè di presentà u lettore à i principii di a rete è a gestione di e pulitiche di rete in Kubernetes, è ancu u plugin Calico di terzu chì estende e capacità standard. In u caminu, a facilità di cunfigurazione è alcune caratteristiche seranu dimustrate usendu esempi reali da a nostra sperienza operativa.

Una introduzione rapida à l'appliance di rete Kubernetes

Un cluster Kubernetes ùn pò esse imaginatu senza una reta. Avemu digià publicatu materiali nantu à i so principii: "Una guida illustrata per a rete in Kubernetes"E"Una Introduzione à e Politiche di Rete Kubernetes per i Prufessiunali di Sicurezza».

In u cuntestu di questu articulu, hè impurtante nutà chì K8s stessu ùn hè micca rispunsevule per a cunnessione di a rete trà i cuntenituri è i nodi: per questu, diverse plugins CNI (Interfaccia di rete di container). Più nantu à stu cuncettu avemu mi anu dettu ancu.

Per esempiu, u più cumuni di sti plugins hè Flannel - furnisce una connettività di rete completa trà tutti i nodi di cluster alzendu ponti nantu à ogni nodu, assignendu una subnet. Tuttavia, l'accessibilità cumpleta è micca regulata ùn hè micca sempre benefica. Per furnisce un tipu di isolamentu minimu in u cluster, hè necessariu intervene in a cunfigurazione di u firewall. In u casu generale, hè pusatu sottu à u cuntrollu di u stessu CNI, per quessa chì qualsiasi intervenzioni di terzu in iptables ponu esse interpretati in modu incorrectu o ignoratu in tuttu.

È "fora di scatula" per urganizà a gestione di pulitica di rete in un cluster Kubernetes hè furnitu NetworkPolicy API. Questa risorsa, distribuita nantu à spazii di nomi selezziunati, pò cuntene regule per diferenze l'accessu da una applicazione à l'altru. Permette ancu di cunfigurà l'accessibilità trà pods specifichi, ambienti (spazi di nomi) o blocchi di indirizzi IP:

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

Questu ùn hè micca l'esempiu più primitivu documentazione ufficiale pò una volta per sempre scoraggià u desideriu di capisce a logica di u funziunamentu di e pulitiche di rete. Tuttavia, avemu sempre à pruvà à capisce i principii basi è i metudi di trasfurmà i flussi di trafficu utilizendu e pulitiche di rete...

Hè logicu chì ci sò 2 tipi di trafficu: entra in u pod (Ingress) è esce da ellu (Egress).

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

In verità, a pulitica hè divisa in queste 2 categurie basatu nantu à a direzzione di u muvimentu.

U prossimu attributu necessariu hè un selettore; quellu à quale si applica a regula. Questu pò esse un pod (o un gruppu di pods) o un ambiente (vale à dì un namespace). Un dettagliu impurtante: i dui tipi di sti ogetti deve cuntene una etichetta (etichetta in a terminologia Kubernetes) - questi sò quelli chì i pulitici operanu.

In più di un numeru finitu di selettori uniti da una certa etichetta, hè pussibule di scrive regule cum'è "Permette / ricusà tuttu / tutti" in diverse variazioni. Per questu scopu, custruzzioni di a forma sò utilizati:

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

- in questu esempiu, tutti i pods in l'ambiente sò bluccati da u trafficu entrante. U cumpurtamentu oppostu pò esse ottenutu cù a custruzzione seguente:

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

Similmente per l'outgoing:

  podSelector: {}
  policyTypes:
  - Egress

- per spegnellu. È quì hè ciò chì include:

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

Riturnendu à a scelta di un plugin CNI per un cluster, vale a pena nutà chì micca tutti i plugins di rete supportanu NetworkPolicy. Per esempiu, u Flannel digià citatu ùn sapi cumu cunfigurà e pulitiche di rete, chì si dice direttamente in u repositoriu ufficiale. Una alternativa hè ancu citata quì - un prughjettu Open Source Calico, chì espansione significativamente u settore standard di l'API Kubernetes in termini di pulitiche di rete.

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

Cunniscenza di Calicu : teoria

U plugin Calico pò esse usatu in integrazione cù Flannel (subproject Canal) o indipindentamente, coprendu a cunnessione di a rete è e capacità di gestione di a dispunibilità.

Chì opportunità offre l'usu di a soluzione "boxed" K8s è u set API di Calico?

Eccu ciò chì hè integratu in NetworkPolicy:

  • i pulitichi sò limitati da l'ambiente;
  • e pulitiche sò applicate à i baccelli marcati cù etichette;
  • e regule ponu esse applicate à pods, ambienti o subnets;
  • regule ponu cuntene protocols, specificazioni portu chjamati o simbolichi.

Eccu cumu Calico estende queste funzioni:

  • e pulitiche ponu esse applicate à qualsiasi ughjettu: pod, cuntainer, macchina virtuale o interfaccia;
  • e regule ponu cuntene una azzione specifica (pruibizione, permessu, logging);
  • u scopu o fonte di e regule pò esse un portu, una varietà di porti, protokolli, attributi HTTP o ICMP, IP o subnet (generazione 4 o 6), qualsiasi selettori (nodi, hosts, ambienti);
  • Inoltre, pudete regulà u passaghju di u trafficu utilizendu paràmetri DNAT è pulitiche di spedizione di trafficu.

I primi impegni nantu à GitHub in u repository Calico datanu di lugliu 2016, è un annu dopu u prugettu hà pigliatu una pusizioni di primura in l'urganizazione di a cunnessione di a rete Kubernetes - questu hè evidenza, per esempiu, da i risultati di l'indagine. cunduttu da The New Stack:

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

Parechje suluzioni gestite grandi cù K8s, cum'è Amazon EKS, Azure AKS, Google GKE è altri cuminciaru à ricumandemu per l'usu.

In quantu à u rendiment, tuttu hè grande quì. In a prova di u so pruduttu, u squadra di sviluppu di Calico hà dimustratu u rendiment astronomicu, eseguendu più di 50000 500 cuntenituri nantu à 20 nodi fisichi cù un ritmu di creazione di XNUMX cuntenituri per seconda. Nisun prublema sò stati identificati cù scaling. Tali risultati sò stati annunziati digià à l'annunziu di a prima versione. Studi indipendenti chì si focalizanu nantu à u throughput è u cunsumu di risorse cunfirmanu ancu chì a prestazione di Calico hè guasi cum'è quella di Flannel. Per esempiu:

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

U prughjettu si sviluppa assai rapidamente, supporta u travagliu in soluzioni populari gestite K8s, OpenShift, OpenStack, hè pussibule aduprà Calico quandu implementate un cluster utilizendu kops, ci sò riferimenti à a custruzzione di rete Service Mesh (eccu un esempiu usatu in cunjunzione cù Istio).

Pratica cù Calico

In u casu generale di usu di vanilla Kubernetes, a stallazione di CNI si riduce à aduprà u schedariu calico.yaml, scaricatu da u situ ufficiali, usendu kubectl apply -f.

Comu regula, a versione attuale di u plugin hè cumpatibile cù l'ultime versioni 2-3 di Kubernetes: l'operazione in versioni più vechje ùn hè micca pruvata è ùn hè micca garantita. Sicondu i sviluppatori, Calico corre nantu à i kernel Linux sopra 3.10 cù CentOS 7, Ubuntu 16 o Debian 8, sopra à iptables o IPVS.

Isolamentu in l'ambiente

Per una cunniscenza generale, fighjemu un casu simplice per capisce cumu e pulitiche di rete in a notazione Calico difierenu da quelli standard è cumu l'approcciu di creà regule simplifica a so leghjibilità è a flessibilità di cunfigurazione:

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

Ci sò 2 applicazioni web implementate in u cluster: in Node.js è PHP, una di quale usa Redis. Per bluccà l'accessu à Redis da PHP, mantenendu a cunnessione cù Node.js, basta à applicà a seguente pulitica:

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

Essenzialmente avemu permessu u trafficu entrante à u portu Redis da Node.js. È chjaramente ùn anu pruibitu nunda altru. Appena NetworkPolicy apparisce, tutti i selettori citati in ella cumincianu à esse isolati, salvu s'ellu ùn hè micca specificatu. Tuttavia, e regule di isolamentu ùn s'applicanu micca à l'altri oggetti chì ùn sò micca cuparti da u selettore.

L'esempiu usa apiVersion Kubernetes fora di a scatula, ma nunda ùn impedisce di aduprà risorsa di u listessu nome da a consegna Calico. A sintassi ci hè più dettagliata, cusì avete bisognu di riscrive a regula per u casu sopra in a forma seguente:

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

I custruzzioni sopra citati per permettenu o nigà tuttu u trafficu attraversu l'API NetworkPolicy regulare cuntenenu custruzzioni cù parentesi chì sò difficiuli di capiscenu è ricurdate. In u casu di Calico, per cambià a logica di una regula di firewall à u cuntrariu, solu cambià action: Allow nantu action: Deny.

Isolamentu da l'ambiente

Avà imaginate una situazione induve una applicazione genera metriche cummerciale per a cullizzioni in Prometheus è più analisi cù Grafana. L'upload pò cuntene dati sensittivi, chì sò di novu visibile publicamente per difettu. Ocultemu questi dati da l'occhi indiscreti:

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

Prometheus, in regula, hè situatu in un ambiente di serviziu separatu - in l'esempiu serà un spaziu di nomi cum'è questu:

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

chjosu metadata.labels questu ùn hè micca un accidentu. Cum'è dettu sopra, namespaceSelector (cum'è podSelector) opera cù etichette. Dunque, per permette di piglià metriche da tutti i pods nantu à un portu specificu, duverete aghjunghje un tipu d'etichetta (o piglià da quelli esistenti), è poi applicà una cunfigurazione cum'è:

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

È se utilizate pulitiche Calico, a sintassi serà cusì:

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

In generale, agghiuncennu sti tipi di pulitiche per bisogni specifichi, pudete prutegge contra l'interferenza maliciosa o accidintali in l'operazione di l'applicazioni in u cluster.

A megghiu pratica, sicondu i creatori di Calico, hè l'approcciu "Blocca tuttu è apre esplicitamente ciò chì avete bisognu", documentatu in documentazione ufficiale (altri seguitanu un approcciu simili - in particulare, in articulu digià citatu).

Utilizà uggetti Calico addiziunali

Lasciami ricurdà chì attraversu u settore estensatu di Calico APIs pudete regulà a dispunibilità di nodi, micca limitati à pods. In l'esempiu seguente usendu GlobalNetworkPolicy a capacità di passà e dumande ICMP in u cluster hè chjusa (per esempiu, ping da un pod à un node, trà pods, o da un node à un pod IP):

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

In u casu sopra, hè sempre pussibule per i nodi di cluster per "alcuni" à l'altri via ICMP. È sta questione hè risolta per mezu GlobalNetworkPolicy, applicata à una entità 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"]

U casu VPN

Infine, daraghju un esempiu assai reale di l'usu di e funzioni di Calico per u casu di interazzione vicinu à u cluster, quandu un settore standard di pulitiche ùn hè micca abbastanza. Per accede à l'applicazione web, i clienti utilizanu un tunnel VPN, è questu accessu hè strettamente cuntrullatu è limitatu à una lista specifica di servizii permessi per l'usu:

Calico per a rete in Kubernetes: introduzione è un pocu di sperienza

I clienti si cunnettanu à a VPN via u portu standard UDP 1194 è, quandu sò cunnessi, ricevenu rotte à i subnets di cluster di pods è servizii. Subnets intere sò spinti per ùn perde micca i servizii durante i riavvii è i cambiamenti di indirizzu.

U portu in a cunfigurazione hè standard, chì impone qualchi sfumature nantu à u prucessu di cunfigurà l'applicazione è trasfirìu à u cluster Kubernetes. Per esempiu, in u stessu AWS LoadBalancer per UDP apparsu literalmente à a fine di l'annu passatu in una lista limitata di regioni, è NodePort ùn pò micca esse usatu per via di u so forwarding in tutti i nodi di cluster è hè impussibile di scala u numeru di istanze di u servitore per scopi di tolleranza di colpa. In più, vi tuccherà à cambià a gamma predeterminata di porti ...

In u risultatu di a ricerca di e pussibuli suluzioni, hè stata scelta:

  1. I pods cù VPN sò pianificati per node in hostNetwork, vale à dì à l'IP attuale.
  2. U serviziu hè publicatu fora attraversu ClusterIP. Un portu hè stallatu fisicu nantu à u node, chì hè accessibile da l'esternu cù riservazioni minori (presenza cundiziunale di un veru indirizzu IP).
  3. A determinazione di u node nantu à quale u pod rose hè fora di u scopu di a nostra storia. Diceraghju solu chì pudete "chiovu" u serviziu à un node o scrive un picculu serviziu di sidecar chì monitorerà l'indirizzu IP attuale di u serviziu VPN è edità i registri DNS registrati cù i clienti - quellu chì hà abbastanza imaginazione.

Da una perspettiva di routing, pudemu identificà unicu un cliente VPN da u so indirizzu IP emessu da u servitore VPN. Quì sottu hè un esempiu primitivu di restrizzione di l'accessu di tali clienti à i servizii, illustratu nantu à i Redis sopra citati:

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]

Quì, a cunnessione à u portu 6379 hè strettamente pruibitu, ma à u listessu tempu u funziunamentu di u serviziu DNS hè cunsirvatu, u funziunamentu di u quali abbastanza spessu soffre quandu stabilisce e regule. Perchè, cum'è diciatu prima, quandu un selettore appare, a pulitica di rifiutu predeterminata hè applicata à ellu, salvu s'ellu hè specificatu altrimenti.

Risultati

Cusì, utilizendu l'API avanzata di Calico, pudete cunfigurà in modu flessibile è cambià dinamicamente u routing in è intornu à u cluster. In generale, u so usu pò vede cum'è sparrows cù un cannone, è l'implementazione di una rete L3 cù tunnelli BGP è IP-IP pare monstruosa in una simplicità di installazione Kubernetes in una reta piatta... In ogni casu, l'uttellu pare assai viable è utile. .

Isulà un cluster per risponde à i bisogni di sicurezza ùn pò micca sempre esse fattibile, è questu hè quì Calico (o una suluzione simili) vene in salvezza. L'esempii dati in questu articulu (cù modifiche minori) sò usati in parechje installazioni di i nostri clienti in AWS.

PS

Leghjite puru nant'à u nostru blog:

Source: www.habr.com

Add a comment