Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Հոդվածի նպատակն է ընթերցողին ծանոթացնել Kubernetes-ում ցանցային կապի և ցանցային քաղաքականության կառավարման հիմունքներին, ինչպես նաև երրորդ կողմի Calico հավելվածին, որն ընդլայնում է ստանդարտ հնարավորությունները: Ճանապարհին կազմաձևման հեշտությունը և որոշ առանձնահատկություններ կցուցադրվեն՝ օգտագործելով իրական օրինակներ մեր աշխատանքային փորձից:

Արագ ներածություն Kubernetes ցանցային սարքին

Kubernetes կլաստերը հնարավոր չէ պատկերացնել առանց ցանցի: Մենք արդեն հրապարակել ենք նյութեր դրանց հիմունքների վերաբերյալ.Կուբերնետեսում ցանցային կապի պատկերազարդ ուղեցույց"Եւ"Անվտանգության մասնագետների համար Kubernetes ցանցային քաղաքականության ներածություն.

Այս հոդվածի համատեքստում կարևոր է նշել, որ K8-ն ինքնին պատասխանատու չէ բեռնարկղերի և հանգույցների միջև ցանցային միացման համար. CNI պլագիններ (Բեռնարկղային ցանցային ինտերֆեյս): Ավելին այս հայեցակարգի մասին մենք նրանք էլ ինձ ասացին.

Օրինակ, այս պլագիններից ամենատարածվածն է Ֆլանել — ապահովում է ամբողջական ցանցային միացում բոլոր կլաստերային հանգույցների միջև՝ յուրաքանչյուր հանգույցի վրա կամուրջներ բարձրացնելով, դրան ենթացանց վերագրելով: Այնուամենայնիվ, ամբողջական և չկարգավորված հասանելիությունը միշտ չէ, որ ձեռնտու է: Կլաստերում որոշակի նվազագույն մեկուսացում ապահովելու համար անհրաժեշտ է միջամտել firewall-ի կազմաձևմանը: Ընդհանուր դեպքում այն ​​դրվում է նույն 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 տեսակ կա՝ պատիճ մտնել (Ingress) և դրանից ելք (Egress):

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Փաստորեն, քաղաքականությունը բաժանվում է այս 2 կատեգորիաների՝ ելնելով շարժման ուղղությունից։

Հաջորդ պահանջվող հատկանիշը ընտրիչն է; նա, ում նկատմամբ կիրառվում է կանոնը. Սա կարող է լինել պատիճ (կամ պատյանների խումբ) կամ միջավայր (այսինքն՝ անվանատարածք): Կարևոր մանրամասն. այս օբյեկտների երկու տեսակներն էլ պետք է պիտակ պարունակեն (պիտակ Kubernetes տերմինաբանությամբ) - սրանք են, որոնցով գործում են քաղաքական գործիչները:

Ի հավելումն որոշակի տեսակի պիտակի միավորված ընտրիչների սահմանափակ քանակի, հնարավոր է գրել կանոններ, ինչպիսիք են «Թույլատրել/մերժել ամեն ինչ/բոլորին» տարբեր տարբերակներով: Այդ նպատակով օգտագործվում են ձևի կոնստրուկցիաներ.

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

— այս օրինակում շրջակա միջավայրի բոլոր պատյաններն արգելափակված են մուտքային տրաֆիկից: Հակառակ վարքագիծը կարելի է ձեռք բերել հետևյալ կառուցվածքով.

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

Նմանապես արտագնա համար.

  podSelector: {}
  policyTypes:
  - Egress

- անջատել: Եվ ահա թե ինչ պետք է ներառել.

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

Վերադառնալով կլաստերի համար CNI plugin-ի ընտրությանը, հարկ է նշել, որ ոչ բոլոր ցանցային հավելվածներն են աջակցում NetworkPolicy-ին. Օրինակ, արդեն նշված Flannel-ը չգիտի, թե ինչպես կարգավորել ցանցային քաղաքականությունը, որը ուղղակիորեն ասված է պաշտոնական պահոցում։ Այնտեղ նշվում է նաև այլընտրանք՝ բաց կոդով նախագիծ Calico- ն, որը զգալիորեն ընդլայնում է Kubernetes API-ների ստանդարտ փաթեթը ցանցային քաղաքականության առումով։

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Ծանոթանալ Calico-ին. տեսություն

Calico plugin-ը կարող է օգտագործվել Flannel-ի հետ ինտեգրվելու (ենթանախագծ Նեղուց) կամ ինքնուրույն՝ ընդգրկելով և՛ ցանցային կապի, և՛ հասանելիության կառավարման հնարավորությունները:

Ի՞նչ հնարավորություններ է տալիս K8s «boxed» լուծման և Calico-ի API հավաքածուի օգտագործումը:

Ահա թե ինչ է ներկառուցված NetworkPolicy-ում.

  • քաղաքական գործիչները սահմանափակված են շրջակա միջավայրով.
  • քաղաքականությունը կիրառվում է պիտակներով նշված պատյանների վրա.
  • կանոնները կարող են կիրառվել պատիճների, միջավայրերի կամ ենթացանցերի վրա.
  • կանոնները կարող են պարունակել արձանագրություններ, անվանված կամ խորհրդանշական պորտի բնութագրեր:

Ահա թե ինչպես է Calico-ն ընդլայնում այս գործառույթները.

  • քաղաքականությունը կարող է կիրառվել ցանկացած օբյեկտի վրա՝ պատիճ, կոնտեյներ, վիրտուալ մեքենա կամ ինտերֆեյս;
  • կանոնները կարող են պարունակել կոնկրետ գործողություն (արգելում, թույլտվություն, անտառահատում);
  • Կանոնների թիրախը կամ աղբյուրը կարող է լինել նավահանգիստ, մի շարք նավահանգիստներ, արձանագրություններ, HTTP կամ ICMP ատրիբուտներ, IP կամ ենթացանց (4-րդ կամ 6-րդ սերունդ), ցանկացած ընտրիչ (հանգույցներ, հոսթեր, միջավայրեր);
  • Բացի այդ, դուք կարող եք կարգավորել երթևեկության անցումը` օգտագործելով DNAT կարգավորումները և երթևեկության վերահասցեավորման քաղաքականությունը:

Calico-ի պահոցում GitHub-ի առաջին պարտավորությունները թվագրվում են 2016 թվականի հուլիսին, իսկ մեկ տարի անց նախագիծը առաջատար դիրք է գրավել Kubernetes ցանցային կապի կազմակերպման գործում. վարում է The New Stack-ը:

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Շատ խոշոր կառավարվող լուծումներ K8-ներով, ինչպիսիք են Amazon EKS, Azure AKS, Google GKE իսկ մյուսները սկսեցին խորհուրդ տալ այն օգտագործելու համար:

Ինչ վերաբերում է կատարմանը, այստեղ ամեն ինչ հիանալի է։ Իր արտադրանքը փորձարկելիս Calico-ի մշակման թիմը ցուցադրել է աստղագիտական ​​կատարում՝ գործարկելով ավելի քան 50000 կոնտեյներ 500 ֆիզիկական հանգույցների վրա՝ վայրկյանում 20 կոնտեյներ ստեղծելու արագությամբ: Սանդղակի հետ կապված խնդիրներ չեն հայտնաբերվել: Նման արդյունքներ հայտարարվել են արդեն առաջին տարբերակի հայտարարության ժամանակ։ Անկախ ուսումնասիրությունները, որոնք կենտրոնանում են թողունակության և ռեսուրսների սպառման վրա, նույնպես հաստատում են, որ Calico-ի կատարումը գրեթե նույնքան լավն է, որքան Flannel-ը: Օրինակ:

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Նախագիծը շատ արագ է զարգանում, այն աջակցում է K8-ի, OpenShift-ի, OpenStack-ի կառավարվող հանրաճանաչ լուծումների աշխատանքին, հնարավոր է Calico-ն օգտագործել կլաստերի տեղակայման ժամանակ՝ օգտագործելով կոպ, կան հղումներ Service Mesh ցանցերի կառուցմանը (ահա մի օրինակ օգտագործվում է Istio-ի հետ համատեղ):

Պարապեք Calico-ի հետ

Վանիլային Kubernetes-ի օգտագործման ընդհանուր դեպքում CNI-ի տեղադրումը հանգում է ֆայլի օգտագործմանը calico.yaml, ներբեռնված է պաշտոնական կայքից, օգտագործելով kubectl apply -f.

Որպես կանոն, plugin-ի ընթացիկ տարբերակը համատեղելի է Kubernetes-ի վերջին 2-3 տարբերակների հետ. հին տարբերակներում աշխատանքը չի փորձարկվում և երաշխավորված չէ: Ըստ մշակողների, Calico-ն աշխատում է 3.10-ից բարձր Linux միջուկներով, որոնք աշխատում են CentOS 7, Ubuntu 16 կամ Debian 8, iptables-ի կամ IPVS-ի վերևում:

Մեկուսացում շրջակա միջավայրի ներսում

Ընդհանուր հասկանալու համար եկեք նայենք մի պարզ դեպքի՝ հասկանալու համար, թե ինչպես են Calico-ի նշագրման ցանցային քաղաքականությունները տարբերվում ստանդարտներից և ինչպես է կանոնների ստեղծման մոտեցումը պարզեցնում դրանց ընթեռնելիությունը և կազմաձևման ճկունությունը.

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Կլաստերում տեղակայված են 2 վեբ հավելվածներ՝ Node.js-ում և PHP-ում, որոնցից մեկն օգտագործում է Redis: PHP-ից Redis-ի մուտքն արգելափակելու համար՝ միաժամանակ պահպանելով կապը Node.js-ի հետ, պարզապես կիրառեք հետևյալ քաղաքականությունը.

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

Հիմնականում մենք թույլ տվեցինք մուտքային երթևեկությունը դեպի Redis նավահանգիստ Node.js-ից: Եվ նրանք ակնհայտորեն այլ բան չէին արգելում։ 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-ի դեպքում, firewall-ի կանոնի տրամաբանությունը հակառակը փոխելու համար, ուղղակի փոխեք action: Allow մասին action: Deny.

Մեկուսացում ըստ շրջակա միջավայրի

Այժմ պատկերացրեք մի իրավիճակ, երբ հավելվածը ստեղծում է բիզնես չափումներ Պրոմեթևսում հավաքագրման և հետագա վերլուծության համար՝ օգտագործելով Grafana-ն: Վերբեռնումը կարող է պարունակել զգայուն տվյալներ, որոնք լռելյայն կրկին տեսանելի են հանրությանը: Եկեք թաքցնենք այս տվյալները հետաքրքրասեր աչքերից.

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Պրոմեթևսը, որպես կանոն, տեղադրվում է առանձին սպասարկման միջավայրում. օրինակում դա կլինի այսպիսի անվանատարածք.

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 հարցումները կլաստերում փոխանցելու հնարավորությունը փակ է (օրինակ՝ ping-ը պատիճից հանգույց, բլոկների միջև կամ հանգույցից 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 թունել, և այդ մուտքը խստորեն վերահսկվում է և սահմանափակվում է օգտագործման համար թույլատրված ծառայությունների հատուկ ցանկով.

Կալիկո Kubernetes-ում ցանցերի համար. ներածություն և մի փոքր փորձ

Հաճախորդները միանում են VPN-ին ստանդարտ UDP 1194 պորտի միջոցով և, երբ միացված են, ստանում են երթուղիներ դեպի բլոկների և ծառայությունների կլաստերային ենթացանցեր: Ամբողջ ենթացանցերը մղվում են, որպեսզի չկորցնեն ծառայությունները վերագործարկման և հասցեների փոփոխության ժամանակ:

Կազմաձևում գտնվող պորտը ստանդարտ է, ինչը որոշ նրբերանգներ է պարտադրում հավելվածի կազմաձևման և այն Kubernetes կլաստերին փոխանցելու գործընթացին: Օրինակ, նույն AWS-ում LoadBalancer-ը UDP-ի համար հայտնվեց բառացիորեն անցած տարվա վերջին՝ տարածաշրջանների սահմանափակ ցանկում, և 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

Կարդացեք նաև մեր բլոգում.

Source: www.habr.com

Добавить комментарий