
Bu məqalənin məqsədi oxucunu Kubernetes-də şəbəkə qarşılıqlı əlaqələrinin və şəbəkə siyasətinin idarə olunmasının əsasları ilə tanış etməkdir, eləcə də standart imkanları artıran Calico adlı üçüncü tərəf plaginini təqdim etməkdir. Eyni zamanda, konfiqurasiyanın rahatlığı və real istifadə təcrübələrimizdən bəzi xüsusiyyətlər nümayiş etdiriləcək.
Kubernetes şəbəkə qurğusuna sürətli giriş
Kubernetes klasteri şəbəkəsiz təsəvvür edilə bilməz. Biz artıq onların əsasları ilə bağlı materiallar dərc etmişik: "» və «».
Bu məqalənin kontekstində qeyd etmək vacibdir ki, konteynerlər və düyünlər arasında şəbəkə bağlantısına Kubernetes özü cavabdeh deyil: bunun üçün müxtəlif CNI plaginləri (Container Networking Interface). Biz bu konsepsiyanı da .
Məsələn, belə plaginlərdən ən çox istifadə edilənlərdən biri — — klasterin bütün düyünləri arasında tam şəbəkə bağlantısı təmin edir, hər bir düyündə körpülər qaldıraraq ona bir alt şəbəkə təyin edir. Lakin tam və tənzimlənməyən əlçatanlıq həmişə faydalı olmur. Klasterdə müəyyən bir izolyasiya təmin etmək üçün firewall konfiqurasiyasına müdaxilə etmək lazımdır. Ümumiyyətlə, bu, həmin CNI-nin idarəsinə verilir, buna görə də iptables-dakı hər hansı bir üçüncü tərəf müdaxiləsi yanlış anlamaya və ya tamamilə görməməzliyə səbəb ola bilər.
Kubernetes klasterində şəbəkə siyasətlərinin idarə olunmasını təşkil etmək üçün "qutudan çıxarılan" mövcuddur. Bu qaynaq seçilmiş ad sahələrinə yayılır və bir tətbiqdən digərinə girişin ayrılması üçün qaydalar saxlayır. Həmçinin, müəyyən pod-lar, mühitlər (ad sahələri) və ya IP ünvanları arasında əlçatanlığı tənzimləməyə imkan verir:
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: 5978Bu, şəbəkə siyasətinin işləmə məntiqini anlamaq istəməməyə səbəb ola biləcək çox sadə olmayan bir nümunədir. Ancaq yükləri şəbəkə siyasətləri vasitəsilə yönləndirmə prinsipləri və metodları başa düşməyə çalışacağıq... Məntiqlidir ki, 2 tip trafik var: pod-a daxil olan (Ingress) və ondan çıxan (Egress).
Həqiqətən də, bu 2 kateqoriya hərəkət istiqamətinə görə ayrı-ayrılıqda şəbəkə siyasətini təşkil edir.

Həqiqətən də, bu 2 kateqoriya hərəkət istiqamətinə görə bölünür.
Növbəti məcburi atribut seçicidir; tətbiq olunan qaydanın kiminə aid olduğunu göstərir. Bu, pod (və ya pod qrupları) ya da mühit ola bilər (yəni ad boşluğu). Vacib detal: bu obyektlərin hər ikisi etiket içerməlidir (etiket ) — məhz bunlar siyasətlərin işlədiyi terminologiyada Kubernetes-də.
Yalnızca müəyyən bir etiket ilə birləşdirilmiş seçicilərin son sayı ilə yanaşı, "Hər şeyi icazə ver / qadağan et" kimi müxtəlif variantlarda qaydalar yazmaq imkanı da var. Bunun üçün aşağıdakı strukturlar istifadə olunur:
podSelector: {}
ingress: []
policyTypes:
- Ingress— bu nümunədə mühitdəki bütün pod-ların daxil olan trafiki qadağandır. Əks hərəkətə belə bir quruluşla nail olmaq mümkündür:
podSelector: {}
ingress:
- {}
policyTypes:
- IngressEynilə çıxan üçün:
podSelector: {}
policyTypes:
- Egress— onu deaktiv etmək üçün. Və aktiv etmək üçün belədir:
podSelector: {}
egress:
- {}
policyTypes:
- EgressCNI-plugin seçiminə geri dönərək, qeyd etmək lazımdır ki, hər şəbəkə plugin-i NetworkPolicy ilə işləməyə imkan vermir. Məsələn, artıq qeyd olunan Flannel şəbəkə siyasətlərini konfiqurasiya edə bilmir, bu barədə . Həmçinin alternativ — Açıq Mənbə layihəsi , Kubernetes-in şəbəkə siyasətləri haqqında standart API zımbasının əhəmiyyətli dərəcədə genişləndirir.

Calico ilə tanış olaq: nəzəriyyə
Calico plugin-i Flannel ilə inteqrasiya şəklində (alt layihə ) yaxud ayrıca istifadə oluna bilər, həm şəbəkə bağlılığını təmin edən funksiyaları, həm də əninə idarəetmə imkanlarını əhatə edir.
K8s-in "qutudan çıxmış" həllini və Calico-dan olan API zımbasını istifadə etmənin nələri təqdim etdiyini düşünək?
NetworkPolicy-də nələr var:
- siyasətlər mühitlə məhdudlaşır;
- siyasətlər etiketlərə işarələnmiş pod-lara tətbiq olunur;
- qaydalar pod-lara, mühitlərə və ya alt şəbəkələrə tətbiq oluna bilər;
- qaydalar protokollar, adlandırılmış və ya simvolik port göstərişlərini ehtiva edə bilər.
Calico bu funksiyaları necə artırır:
- siyasətlər hər hansı bir obyektə tətbiq oluna bilər: pod, konteyner, virtual maşın və ya interfeys;
- qaydalar konkret bir tədbiri (qadağa, icazə, qeyd etmək) ehtiva edə bilər;
- qaydaların hədəfi və ya mənbəyi port, port aralığı, protokollar, HTTP və ya ICMP atributları, IP və ya alt şəbəkə (4 və ya 6 nəsil), hər hansı seçicilər (düyün, ev sahibi, mühit);
- əlavə olaraq, DNAT parametrləri və trafikin keçirilməsi siyasətləri ilə trafikin keçirilməsini tənzimləmək olar.
Calico-nun GitHub’daki depozitindəki ilk komitələrin tarixi iyul 2016-cı ilə gedir və artıq bir il sonra layihə Kubernetes şəbəkə bağlılığında lider mövcudiyyət qazanmışdır — bunu, məsələn, The New Stack tərəfindən keçirilmiş sorğunun nəticələri göstərir, :

Bir çox böyük idarə olunan K8s həlləri, məsələn, , , və digərləri, onun istifadəsini tövsiyə etməyə başladılar.
Performans məsələsinə gəldikdə, hər şey mükəmməldir. Calico inkişaf komandası məhsulunu test edərkən 500 fiziki nodda 50000-dən çox konteyneri saniyədə 20 konteyner yarada biləcək şəkildə işə saldığını nümayiş etdirdi. Şkalalaşdırmada heç bir problem aşkar edilmədi. Bu cür nəticələr bəyan edilmişdi. Müstəqil tədqiqatlar, keçid qabiliyyəti və resurs istehlakının həcmini ölçən tədqiqatlar Calico-nun Flannel-a demək olar ki, bərabər performansını da təsdiq edir. :

Layihə çox sürətlə inkişaf edir, məşhur managed K8s, OpenShift, OpenStack həllərində dəstəklənir, Calico-nun klasterin yerləşdirilməsində istifadəsi mümkün olub , Service Mesh şəbəkələrinin yaradılması haqqında da məlumatlar var ( Istio ilə birgə istifadənin).
Calico ilə praktikalar
Vanil Kubernetes-da CNI qurulması ümumiyyətlə aşağıdakı faylın tətbiqinə əsaslanır calico.yaml, , kubectl apply -f.
Adətən, plugin-in cari versiyası Kubernetes-in son 2-3 versiyası ilə uyğun gəlir: daha köhnə versiyalarda işləməsi test edilmir və zəmanət verilmir. İnkişaf etdiricilərin bildirdiklərinə görə, Calico, CentOS 7, Ubuntu 16 ya da Debian 8 üzərində 3.10-dan yuxarı Linux kernelində işləyir, iptables ya da IPVS üzərində.
Mühit içində izolyasiya
Ümumi başa düşmək üçün şəbəkə siyasətinin Calico notasında standartlardan necə fərqləndiyini anlamaq üçün bir sadə vəziyyəti nəzərdən keçirək və qaydaların tərtib edilməsini necə asanlaşdırdığını başa düşək:

Klasterdə 2 veb tətbiqi yerləşdirilib: biri Node.js, digəri PHP-dır, bunlardan biri Redis istifadə edir. PHP-dən Redis-ə girişi bağlayaraq, Node.js ilə əlaqəni saxlamaq üçün yalnız aşağıdakı siyasəti tətbiq etmək kifayətdir:
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Əslində, Node.js-dən Redis portuna daxil olan trafiki icazə verdik. Və açıq şəkildə başqa şeylərə qadağa qoymadıq. NetworkPolicy meydana çıxdıqda, orada qeyd olunan bütün seletorlar izolyasiya olunmağa başlayır, əgər əksinə göstərilməyibsə. Eyni zamanda, izolyasiya qaydaları seletorla əhatə olunmayan digər obyektlərə tətbiq olunmur.
Nümunədə istifadə olunur apiVersion Kubernetes-dən "çıxan", amma Calico-nun təqdim etdiyi eyniadlı resursu istifadə etməyə heç bir əngəl yoxdur. 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 Yuxarıda qeyd olunan adımlardan istifadə edərək, adi NetworkPolicy API vasitəsilə bütün trafikin icazə verilməsi və ya qadağan edilməsi üçün istifadə olunan strukturlar, başa düşülməsi və yadda saxlanması çətin olan parantezli qurğulardan ibarətdir. Calico ilə firewall qaydasının iş prinsipi əksinə dəyişmək üçün sadəcə action: Allow buna action: Deny.
Mühitə görə izolyasiya
İndi bir vəziyyəti təsəvvür edək, burada proqram, Prometheus-da toplanması və sonradan Grafana vasitəsilə analizi üçün biznes metrikaları yaradır. İxracatda, standart olaraq hamıya açıq olan həssas məlumatlar ola bilər. Bu məlumatları xarici gözlərdən qoruyuruq:

Prometheus, ümumiyyətlə, ayrı bir xidmət mühitindədir - nümunədə bu, aşağıdakı növ namespace olacaq:
apiVersion: v1
kind: Namespace
metadata:
labels:
module: prometheus
name: kube-prometheus Alan metadata.labels burada təsadüfi deyil. Yuxarıda qeyd olunduğu kimi, namespaceSelector (kimi podSelector) etiketlərlə işləyir. Buna görə də, müəyyən bir portda bütün pod'lardan metrikaları almağa icazə vermək üçün, ya yeni bir etiket əlavə etməli (ya da mövcudlardan götürməli), daha sonra aşağıdakı konfiqurasiyanı tətbiq etməlisiniz:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-metrics-prom
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
module: prometheus
ports:
- protocol: TCP
port: 9100Calico siyasətləri təsviri üçün sintaksis isə belə olacaq:
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Ümumiyyətlə, bu cür siyasətləri spesifik ehtiyaclar üçün əlavə etməklə, klasterdə olan tətbiqlərin işinə zərərli və ya təsadüfi müdaxilədən qorumaq mümkündür.
Calico yaradıcılığının fikrincə, 'Hər şeyi qadağan et və mütləq lazım olanları aç' yanaşması ən yaxşı təcrübədir, bu da (həmçinin digər — xüsusilə, ).
Calico-nun əlavə obyektlərinin tətbiqi
Xatırlatmaq istəyirəm ki, genişləndirilmiş API komplekti vasitəsilə Calico, pod'larla məhdudlaşmadan node-ların əlçatanlığını tənzimləməyə imkan verir. Aşağıdakı nümunədə GlobalNetworkPolicy klasterdə ICMP sorğularının keçməsini qadağan edir (məsələn, pod'dan node'a, pod'lardan arasında və ya node-dan pod IP-ə pinglər):
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 Yuxarıda göstərilən nümunədə, klaster node-ları arasında ICMP ilə 'əlaqə' qurma imkanı qalır. Bu məsələ isə GlobalNetworkPolicy, varlığın tətbiqinə yönlənmiş 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 ilə bağlı vəziyyət
Nəhayət, standart siyasətlərin kifayət etmədiyi klaster ətrafı qarşılıqlı əlaqə üçün Calico funksiyalarının istifadəsi ilə tam real bir nümunəni təqdim edirəm. Müştərilər veb tətbiqinə VPN tuneli vasitəsilə daxil olurlar və bu giriş ciddi şəkildə müəyyən edilmiş icazə verilmiş xidmətlər siyahısı ilə məhdudlaşdırılır:

Müştərilər VPN-ə standart UDP 1194 portu vasitəsilə qoşulur və qoşularkən pod və xidmət klaster altşəbəkələrinə yol alır. Altşəbəkələr tamamilə təqdim edilir ki, serverlərin yenidən başladılması və adreslərin dəyişməsi zamanı xidmətlər itirilməsin.
Konfiqurasiyadakı port standartdır, bu, tətbiqin konfiqurasiyası və Kubernetes klasterinə köçürülməsi prosesinə müəyyən çətinliklər yaradır. Məsələn, eyni AWS LoadBalancer-i üçün UDP yalnız keçən ilin sonunda məhdud bölgələr siyahısında meydana çıxdı, NodePort-lardan istifadə edilə bilmir, çünki bunlar bütün klaster düyünlərinə yönləndirilir və server instansiyalarının sayını artırmaq üçün miqyası genişləndirmək mümkün deyil. Üstəlik, varsayılan olaraq seçilən portların diapazonunu dəyişmək məcburiyyətində qalacaqsınız...
Mümkün olan həllərin araşdırılması nəticəsində aşağıdakı seçim seçildi:
- VPN podları düyünə aşağıdakı rejimdə planlaşdırılır:
hostNetwork, yəni faktiki IP üzərində. - Xidmət, aşağıdakı vasitəsilə yerləşdirilir:
ClusterIP. Düyündə, müəyyən şərtlərlə (şərti olaraq real IP-un olması) xaricdən əlçatan olan bir port açılır. - Podun yerləşdiyi düyünü müəyyən etmək bizim hekayəmizin sərhədindən kənardadır. Yalnız onu qeyd edim ki, xidməti düyünə sərt bağlamaq və ya VPN xidmətinin aktiv IP ünvanını izləyən və müştərilərdə qeyd olunan DNS qeydlərini düzəldən kiçik bir sidecar xidmət yazmaq mümkündür — hər kəsin yaradıcılığına asılıdır.
Marşrutlaşdırma perspektivindən, VPN tərəfindən verilən IP ünvanı vasitəsilə müştəriyi dəqiq qeyd edə bilərik. Aşağıda — müştərinin yuxarıda qeyd olunmuş Redis xidmətlərinə girişini məhdudlaşdıran primitiv bir nümunə:
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]Port 6379 is strictly prohibited, but the DNS service remains operational, which often suffers from rule configurations. As previously mentioned, when a selector appears, a restrictive policy is applied by default unless stated otherwise.
Yekunlar
Thus, with the extended Calico API, you can flexibly configure and dynamically change routing within the cluster and around it. Generally, its usage can seem like using a cannon to shoot sparrows, and implementing an L3 network with BGP and IP-IP tunnels looks monstrous in a simple Kubernetes installation on a flat network... However, the tool appears quite viable and useful otherwise.
Cluster isolation to meet security requirements cannot always be implemented, and it is in such situations that Calico (or similar solutions) comes to the rescue. The examples provided in the article (with some modifications) are used in several installations by our clients in AWS.
P.S.
Blogumuzda oxuyun:
- «»;
- «Kubernetes-də Şəbəkənin Quruluşunu İllüstrasiya edən Rehber»: , ;
- «».
Mənbə: habr.com
