Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Maqolaning maqsadi o'quvchini Kubernetes-da tarmoq tuzish va tarmoq siyosatini boshqarish asoslari, shuningdek, standart imkoniyatlarni kengaytiruvchi uchinchi tomon Calico plaginlari bilan tanishtirishdir. Yo'l davomida konfiguratsiya qulayligi va ba'zi xususiyatlar bizning operatsion tajribamizdan haqiqiy misollar yordamida namoyish etiladi.

Kubernetes tarmoq qurilmasiga qisqacha kirish

Kubernetes klasterini tarmoqsiz tasavvur qilib bo'lmaydi. Biz allaqachon ularning asoslari bo'yicha materiallarni nashr qildik: "Kubernetesda tarmoqqa ulanish bo'yicha tasvirlangan qo'llanma"Va"Xavfsizlik mutaxassislari uchun Kubernetes tarmoq siyosatiga kirish".

Ushbu maqola kontekstida shuni ta'kidlash kerakki, K8-ning o'zi konteynerlar va tugunlar o'rtasidagi tarmoq ulanishi uchun javobgar emas: buning uchun turli xil CNI plaginlari (Konteyner tarmoq interfeysi). Ushbu kontseptsiya haqida ko'proq biz menga ham aytishdi.

Masalan, ushbu plaginlarning eng keng tarqalgani Flanel — har bir tugundagi ko'priklarni ko'tarish, unga quyi tarmoqni belgilash orqali barcha klaster tugunlari o'rtasida to'liq tarmoq ulanishini ta'minlaydi. Biroq, to'liq va tartibga solinmagan foydalanish har doim ham foydali emas. Klasterda qandaydir minimal izolyatsiyani ta'minlash uchun xavfsizlik devori konfiguratsiyasiga aralashish kerak. Umumiy holda, u xuddi shu CNI nazorati ostida bo'ladi, shuning uchun iptables-ga har qanday uchinchi tomon aralashuvi noto'g'ri talqin qilinishi yoki umuman e'tiborga olinmasligi mumkin.

Kubernetes klasterida tarmoq siyosatini boshqarishni tashkil qilish uchun "qutidan tashqarida" taqdim etilgan NetworkPolicy API. Tanlangan nomlar boʻshliqlari boʻyicha taqsimlangan ushbu resurs bir ilovadan boshqasiga kirishni farqlash qoidalarini oʻz ichiga olishi mumkin. Shuningdek, u sizga ma'lum podalar, muhitlar (nom bo'shliqlari) yoki IP manzil bloklari o'rtasida foydalanish imkoniyatini sozlash imkonini beradi:

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

Bu eng ibtidoiy misol emas rasmiy hujjatlar tarmoq siyosati qanday ishlashi mantiqini tushunish istagini bir marta va baribir so'ndirishi mumkin. Biroq, biz hali ham tarmoq siyosatidan foydalangan holda trafik oqimlarini qayta ishlashning asosiy tamoyillari va usullarini tushunishga harakat qilamiz...

Trafikning 2 turi mavjudligi mantiqan to'g'ri keladi: podga kirish (Kirish) va undan chiqish (Egress).

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Darhaqiqat, siyosat harakat yo'nalishiga ko'ra ushbu 2 toifaga bo'linadi.

Keyingi talab qilinadigan atribut - bu selektor; qoida kimga tegishli bo'lsa. Bu pod (yoki podalar guruhi) yoki muhit (ya'ni nomlar maydoni) bo'lishi mumkin. Muhim tafsilot: ushbu ob'ektlarning ikkala turida yorliq bo'lishi kerak (belgi Kubernetes terminologiyasida) - siyosatchilar shular bilan ishlaydi.

Belgilar bilan birlashtirilgan cheklangan sonli selektorlarga qo'shimcha ravishda, turli xil variantlarda "Hamma narsaga / hammaga ruxsat berish / rad etish" kabi qoidalarni yozish mumkin. Shu maqsadda shaklning konstruktsiyalari qo'llaniladi:

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

— bu misolda muhitdagi barcha podlar kiruvchi trafikdan bloklangan. Qarama-qarshi xatti-harakatlarga quyidagi qurilish bilan erishish mumkin:

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

Xuddi shunday chiqish uchun:

  podSelector: {}
  policyTypes:
  - Egress

- uni o'chirish uchun. Va bu erda quyidagilarni kiritish kerak:

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

Klaster uchun CNI plaginini tanlashga qaytsak, shuni ta'kidlash kerak har bir tarmoq plaginlari NetworkPolicy-ni qo'llab-quvvatlamaydi. Misol uchun, yuqorida aytib o'tilgan Flanel tarmoq siyosatini qanday sozlashni bilmaydi to'g'ridan-to'g'ri aytiladi rasmiy omborda. U erda muqobil ham tilga olinadi - Open Source loyihasi Calico, bu tarmoq siyosati nuqtai nazaridan Kubernetes API standart to'plamini sezilarli darajada kengaytiradi.

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Calico bilan tanishish: nazariya

Calico plaginidan Flannel (subloyiha) bilan integratsiyada foydalanish mumkin kanal) yoki mustaqil ravishda, ham tarmoqqa ulanish, ham mavjudlikni boshqarish imkoniyatlarini qamrab oladi.

K8s "qutili" yechimi va Calico API to'plamidan foydalanish qanday imkoniyatlarni beradi?

Mana NetworkPolicy-ga o'rnatilgan narsalar:

  • siyosatchilar atrof-muhit bilan cheklangan;
  • siyosatlar teglar bilan belgilangan podlarga qo'llaniladi;
  • qoidalar podlar, muhitlar yoki pastki tarmoqlarga qo'llanilishi mumkin;
  • qoidalar protokollar, nomli yoki ramziy port spetsifikatsiyalarini o'z ichiga olishi mumkin.

Calico ushbu funktsiyalarni qanday kengaytiradi:

  • siyosatlar har qanday ob'ektga qo'llanilishi mumkin: pod, konteyner, virtual mashina yoki interfeys;
  • qoidalar muayyan harakatni o'z ichiga olishi mumkin (taqiq, ruxsat, jurnal);
  • maqsad yoki qoidalar manbai port, portlar qatori, protokollar, HTTP yoki ICMP atributlari, IP yoki quyi tarmoq (4 yoki 6-avlod), har qanday selektor (tugunlar, xostlar, muhitlar) bo'lishi mumkin;
  • Bundan tashqari, siz DNAT sozlamalari va trafikni yo'naltirish siyosati yordamida trafik o'tishini tartibga solishingiz mumkin.

GitHub-da Calico omboridagi birinchi majburiyatlar 2016 yil iyuliga to'g'ri keladi va bir yil o'tgach, loyiha Kubernetes tarmog'iga ulanishni tashkil qilishda etakchi o'rinni egalladi - bu, masalan, so'rov natijalaridan dalolat beradi, The New Stack tomonidan o'tkazilgan:

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

K8 bilan boshqariladigan ko'plab yirik echimlar, masalan Amazon EKS, Azure AKS, Google GKE va boshqalar undan foydalanishni tavsiya qila boshladilar.

Ishlashga kelsak, bu erda hamma narsa ajoyib. O'z mahsulotlarini sinovdan o'tkazishda Calico ishlab chiqish jamoasi 50000 dan ortiq jismoniy tugunlarda sekundiga 500 ta konteyner yaratish tezligi bilan 20 XNUMX dan ortiq konteynerlarni ishlatib, astronomik ko'rsatkichlarni namoyish etdi. O'lchov bilan bog'liq muammolar aniqlanmadi. Bunday natijalar e’lon qilindi allaqachon birinchi versiyani e'lon qilishda. O'tkazish qobiliyati va resurslarni iste'mol qilishga qaratilgan mustaqil tadqiqotlar, shuningdek, Caliconing ishlashi Flannelnikiga teng ekanligini tasdiqlaydi. Misol uchun:

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Loyiha juda tez rivojlanmoqda, u K8s, OpenShift, OpenStack tomonidan boshqariladigan mashhur echimlarda ishlashni qo'llab-quvvatlaydi, klasterni joylashtirishda Calico-dan foydalanish mumkin. tepmoq, Service Mesh tarmoqlari qurilishiga havolalar mavjud (bu erda bir misol Istio bilan birgalikda ishlatiladi).

Calico bilan mashq qiling

Vanilla Kubernetes-dan foydalanishning umumiy holatida CNI-ni o'rnatish fayldan foydalanishga to'g'ri keladi calico.yaml, rasmiy veb-saytidan yuklab olingan, s pomoshchyu kubectl apply -f.

Qoida tariqasida, plaginning joriy versiyasi Kubernetesning so'nggi 2-3 versiyasiga mos keladi: eski versiyalarda ishlash sinovdan o'tkazilmaydi va kafolatlanmaydi. Ishlab chiquvchilarga ko'ra, Calico CentOS 3.10, Ubuntu 7 yoki Debian 16 bilan ishlaydigan 8 dan yuqori Linux yadrolarida iptables yoki IPVS ustida ishlaydi.

Atrof muhitda izolyatsiya

Umumiy tushunish uchun, keling, Calico notatsiyasidagi tarmoq siyosatlari standartlardan qanday farq qilishini va qoidalarni yaratishga yondashuv ularning o'qilishi va konfiguratsiya moslashuvchanligini qanday soddalashtirishini tushunish uchun oddiy holatni ko'rib chiqaylik:

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Klasterda ikkita veb-ilova o'rnatilgan: Node.js va PHP-da, ulardan biri Redis-dan foydalanadi. Node.js bilan ulanishni saqlab turgan holda PHP-dan Redis-ga kirishni bloklash uchun quyidagi siyosatni qo'llash kifoya:

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

Aslida biz Node.js dan Redis portiga kiruvchi trafikga ruxsat berdik. Va ular aniq boshqa hech narsani taqiqlamadilar. NetworkPolicy paydo bo'lishi bilan, agar boshqacha ko'rsatilmagan bo'lsa, unda ko'rsatilgan barcha selektorlar izolyatsiya qilina boshlaydi. Biroq, izolyatsiyalash qoidalari selektor tomonidan qamrab olinmagan boshqa ob'ektlarga taalluqli emas.

Misol foydalanadi apiVersion Kubernetes qutidan chiqdi, lekin uni ishlatishingizga hech narsa to'sqinlik qilmaydi Calico yetkazib berishdan bir xil nomdagi resurs. U erda sintaksis batafsilroq, shuning uchun yuqoridagi holat uchun qoidani quyidagi shaklda qayta yozishingiz kerak bo'ladi:

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

Oddiy NetworkPolicy API orqali barcha trafikga ruxsat berish yoki rad etish uchun yuqorida qayd etilgan konstruksiyalar tushunish va eslab qolish qiyin bo‘lgan qavslar bilan tuzilgan konstruksiyalarni o‘z ichiga oladi. Calico misolida, xavfsizlik devori qoidasining mantiqini teskarisiga o'zgartirish uchun shunchaki o'zgartiring action: Allow haqida action: Deny.

Atrof-muhit bo'yicha izolyatsiya

Endi dastur Prometeyda yig'ish va Grafana yordamida keyingi tahlil qilish uchun biznes ko'rsatkichlarini yaratadigan vaziyatni tasavvur qiling. Yuklashda maxfiy maʼlumotlar boʻlishi mumkin, ular sukut boʻyicha yana hammaga koʻrinadi. Keling, ushbu ma'lumotlarni begona ko'zlardan yashiraylik:

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Prometey, qoida tariqasida, alohida xizmat ko'rsatish muhitiga joylashtiriladi - misolda u shunday nom maydoni bo'ladi:

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

dala metadata.labels bu tasodif emas ekan. Yuqorida aytib o'tilganidek, namespaceSelector (shu qatorda; shu bilan birga podSelector) teglar bilan ishlaydi. Shuning uchun, ko'rsatkichlarni ma'lum bir portdagi barcha podslardan olishga ruxsat berish uchun siz qandaydir yorliqni qo'shishingiz (yoki mavjudlaridan olishingiz) va keyin quyidagi kabi konfiguratsiyani qo'llashingiz kerak bo'ladi:

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

Va agar siz Calico siyosatlaridan foydalansangiz, sintaksis quyidagicha bo'ladi:

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

Umuman olganda, muayyan ehtiyojlar uchun ushbu turdagi siyosatlarni qo'shish orqali siz klasterdagi ilovalarning ishlashiga zararli yoki tasodifiy aralashuvlardan himoya qilishingiz mumkin.

Calico yaratuvchilari fikriga ko'ra, eng yaxshi amaliyot "Hamma narsani blokirovka qiling va sizga kerak bo'lgan narsani aniq oching" yondashuvi hujjatlashtirilgan. rasmiy hujjatlar (boshqalar shunga o'xshash yondashuvni qo'llashadi - xususan, in allaqachon aytib o'tilgan maqola).

Qo'shimcha Calico ob'ektlaridan foydalanish

Sizga eslatib o'tamanki, Calico API-larining kengaytirilgan to'plami orqali siz tugunlarning mavjudligini tartibga solishingiz mumkin, faqat podalar bilan cheklanmaydi. Quyidagi misolda foydalanish GlobalNetworkPolicy klasterda ICMP so'rovlarini o'tkazish imkoniyati yopiq (masalan, poddan tugunga, podlar orasidagi yoki tugundan IP podasiga pinglar):

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

Yuqoridagi holatda, klaster tugunlari ICMP orqali bir-biriga "qo'llashi" hali ham mumkin. Va bu muammo vositalar yordamida hal qilinadi GlobalNetworkPolicy, ob'ektga nisbatan qo'llaniladi 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 ishi

Nihoyat, men standart siyosatlar to'plami etarli bo'lmaganda, klasterga yaqin o'zaro ta'sir qilish uchun Calico funktsiyalaridan foydalanishning haqiqiy misolini keltiraman. Veb-ilovaga kirish uchun mijozlar VPN tunnelidan foydalanadilar va bu kirish qat'iy nazorat qilinadi va foydalanishga ruxsat berilgan xizmatlarning ma'lum ro'yxati bilan cheklanadi:

Kubernetesda tarmoq yaratish uchun Calico: kirish va ozgina tajriba

Mijozlar VPN ga standart UDP porti 1194 orqali ulanadi va ulanganda pods va xizmatlarning klaster quyi tarmoqlariga marshrutlarni oladi. Qayta ishga tushirilganda va manzillarni o'zgartirganda xizmatlarni yo'qotmaslik uchun butun subtarmoqlar suriladi.

Konfiguratsiyadagi port standart bo'lib, dasturni sozlash va uni Kubernetes klasteriga o'tkazish jarayoniga ba'zi nuanslarni yuklaydi. Masalan, xuddi shu AWS LoadBalancer for UDP o'tgan yilning oxirida cheklangan hududlar ro'yxatida paydo bo'ldi va NodePort barcha klaster tugunlarida yo'naltirilganligi sababli ishlatilmaydi va server misollari sonini o'lchash mumkin emas. xatolarga chidamlilik maqsadlari. Bundan tashqari, standart portlar oralig'ini o'zgartirishingiz kerak bo'ladi...

Mumkin bo'lgan echimlarni izlash natijasida quyidagilar tanlandi:

  1. VPN bilan podalar har bir tugun uchun rejalashtirilgan hostNetwork, ya'ni haqiqiy IP-ga.
  2. Xizmat tashqarida orqali e'lon qilinadi ClusterIP. Tugunga jismonan port o'rnatilgan bo'lib, unga tashqi tomondan kichik zahiralar bilan kirish mumkin (haqiqiy IP-manzilning shartli mavjudligi).
  3. Poda gullagan tugunni aniqlash bizning hikoyamiz doirasidan tashqarida. Aytmoqchimanki, siz xizmatni tugunga mahkam "mixlab" qo'yishingiz yoki VPN xizmatining joriy IP-manzilini kuzatib boradigan va mijozlar bilan ro'yxatdan o'tgan DNS yozuvlarini tahrirlaydigan kichik yonbosh xizmatini yozishingiz mumkin - kimning tasavvuri etarli bo'lsa.

Marshrutlash nuqtai nazaridan biz VPN mijozini VPN serveri tomonidan berilgan IP manzili bo'yicha yagona aniqlashimiz mumkin. Quyida yuqorida qayd etilgan Redis-da tasvirlangan bunday mijozning xizmatlarga kirishini cheklashning ibtidoiy misoli keltirilgan:

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]

Bu erda 6379 portiga ulanish qat'iyan man etiladi, lekin shu bilan birga DNS xizmatining ishlashi saqlanib qoladi, uning ishlashi qoidalarni tuzishda juda tez-tez zarar ko'radi. Chunki, avval aytib o'tilganidek, selektor paydo bo'lganda, agar boshqacha ko'rsatilmagan bo'lsa, unga standart rad etish siyosati qo'llaniladi.

natijalar

Shunday qilib, Calico-ning ilg'or API-dan foydalanib, siz klaster ichida va uning atrofida marshrutlashni moslashuvchan tarzda sozlashingiz va dinamik ravishda o'zgartirishingiz mumkin. Umuman olganda, undan foydalanish to'p bilan chumchuqlarni otish kabi ko'rinishi mumkin va BGP va IP-IP tunnellari bilan L3 tarmog'ini amalga oshirish tekis tarmoqdagi oddiy Kubernetes o'rnatilishida dahshatli ko'rinadi... Biroq, aks holda, vosita ancha hayotiy va foydali ko'rinadi. .

Xavfsizlik talablariga javob beradigan klasterni izolyatsiya qilish har doim ham imkonsiz bo'lishi mumkin va bu erda Calico (yoki shunga o'xshash yechim) yordamga keladi. Ushbu maqolada keltirilgan misollar (kichik o'zgartirishlar bilan) mijozlarimizning AWS-dagi bir nechta o'rnatishlarida qo'llaniladi.

PS

Shuningdek, bizning blogimizda o'qing:

Manba: www.habr.com

a Izoh qo'shish