Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Tujuan artikel kasebut yaiku kanggo ngenalake pamaca babagan dhasar jaringan lan ngatur kabijakan jaringan ing Kubernetes, uga plugin Calico pihak katelu sing ngluwihi kemampuan standar. Sadawane dalan, gampang konfigurasi lan sawetara fitur bakal dituduhake nggunakake conto nyata saka pengalaman operasi kita.

Pambuka cepet kanggo piranti jaringan Kubernetes

Kluster Kubernetes ora bisa dibayangake tanpa jaringan. Kita wis nerbitake materi babagan dhasar: "Pandhuan ilustrasi kanggo jaringan ing Kubernetes"Lan"Pambuka kanggo Kabijakan Jaringan Kubernetes kanggo Profesional Keamanan".

Ing konteks artikel iki, penting kanggo dicathet yen K8s dhewe ora tanggung jawab kanggo konektivitas jaringan antarane wadhah lan simpul: kanggo iki, macem-macem Plugin CNI (Antarmuka Jaringan Kontainer). Liyane babagan konsep iki kita padha uga marang kula.

Contone, sing paling umum saka plugin iki yaiku Flannel - nyedhiyakake panyambungan jaringan lengkap ing antarane kabeh kelenjar kluster kanthi ngunggahake jembatan ing saben simpul, menehi subnet. Nanging, aksesibilitas lengkap lan ora diatur ora mesthi migunani. Kanggo nyedhiyani sawetara jenis isolasi minimal ing kluster, iku perlu kanggo campur ing konfigurasi saka firewall. Ing kasus umum, diselehake ing kontrol CNI sing padha, mula apa wae intervensi pihak katelu ing iptables bisa ditafsirake kanthi ora bener utawa ora digatekake kabeh.

Lan "out of the box" kanggo ngatur manajemen kabijakan jaringan ing kluster Kubernetes diwenehake NetworkPolicy API. Sumber daya iki, disebarake liwat spasi jeneng sing dipilih, bisa uga ngemot aturan kanggo mbedakake akses saka siji aplikasi menyang aplikasi liyane. Sampeyan uga ngidini sampeyan ngatur aksesibilitas ing antarane pods, lingkungan (spasi jeneng) utawa blok alamat IP tartamtu:

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

Iki dudu conto sing paling primitif dokumentasi resmi bisa sapisan lan kanggo kabeh discourage kepinginan kanggo ngerti logika carane kawicaksanan jaringan bisa. Nanging, kita isih bakal nyoba mangertos prinsip dhasar lan cara ngolah arus lalu lintas nggunakake kabijakan jaringan...

Iku logis yen ana 2 jinis lalu lintas: ngetik pod (Ingress) lan metu saka iku (Egress).

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Sejatine politik dipΓ©rang dadi 2 kategori iki adhedhasar arah gerakan.

Atribut sing dibutuhake sabanjure yaiku pamilih; wong sing ditrapake aturan kasebut. Iki bisa dadi pod (utawa klompok pods) utawa lingkungan (yaiku namespace). Rincian penting: loro jinis obyek kasebut kudu ngemot label (label ing terminologi Kubernetes) - iki sing dianggo politisi.

Saliyane nomer winates saka pamilih united dening sawetara jenis label, iku bisa kanggo nulis aturan kaya "Allow / nolak kabeh / kabeh" ing variasi beda. Kanggo tujuan iki, konstruksi wangun digunakake:

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

- ing conto iki, kabeh pods ing lingkungan diblokir saka lalu lintas mlebu. Prilaku ngelawan bisa digayuh kanthi konstruksi ing ngisor iki:

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

Kajaba iku kanggo metu:

  podSelector: {}
  policyTypes:
  - Egress

- kanggo mateni. Lan iki sing kudu kalebu:

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

Bali menyang pilihan saka plugin CNI kanggo kluster, iku worth kang lagi nyimak sing ora saben plugin jaringan ndhukung NetworkPolicy. Contone, Flannel wis kasebut ora ngerti carane ngatur kawicaksanan jaringan, kang iku ngandika langsung ing repositori resmi. Alternatif uga kasebut ing kana - proyek Open Source Calico, sing sacara signifikan ngembangake set standar API Kubernetes babagan kabijakan jaringan.

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Ngerteni Calico: teori

Plugin Calico bisa digunakake kanthi integrasi karo Flannel (subproyek Kanal) utawa kanthi mandiri, nyakup konektivitas jaringan lan kapabilitas manajemen kasedhiyan.

Apa kesempatan nggunakake solusi "kotak" K8s lan set API saka Calico nyedhiyani?

Mangkene apa sing dibangun ing NetworkPolicy:

  • politisi diwatesi dening lingkungan;
  • kawicaksanan ditrapake kanggo polong sing ditandhani label;
  • aturan bisa ditrapake kanggo pods, lingkungan utawa subnets;
  • aturan bisa ngemot protokol, jeneng utawa specifications port simbolis.

Mangkene carane Calico ngluwihi fungsi kasebut:

  • kawicaksanan bisa ditrapake kanggo obyek apa wae: pod, wadhah, mesin virtual utawa antarmuka;
  • aturan bisa ngemot tumindak tartamtu (larangan, ijin, logging);
  • target utawa sumber aturan bisa dadi port, sawetara port, protokol, HTTP utawa ICMP atribut, IP utawa subnet (generasi 4 utawa 6), pamilih (node, host, lingkungan);
  • Kajaba iku, sampeyan bisa ngatur lalu lintas nggunakake setelan DNAT lan kabijakan terusan lalu lintas.

Komitmen pisanan ing GitHub ing repositori Calico tanggal bali menyang Juli 2016, lan setaun sabanjure proyek kasebut njupuk posisi utama ing ngatur konektivitas jaringan Kubernetes - iki dibuktekake, contone, kanthi asil survey, ditindakake dening The New Stack:

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Akeh solusi ngatur gedhe karo K8s, kayata Amazon EX, Azure AKS, Google GKE lan liyane wiwit menehi rekomendasi kanggo nggunakake.

Kanggo kinerja, kabeh apik ing kene. Nalika nguji produke, tim pangembang Calico nduduhake kinerja astronomi, nglakokake luwih saka 50000 kontainer ing 500 simpul fisik kanthi tingkat nggawe 20 kontainer per detik. Ora ana masalah sing diidentifikasi karo skala. Hasil sing kaya ngono padha diumumake wis ing woro-woro versi pisanan. Pasinaon independen sing fokus ing throughput lan konsumsi sumber daya uga ngonfirmasi kinerja Calico meh padha karo Flannel. Contone:

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Proyèk iki berkembang cepet banget, ndhukung karya ing solusi populer ngatur K8s, OpenShift, OpenStack, iku bisa kanggo nggunakake Calico nalika deploying kluster nggunakake nyepak, ana referensi kanggo pambangunan jaringan Service Mesh (Punika conto digunakake bebarengan karo Istio).

Laku karo Calico

Ing kasus umum nggunakake vanilla Kubernetes, nginstal CNI mudhun kanggo nggunakake file calico.yaml, diundhuh saka situs web resmi, kanthi nggunakake kubectl apply -f.

Minangka aturan, versi plugin saiki kompatibel karo 2-3 versi paling anyar saka Kubernetes: operasi ing versi lawas ora dites lan ora dijamin. Miturut pangembang, Calico mlaku ing kernel Linux ndhuwur 3.10 mlaku CentOS 7, Ubuntu 16 utawa Debian 8, ing ndhuwur iptables utawa IPVS.

Isolasi ing lingkungan

Kanggo pangerten umum, ayo goleki kasus sing gampang kanggo ngerti kepiye kabijakan jaringan ing notasi Calico beda karo standar lan kepiye cara nggawe aturan nggawe gampang diwaca lan keluwesan konfigurasi:

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Ana 2 aplikasi web sing disebarake ing kluster: ing Node.js lan PHP, salah sijine nggunakake Redis. Kanggo mblokir akses menyang Redis saka PHP, nalika njaga konektivitas karo Node.js, gunakake kabijakan ing ngisor iki:

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

Ateges kita ngidini lalu lintas mlebu menyang port Redis saka Node.js. Lan padha cetha ora nglarang tindakan liya. Sanalika NetworkPolicy katon, kabeh pamilih sing kasebut ing kono wiwit diisolasi, kajaba kasebut. Nanging, aturan isolasi ora ditrapake kanggo obyek liyane sing ora dilindhungi dening pamilih.

Tuladha nggunakake apiVersion Kubernetes metu saka kothak, nanging ora ana sing ngalangi sampeyan nggunakake sumber saka jeneng sing padha saka pangiriman Calico. Sintaks ana luwih rinci, dadi sampeyan kudu nulis ulang aturan kanggo kasus ing ndhuwur ing wangun ing ngisor iki:

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

Konstruksi sing kasebut ing ndhuwur kanggo ngidini utawa nolak kabeh lalu lintas liwat NetworkPolicy API biasa ngemot konstruksi nganggo tanda kurung sing angel dimangerteni lan dieling-eling. Ing cilik saka Calico, kanggo ngganti logika aturan firewall kanggo ngelawan, mung ngganti action: Allow ing action: Deny.

Isolasi dening lingkungan

Saiki bayangake kahanan ing ngendi aplikasi ngasilake metrik bisnis kanggo koleksi ing Prometheus lan analisis luwih lanjut nggunakake Grafana. Unggahan kasebut bisa uga ngemot data sensitif, sing bisa dideleng maneh kanthi umum. Ayo ndhelikake data iki saka prying eyes:

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Prometheus, minangka aturan, diselehake ing lingkungan layanan sing kapisah - ing conto bakal dadi spasi jeneng kaya iki:

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

lapangan metadata.labels iki pranyata ora Laka. Kaya sing kasebut ing ndhuwur, namespaceSelector (uga podSelector) dianggo nganggo label. Mula, kanggo ngidini metrik dijupuk saka kabeh pod ing port tartamtu, sampeyan kudu nambah sawetara jinis label (utawa njupuk saka sing wis ana), banjur aplikasi konfigurasi kaya:

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

Lan yen sampeyan nggunakake kabijakan Calico, sintaks bakal kaya iki:

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

UmumΓ©, kanthi nambahake kabijakan iki kanggo kabutuhan tartamtu, sampeyan bisa nglindhungi saka gangguan sing ora sengaja utawa ora sengaja ing operasi aplikasi ing kluster.

Praktek paling apik, miturut pencipta Calico, yaiku pendekatan "Blokir kabeh lan mbukak kanthi jelas apa sing sampeyan butuhake", didokumentasikan ing dokumentasi resmi (liyane ngetutake pendekatan sing padha - utamane, ing wis kasebut artikel).

Nggunakake Obyek Calico Tambahan

Ayo kula ngelingake sampeyan liwat set lengkap Calico API sampeyan bisa ngatur kasedhiyan kelenjar, ora winates kanggo pods. Ing conto ing ngisor iki nggunakake GlobalNetworkPolicy kemampuan kanggo ngirim panjalukan ICMP ing kluster ditutup (contone, ping saka pod menyang simpul, antarane pods, utawa saka simpul menyang 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

Ing kasus ndhuwur, iku isih bisa kanggo kelenjar kluster kanggo "tekan metu" kanggo saben liyane liwat ICMP. Lan masalah iki ditanggulangi kanthi cara GlobalNetworkPolicy, ditrapake kanggo entitas 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"]

Kasus VPN

Akhire, aku bakal menehi conto banget nyata nggunakake fungsi Calico kanggo cilik interaksi cedhak-cluster, nalika pesawat standar saka kawicaksanan ora cukup. Kanggo ngakses aplikasi web, klien nggunakake terowongan VPN, lan akses iki dikontrol kanthi ketat lan diwatesi menyang dhaptar layanan tartamtu sing diidini digunakake:

Calico kanggo jaringan ing Kubernetes: introduksi lan pengalaman sethithik

Klien nyambung menyang VPN liwat port UDP standar 1194 lan, nalika disambungake, nampa rute menyang subnet kluster pods lan layanan. Kabeh subnet di-push supaya ora kelangan layanan nalika miwiti maneh lan owah-owahan alamat.

Port ing konfigurasi punika standar, kang nemtokke sawetara nuansa ing proses configuring aplikasi lan nransfer menyang kluster Kubernetes. Contone, ing padha AWS LoadBalancer kanggo UDP katon secara harfiah ing pungkasan taun pungkasan ing dhaftar winates saka wilayah, lan NodePort ora bisa digunakake amarga nerusake ing kabeh kelenjar kluster lan iku mokal kanggo ukuran nomer kedadean server kanggo. tujuan toleransi kesalahan. Kajaba iku, sampeyan kudu ngganti sawetara standar port ...

Minangka asil panelusuran liwat solusi sing bisa, ing ngisor iki dipilih:

  1. Pod karo VPN dijadwalake saben simpul ing hostNetwork, yaiku, menyang IP nyata.
  2. Layanan dikirim njaba liwat ClusterIP. A port dipasang sacara fisik ing simpul, sing bisa diakses saka njaba kanthi leladen cilik (kondisi anane alamat IP nyata).
  3. Nemtokake simpul ing ngendi polong mawar ngluwihi ruang lingkup crita kita. Aku mung bakal ujar manawa sampeyan bisa "naku" layanan kasebut menyang simpul utawa nulis layanan sidecar cilik sing bakal ngawasi alamat IP saiki layanan VPN lan nyunting cathetan DNS sing didaftar karo klien - sapa wae sing duwe imajinasi sing cukup.

Saka perspektif routing, kita bisa ngenali klien VPN kanthi alamat IP sing diterbitake dening server VPN. Ing ngisor iki minangka conto primitif kanggo mbatesi akses klien kasebut menyang layanan, sing digambarake ing Redis sing kasebut ing ndhuwur:

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]

Ing kene, nyambungake menyang port 6379 dilarang banget, nanging ing wektu sing padha operasi layanan DNS dilestarekake, fungsi sing asring nandhang sangsara nalika nggawe aturan. Amarga, kaya sing wis kasebut sadurunge, nalika pamilih katon, kabijakan nolak standar ditrapake kajaba kasebut.

Hasil

Mangkono, nggunakake API majeng Calico kang, sampeyan bisa fleksibel ngatur lan mbosenke ngganti nuntun ing lan watara kluster. UmumΓ©, nggunakake bisa katon kaya manuk pipit nembak karo mriem, lan ngleksanakake jaringan L3 karo BGP lan IP-IP trowongan katon monstrous ing instalasi Kubernetes prasaja ing jaringan flat ... Nanging, digunakake alat katon cukup sregep lan migunani. .

Ngisolasi kluster kanggo nyukupi syarat keamanan bisa uga ora bisa ditindakake, lan ing kene Calico (utawa solusi sing padha) bisa nylametake. Conto sing diwenehake ing artikel iki (karo modifikasi cilik) digunakake ing sawetara instalasi klien kita ing AWS.

PS

Waca uga ing blog kita:

Source: www.habr.com

Add a comment