Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Мақаланың мақсаты - оқырманды Kubernetes жүйесіндегі желілік құру және желілік саясаттарды басқару негіздерімен, сондай-ақ стандартты мүмкіндіктерді кеңейтетін үшінші тарап Calico плагинімен таныстыру. Жол бойында конфигурацияның қарапайымдылығы мен кейбір мүмкіндіктер операциялық тәжірибемізден нақты мысалдар арқылы көрсетіледі.

Kubernetes желілік құрылғысына жылдам кіріспе

Kubernetes кластерін желісіз елестету мүмкін емес. Біз олардың негіздері туралы материалдарды жарияладық: «Kubernetes желісіндегі суреттелген нұсқаулық«Ал»Қауіпсіздік мамандарына арналған Kubernetes желілік саясаттарына кіріспе«.

Осы мақаланың контекстінде K8s өзі контейнерлер мен түйіндер арасындағы желілік қосылымға жауап бермейтінін атап өту маңызды: бұл үшін әртүрлі CNI плагиндері (Контейнерлік желі интерфейсі). Бұл тұжырымдама туралы толығырақ біз олар да маған айтты.

Мысалы, бұл плагиндердің ең көп таралғаны Фланель — әрбір түйінде көпірлерді көтеру, оған ішкі желі тағайындау арқылы барлық кластер түйіндері арасындағы толық желілік қосылымды қамтамасыз етеді. Дегенмен, толық және реттелмеген қолжетімділік әрқашан тиімді бола бермейді. Кластерде минималды оқшаулаудың қандай да бір түрін қамтамасыз ету үшін брандмауэрдің конфигурациясына араласу қажет. Жалпы жағдайда, ол бірдей CNI бақылауында болады, сондықтан iptables-ке кез келген үшінші тарап араласулары дұрыс емес түсіндірілуі немесе мүлде елемеуі мүмкін.

Және Kubernetes кластерінде желілік саясатты басқаруды ұйымдастыру үшін «қораптан тыс» қамтамасыз етілген NetworkPolicy API. Таңдалған аттар кеңістігінде таратылатын бұл ресурста бір қолданбадан екіншісіне қатынасты ажырататын ережелер болуы мүмкін. Ол сондай-ақ арнайы подкасттар, орталар (аттар кеңістігі) немесе 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

Бұл ең қарапайым мысал емес ресми құжаттама желілік саясаттардың қалай жұмыс істейтінінің логикасын түсінуге деген ұмтылысты біржолата басуы мүмкін. Дегенмен, біз әлі де желілік саясаттарды пайдалана отырып, трафик ағындарын өңдеудің негізгі принциптері мен әдістерін түсінуге тырысамыз...

Трафиктің 2 түрі болуы қисынды: подкастқа кіру (Кіру) және одан шығу (Egress).

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Негізінде, саясат қозғалыс бағытына қарай осы екі категорияға бөлінеді.

Келесі қажетті атрибут селектор болып табылады; ереже қолданылатын адам. Бұл бөлім (немесе қосқыштар тобы) немесе орта (мысалы, аттар кеңістігі) болуы мүмкін. Маңызды деталь: осы нысандардың екі түрінде де белгі болуы керек (заттаңба Кубернетес терминологиясында) - бұл саясаткерлер жұмыс істейтіндер.

Белгінің қандай да бір түрімен біріктірілген таңдаушылардың шектеулі санына қоса, әртүрлі вариацияларда «Бәріне/барлығына рұқсат беру/қабылдамау» сияқты ережелерді жазуға болады. Осы мақсатта пішіннің конструкциялары қолданылады:

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

— бұл мысалда қоршаған ортадағы барлық қосқыштар кіріс трафиктен блокталған. Қарама-қарсы мінез-құлыққа келесі құрылыспен қол жеткізуге болады:

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

Сол сияқты шығыс үшін:

  podSelector: {}
  policyTypes:
  - Egress

- өшіру үшін. Және мынаны қосу керек:

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

Кластерге арналған CNI плагинін таңдауға оралсақ, мынаны атап өткен жөн әрбір желілік плагин NetworkPolicy қолданбасын қолдамайды. Мысалы, қазірдің өзінде аталған Фланель желілік саясаттарды қалай конфигурациялау керектігін білмейді тікелей айтылған ресми репозиторийде. Сондай-ақ, бұл жерде балама – Open Source жобасы да айтылған Calico, бұл желі саясаттары тұрғысынан Kubernetes API интерфейстерінің стандартты жинағын айтарлықтай кеңейтеді.

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Каликомен танысу: теория

Calico плагинін Flannel (ішкі жоба канал) немесе желі қосылымын және қол жетімділікті басқару мүмкіндіктерін қамтитын дербес.

K8s «қораптағы» шешімін және Calico API жиынтығын пайдалану қандай мүмкіндіктер береді?

Міне, NetworkPolicy ішіне не кіреді:

  • саясаткерлер қоршаған ортамен шектеледі;
  • саясаттар белгілермен белгіленген тармақтарға қолданылады;
  • ережелер подкасттарға, орталарға немесе ішкі желілерге қолданылуы мүмкін;
  • ережелерде протоколдар, аталған немесе символдық порт спецификациялары болуы мүмкін.

Calico бұл функцияларды қалай кеңейтеді:

  • саясаттарды кез келген нысанға қолдануға болады: подкаст, контейнер, виртуалды машина немесе интерфейс;
  • ережелер белгілі бір әрекетті қамтуы мүмкін (тыйым салу, рұқсат беру, журналға жазу);
  • мақсат немесе ережелер көзі порт, порттар ауқымы, протоколдар, HTTP немесе ICMP атрибуттары, IP немесе ішкі желі (4-ші немесе 6-шы буын), кез келген селекторлар (түйіндер, хосттар, орталар) болуы мүмкін;
  • Сонымен қатар, сіз DNAT параметрлері мен трафикті бағыттау саясаттары арқылы трафиктің өтуін реттей аласыз.

Calico репозиторийіндегі GitHub-тағы алғашқы міндеттемелер 2016 жылдың шілдесінен басталады, ал бір жылдан кейін жоба Kubernetes желісінің қосылуын ұйымдастыруда жетекші орынға ие болды - бұл, мысалы, сауалнама нәтижелерімен дәлелденді, The New Stack жүргізді:

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

сияқты K8 құрылғыларымен басқарылатын көптеген ірі шешімдер Amazon EKS, Azure AKS, Google GKE және басқалары оны қолдануға кеңес бере бастады.

Өнімділікке келетін болсақ, мұнда бәрі тамаша. Өз өнімін сынау кезінде Calico әзірлеу тобы секундына 50000 контейнер жасау жылдамдығымен 500 физикалық түйінде 20 XNUMX-нан астам контейнерді басқарып, астрономиялық өнімділікті көрсетті. Масштабтауда ешқандай проблемалар анықталған жоқ. Мұндай нәтижелер жарияланды бірінші нұсқасы туралы хабарландыруда. Өткізу қабілеті мен ресурстарды тұтынуға бағытталған тәуелсіз зерттеулер де Calico өнімділігі Фланелдікімен бірдей жақсы екенін растайды. Мысалы:

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Жоба өте жылдам дамып келеді, ол K8s, OpenShift, OpenStack басқарылатын танымал шешімдерде жұмысты қолдайды, кластерді қолдану арқылы Calico-ны қолдануға болады. коп, Service Mesh желілерінің құрылысына сілтемелер бар (міне мысал Istio-мен бірге қолданылады).

Каликомен жаттығу

Vanilla Kubernetes пайдаланудың жалпы жағдайында CNI орнату файлды пайдаланумен байланысты calico.yaml, ресми сайтынан жүктеп алынған, көмегімен kubectl apply -f.

Әдетте, плагиннің ағымдағы нұсқасы Kubernetes-тің соңғы 2-3 нұсқасымен үйлесімді: ескі нұсқалардағы жұмыс тексерілмеген және кепілдік берілмейді. Әзірлеушілердің айтуынша, Calico 3.10-дан жоғары Linux ядроларында CentOS 7, Ubuntu 16 немесе Debian 8, iptables немесе IPVS үстіне жұмыс істейді.

Қоршаған ортадағы оқшаулау

Жалпы түсіну үшін Calico белгілеуіндегі желі саясаттары стандарттылардан қалай ерекшеленетінін және ережелерді құру тәсілі олардың оқылу және конфигурация икемділігін қалай жеңілдететінін түсіну үшін қарапайым жағдайды қарастырайық:

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Кластерде орналастырылған 2 веб-бағдарлама бар: Node.js және PHP, олардың біреуі Redis пайдаланады. Node.js қосылымын сақтай отырып, PHP жүйесінен Redis жүйесіне кіруді блоктау үшін келесі саясатты қолданыңыз:

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

Негізінде Node.js сайтынан Redis портына кіріс трафикке рұқсат бердік. Және олар басқа ештеңеге тыйым салмағаны анық. NetworkPolicy пайда болғаннан кейін, басқаша көрсетілмесе, онда аталған барлық селекторлар оқшаулана бастайды. Дегенмен, оқшаулау ережелері селектормен қамтылмаған басқа нысандарға қолданылмайды.

Мысал пайдаланады apiVersion Kubernetes қораптан шықты, бірақ оны пайдалануға ештеңе кедергі келтірмейді Calico жеткізілімінен аттас ресурс. Ондағы синтаксис толығырақ, сондықтан жоғарыдағы жағдайға ережені келесі пішінде қайта жазу керек:

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

Тұрақты NetworkPolicy API арқылы барлық трафикке рұқсат беруге немесе бас тартуға арналған жоғарыда аталған құрылымдарда түсіну және есте сақтау қиын жақшалары бар құрылымдар бар. Calico жағдайында брандмауэр ережесінің логикасын керісінше өзгерту үшін жай ғана өзгертіңіз action: Allow туралы action: Deny.

Қоршаған орта бойынша оқшаулау

Енді бағдарлама Prometheus жүйесінде жинау және Grafana көмегімен әрі қарай талдау үшін бизнес өлшемдерін жасайтын жағдайды елестетіп көріңіз. Жүктеп салуда құпия деректер болуы мүмкін, олар әдепкі бойынша қайтадан жалпыға қолжетімді. Бұл деректерді бейтаныс көздерден жасырайық:

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Прометей, әдетте, бөлек қызмет көрсету ортасына орналастырылады - мысалда ол келесідей аттар кеңістігі болады:

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

өріс metadata.labels бұл кездейсоқ емес болып шықты. Жоғарыда айтылғандай, namespaceSelector (сонымен қатар podSelector) белгілермен жұмыс істейді. Сондықтан, көрсеткіштерді белгілі бір порттағы барлық қосқыштардан алуға рұқсат беру үшін белгінің қандай да бір түрін қосу (немесе барлардан алу), содан кейін келесідей конфигурацияны қолдану керек:

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

Егер сіз Calico саясаттарын пайдалансаңыз, синтаксис келесідей болады:

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

Жалпы алғанда, арнайы қажеттіліктер үшін саясаттардың осы түрлерін қосу арқылы кластердегі қолданбалардың жұмысына зиянды немесе кездейсоқ араласудан қорғай аласыз.

Calico жасаушылардың пікірінше, ең жақсы тәжірибе - бұл құжатта көрсетілген «Барлығын бұғаттаңыз және қажет нәрсені нақты ашыңыз» тәсілі. ресми құжаттама (басқалары ұқсас тәсілді ұстанады - атап айтқанда, в бұрын айтылған мақала).

Қосымша Calico нысандарын пайдалану

Calico API интерфейстерінің кеңейтілген жиынтығы арқылы сіз түйіндермен шектелмей, түйіндердің қолжетімділігін реттей алатыныңызды еске салайын. Келесі мысалда пайдалану GlobalNetworkPolicy кластердегі ICMP сұрауларын беру мүмкіндігі жабық (мысалы, түйіннен түйінге, қосқыштар арасындағы немесе түйіннен 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

Жоғарыда аталған жағдайда кластерлік түйіндердің ICMP арқылы бір-біріне «қол жеткізуі» мүмкін. Және бұл мәселе құралдар арқылы шешіледі GlobalNetworkPolicy, нысанға қолданылады 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 жағдайы

Соңында, стандартты саясат жиынтығы жеткіліксіз болған кезде кластерге жақын әрекеттесу жағдайында Calico функцияларын пайдаланудың нақты мысалын беремін. Веб-қосымшаға кіру үшін клиенттер VPN туннелін пайдаланады және бұл қатынас қатаң бақыланады және пайдалануға рұқсат етілген қызметтердің белгілі бір тізімімен шектеледі:

Кубернетестегі желіге арналған Calico: кіріспе және кішкене тәжірибе

Клиенттер VPN желісіне стандартты UDP порты 1194 арқылы қосылады және қосылған кезде подкасттар мен қызметтердің кластерлік ішкі желілеріне маршруттарды алады. Қайта іске қосу және мекенжайларды өзгерту кезінде қызметтерді жоғалтпау үшін бүкіл ішкі желілер итеріледі.

Конфигурациядағы порт стандартты болып табылады, ол қолданбаны конфигурациялау және оны Kubernetes кластеріне тасымалдау процесіне кейбір нюанстарды жүктейді. Мысалы, UDP үшін дәл сол AWS LoadBalancer өткен жылдың соңында аймақтардың шектеулі тізімінде пайда болды және NodePort оның барлық кластер түйіндерінде қайта бағытталуына байланысты пайдаланыла алмайды және сервер даналарының санын масштабтау мүмкін емес. ақауларға төзімділік мақсаттары. Оған қоса, порттардың әдепкі ауқымын өзгертуге тура келеді...

Ықтимал шешімдерді іздеу нәтижесінде мыналар таңдалды:

  1. VPN бар қосқыштар әр түйінге жоспарланған hostNetwork, яғни нақты IP-ге.
  2. Қызмет сыртта арқылы орналастырылады ClusterIP. Түйінде порт физикалық түрде орнатылады, оған сырттан шағын ескертпелермен қол жеткізуге болады (нақты IP мекенжайының шартты болуы).
  3. Бұршақ гүлінің түйінін анықтау біздің тарихымыздың ауқымынан тыс. Мен жай ғана айтамын, сіз қызметті түйінге мықтап «тырнақтай» аласыз немесе VPN қызметінің ағымдағы IP мекенжайын қадағалайтын және клиенттерде тіркелген DNS жазбаларын өңдейтін шағын бүйірлік қызметті жаза аласыз - кімде жеткілікті қиял болса.

Маршруттау тұрғысынан біз VPN клиентін VPN сервері шығарған IP мекенжайы бойынша бірегей түрде анықтай аламыз. Төменде жоғарыда аталған 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]

Мұнда 6379 портына қосылуға қатаң тыйым салынады, бірақ сонымен бірге ережелерді жасау кезінде жұмысы жиі зардап шегетін DNS қызметінің жұмысы сақталады. Өйткені, бұрын айтылғандай, селектор пайда болғанда, басқаша көрсетілмесе, оған әдепкі бас тарту саясаты қолданылады.

Нәтижелері

Осылайша, Calico кеңейтілген API көмегімен кластердегі және оның айналасындағы бағыттауды икемді конфигурациялауға және динамикалық түрде өзгертуге болады. Тұтастай алғанда, оны қолдану торғайларды зеңбірекпен ату сияқты көрінуі мүмкін, ал BGP және IP-IP туннельдері бар L3 желісін іске асыру тегіс желідегі қарапайым Kubernetes қондырғысында құбыжық көрінеді... Алайда, әйтпесе құрал өте өміршең және пайдалы болып көрінеді. .

Қауіпсіздік талаптарын қанағаттандыру үшін кластерді оқшаулау әрқашан мүмкін болмауы мүмкін және бұл жерде Calico (немесе ұқсас шешім) құтқаруға келеді. Осы мақалада келтірілген мысалдар (шағын өзгертулермен) AWS жүйесіндегі клиенттеріміздің бірнеше орнатуларында қолданылады.

PS

Біздің блогта да оқыңыз:

Ақпарат көзі: www.habr.com

пікір қалдыру