
Այս հոդվածի նպատակը ընթերց անգամ ծանոթացնելն է Kubernetes-ում նախատեսված ցանցային փոխազդեցության և ցանցային քաղաքականությունների կառավարման հիմնական սկզբունքներին, ինչպես նաև Calico երրորդ կողմի լրացքում, որն ընդլայնում է ստանդարտ հնարավորությունները: Փորձագիտական օրինակներով կներկայացվի հարմարության կոնֆիգուրացիան և որոշ առանձնահատկություններ:
Կարճ ներկայացում Kubernetes-ի ցանցային սարքի վերաբերյալ
Kubernetes կլաստերն անհնար է պատկերացնել առանց ցանցի: Մենք արդեն հրապարակել ենք դրանց հիմունքների մասին նյութեր: «» և «».
Այս հոդվածի համատեքստում կարևոր է նշել, որ ցանցային կապը կոնտեյներների և հանգույցների միջև ապահովում է ոչ թե K8s-ը, այլ տարբեր CNI լրացումներ (Container Networking Interface). Մենք այդ կոնցեպտի մասին նույնպես պատմել ենք: .
Flannel Եվ «ճիշտ արկղից» ցանցային քաղաքականությունների կառավարման կազմակերպման համար Kubernetes կլաստերում տրամադրվում է
NetworkPolicy API 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): Ինձնից, այս երկու կատեգորայի հիման վրա էլ բաժանվում է քաղաքականություն։
Ֆիզիկապես պարտադիր հատկանիշներն են՝ ընտրողը; նա, ում կիրառվում է կանոնը։ Սա կարող է լինել pod (կամ pod-երի խումբ) կամ միջավայր (այսինքն՝ անվան տարածք): Տարածական մանրամասներ՝ երկուսն էլ պարտադիր պետք է պարունակեն պիտակ (

label
Հաջորդ պարտադիր ատրիբուտը ընտրիչն է, այն, ինչին կիրառվում է կանոնը։ Սա կարող է լինել pod (կամ pod-երի խումբ) կամ միջավայր (սա նշանակում է անունների տարածք)։ Կարևոր Detail՝ այս երկու տեսակի օբյեկտները պարտադիր պետք է ունենան պիտակ (label Kubernetes-ի terminologiyada) — հենց դրանք են, որոնցով կառավարում են քաղաքականություններ։
Վերջնական ընտրության թվի սելեկտորներից, որոնք միավորվում են որոշ բացականչությամբ, կա նաև գործիքի հնարավորությունը՝ «Թույլատրել/արգելել ամեն ինչ/բոլորին» տարբերակներով։ Dafür verwendet Methoden wie:
podSelector: {}
ingress: []
policyTypes:
- Ingress— այս օրինակով բոլոր pod-երին հասանելիությունը փակվում է։ Ընդհանուր գործում հակառակ վարքագիծ ստանալու համար կարելի է օգտագործել հետևյալ կառուցվածքը:
podSelector: {}
ingress:
- {}
policyTypes:
- IngressՆման կերպ ելքայինի համար:
podSelector: {}
policyTypes:
- Egress— նրա փակման համար։ Իսկ ահա ինչ-որ բան ընդգրկելու համար:
podSelector: {}
egress:
- {}
policyTypes:
- EgressՎերադառնալով CNI-plugin-ի ընտրության հարցին, հարկ է նշել, որ չի կարելի ասել, որ յուրաքանչյուր ցանցային plugin աջակցում է NetworkPolicy-ի հետ աշխատելուն։ Օրինակ, արդեն նշված Flannel-ը չի կարող config անել ցանցային քաղաքականություններ, ինչի մասին официальном хранилище։ Там же упоминается альтернатива — Open Source-проект , который значительно расширяет стандартный набор API Kubernetes в плане сетевых политик.

Calico-ով ծանոթանում ենք՝ տեսություն
Calico plugin-ը կարող է օգտագործվել Flannel-ի հետ ինտեգրված (մասնաճյուղի ) կամ ինքնուրույն, ընդգրկելով ինչպես ցանցային կապի ապահովման, այնպես էլ հասանելիության կառավարման ֆունկցիաներ։
Որպեսզի Calico-ի API-ների «տուփային» որոշումների օգտագործումը ինչ հնարավորություններ է տալիս K8s-ի վրա:
Ահա թե ինչն է ինտեգրված NetworkPolicy-ում:
- քաղաքականությունները սահմանափակված են միջավայրի շրջապատներով;
- քաղաքականությունները կիրառվում են լեյբոլերով նշված pod-ների նկատմամբ;
- կարգերը կարելի է կիրառել pod-ներին, միջավայրերին կամ ենթանցքերին;
- կարգերը կարող են պարունակել պրոտոկոլներ, անվանված կամ խորհրդանշանային պորտերի ցույցեր։
Նկատեք, թե ինչպես է Calico-ն ընդլայնում այս ֆունկցիաները:
- քաղաքականությունները կարող են կիրառվել ցանկացած օբյեկտի համար՝ pod, կոնտեյներ, վիրտուալ մեքենա կամ ինտերֆեյս;
- կարգերը կարող են պարունակել կոնկրետ գործողություն (արգելք, թույլտվություն, պատճառով պատասխանատու)։
- Կամ որպես կարգ կամ աղբյուրը կարող է լինել պորտը, պորտերի տիրույթը, պրոտոկոլները, HTTP կամ ICMP հատկությունները, IP կամ ենթանցք (4 կամ 6-րդ սերունդ), ցանկացած սելեկտորներ (հուշարձանների, հոստերի, միջավայրերի);
- Լրացուցիչ հնարավոր է կարգավորել միջանցքով երթևեկությունը DNAT կարգավորումների և երթևեկության քաղաքականությունների միջոցով։
Calico-ի GitHub-ում առաջին կոմիտները թվագրվում են 2016-ի հուլիսին, իսկ արդեն մեկ տարի անց նախագիծը զբաղեցրեց առաջնորդող դիրքեր Kubernetes-ի ցանցային կապի կազմակերպման մեջ՝ ինչպես վկայում են, օրինակ, The New Stack-ի հարցումները, :

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

Ծրագիրը շատ արագ զարգանում է, աջակցում է հայտնի լուծումների – managed K8s, OpenShift, OpenStack, ունի Calico-ն արագացնելիս իրացման հնարավորություն , հանդիպում են Service Mesh ցանցերի կառուցման նշումներ ( Istio-ի հետ համատեղ օգտագործելու):
Calico-ի փորձը
Ընդհանուր առմամբ, վանիլ Kubernetes-ի օգտագործման դեպքում CNI-ի տեղադրմանը վերաբերում է calico.yaml ֆայլի կիրառումը, որն անհրաժեշտ է ներբեռնել պաշտոնական կայքից, kubectl apply -f Բոլոր դեպքերում, ընթացիկ պլագինի նոր տարբերակը սովորաբար համատեղելի է Kubernetes-ի վերջին 2-3 տարբերություններով. ավելի հին տարբերություններում աշխատանքի ամրագրումն ու երաշխավորումը չի իրականացվում: Աշխատակազմի հայտարարությունների համաձայն, Calico-ն աշխատում է Linux միջուկով, որը ավելի բարձր է 3.10 CentOS 7, Ubuntu 16 կամ Debian 8-ի ներքո, iptables կամ IPVS մակերևույթին:.
Կրիտիկայում
Ունենալով ընդհանուր պատկերացում, եկեք դիտարկենք պարզ դեպք, որպեսզի հասկանալ, թե ինչով են Calico-ի ցանցային քաղաքականությունները տարբերվում ստանդարտներից և ինչպես կանոնակարգի կազմումը պարզեցնում է դրանց ընթերցելիությունը և կարգարկվածությունը:
Կլաստերում տեղադրված են 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
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-ով, արգելակման կանոնի տրամաբանությունը հակառակ ուղղությամբ փոխելու համար բավարար է փոխել գործողություն: Թույլատրել ըստ գործողություն: արգելել.
Չափորոշիչներով առանձնացնել
Հիմա պատկերացնենք մի իրավիճակ, երբ ծրագիրը բիզնես մետրիկաներ է արտադրում Prometheus համակարգում հավաքելու և դրանք հետագա վերլուծության համար Grafana-ով: Ապրանքներում կարող է ներառվել զգայուն տվյալներ, որոնք ըստ այնմ հասանելի են հանրային դիտման: Վերջին մոռացած մթերքները կփակենք սկզբում այս տվյալներից:

Prometheus-ը, որպես կանոն, տեղակայված է առանձին ծառայողական սեռում — օրինակ, դա կլինի հետևյալ տեսակի namespace:
apiVersion: v1
kind: Namespace
metadata:
labels:
module: prometheus
name: kube-prometheus Դաշտը metadata.labels այստեղ դա պատահական չէ: Ինչպես արդեն նշվել է վերևում, namespaceSelector (ինչպես և podSelector) աշխատում են լեյբլներով: Ինչպես ուներ մետրիկները բոլոր pod-ներից որոշակի պորտում հավաքելու համար, ստիպված կլինեք ավելացնել որևէ լեյբլ (կամ վերցնել առկաներից), այնուհետև կիրառեք նման կարգավորում:
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-ի միջոցով հնարավոր է կարգավորել узловերի հասանելիությունը, առանց pod-ների սահմանափակման: Վ siguiente օրինակով, մեկ GlobalNetworkPolicy արգելվում է ICMP-հարցումների անցնում կլաստերում (օրինակ, ping-եր pod-ից узловի, pod-ների միջև կամ узловից IP pod-ի վրա):
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-տունություն և այս հասանելիությունը խիստ վերահսկվում է` օգտագործման թույլատրված ծառայությունների կոնկրետ ցանկով:

Հաճախորդները միանում են VPN-ին ստանդարտ UDP-պորտ 1194-ի միջոցով և միանալու պահին ստանում են միջանցքներ տնակային ենթաճյուղերի ու ծառայությունների համար: Միջանձնային հասցեները ամբողջությամբ բաշխվում են, որպեսզի չկորցնեն ծառայությունները կրկին վերագործարկումների և հասցեների փոփոխությունների ժամանակ:
Պորտը կոնֆիգուրացվել է ստանդարտ, ինչը որոշակի հատկանիշներ է ավելացնում ծրագրի կոնֆիգուրացման գործընթացին և դրա տեղափոխմանը Kubernetes-կլաստեր: Օրինակ, AWS LoadBalancer-ում UDP-ն հայտնվել է միայն անցյալ տարվա վերջում մի սահմանափակ տարածաշրջանում, իսկ NodePort-ը չի կարելի օգտագործել, քանի որ դա փոխանցվում է բոլոր կլաստերների узлу և անհնար է մետ ապային չկախվածությամբ ծառայությունների ինտերֆեյսների քանակը: Եվ պետք է փոխել նախկինում ընտրված պորտերի տպաքանակը:
Հնարավոր լուծումների վերանայման արդյունքում հետևյալը ընտրվեց:
- VPN-իPods-ն ծրագրավորվում են узлу եզակի միջավայրում
hostNetwork, այսինքն՝ իրական IP-ով: - Ծառայությունը ներկայացվում է դրսում
ClusterIP. Узлу հասարակաց տեղադրվում է պորտ, որը հասանելի է դրսից որոշակի նկատառումներով (ստեղծված իրական IP-հասցեների առկայություն): - Uzlu, որտեղ կազմավորվել է pod-ը, մեր պատմության սահմաններից դուրս է: Պետք է նշել, որ ծառայությունը հնարավոր է պինդ կապել узлу կամ գրել մի փոքր sidecar-ծառայություն, որը հետևելու է VPN-ծառայության ներկայիս IP-հասցեին և փոփոխություններ կատարում DNS-գրառումներին, որոնք առաջ ետ են տվել հաճախորդներին` ով ինչի կարող է երևակայել:
Ռուսհավաքման տեսանկյունից մենք կարող ենք անհամեմատելիորեն հաստատել հաճախորդին VPN-ի միջոցով նրա IP-հասցեի հիման վրա, որը տրամադրվում է VPN-ի ծառի կողմից: Ստորև ներկայացված է պարզ օրինակ մի հաճախորդի հասանելիության սահմանափակման վրա, որի ծառայությունները, օրինակ, հայտարարել են 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 ծառայության աշխատանքը պահպանվում է, որի գործունեությունը հաճախ տուժում է կանոնների կազմման ժամանակ: Քանի որ, ինչպես արդեն նշվել է, եթե ընտրիչը առաջանում է, այն ենթարկվում է վաղ Default արգելման քաղաքականության, եթե այլ կերպ չի նշվել:
Եզրակացություններ
Այսպիսով, Calico-ի ընդլայնված API-ի միջոցով հնարավոր է ճկուն կարգավորումներ կատարել և դինամիկ կերպով փոխել մասշտաբը կլաստերում և դրա շուրջ: Ընդհանուր առմամբ, դրա օգտագործումը կարող է նմանվել գնդակի արձակում, իսկ L3 ցանցի ներդրումը BGP- և IP-IP-տուննեյններով պարզապես հսկայական է սովորական Kubernetes-instsallում հարթ ցանցի դեպքում... Այնուամենայնիվ, մյուս կողմից գործի միջոցը շատ կենսունակ և օգտակար է:
Կլաստերի մեկուսացումը անվտանգություն պահպանելու պահանջները իրականացնելը միշտ չէ, որ հնարավոր է, ու հենց այդ դեպքերում Calico-ն (օրինակ, նման լուծում) կարող է օգտակար լինել: Գործս օրինակները, որոնք ներկայացված են հոդվածում (քիչ փոփոխություններով) կիրառվում են մեր հաճախորդների մի քանի ինստալացիաներում AWS-ում:
P.S.
Նաեւ կարդացեք մեր բլոգում:
- «»;
- «Ցուցանակաձև ուղեցույց Kubernetes ցանցի կառուցվածքի համար»: , ;
- «».
Ընտանիք: habr.com
