
Pozn. prekl.: Autor článku – Reuven Harrison – má viac ako 20 rokov skúseností s vývojom softvéru a v súčasnosti je technickým riaditeľom a spoluzakladateľom spoločnosti Tufin, ktorá vytvára riešenia na správu bezpečnostných politík. Keďže sieťové politiky Kubernetes považuje za dosť silný nástroj na segmentáciu siete v klastre, zároveň si myslí, že ich aplikácia v praxi nie je taká jednoduchá. Tento materiál (relatívne rozsiahly) je určený na zvýšenie povedomia odborníkov v tejto oblasti a pomoc pri vytváraní potrebných konfigurácií.
V súčasnosti si stále viac firiem vyberá Kubernetes na spúšťanie svojich aplikácií. Záujem o tento softvér je taký vysoký, že niektorí ho nazývajú „novým operačným systémom pre dátové centrá“. Postupne sa Kubernetes (alebo k8s) začína vnímať ako kriticky dôležitá súčasť podnikania, ktorá si vyžaduje organizáciu vyspelých obchodných procesov, vrátane zaisťovania sieťovej bezpečnosti.
Pre odborníkov na bezpečnosť, ktorých zmiatlo zaobchádzanie s Kubernetes, môže byť skutočným prekvapením predvolené pravidlo tejto platformy: povoliť všetko.
Tento sprievodca pomôže porozumieť vnútornej štruktúre sieťových politík; pochopiť, v čom sa líšia od pravidiel pre bežné firewally. Tiež sa dozviete o niektorých úskalí a dostanete odporúčania, ktoré pomôžu chrániť aplikácie v Kubernetes.
Sieťové politiky Kubernetes
Mechanizmus sieťových politík Kubernetes umožňuje riadiť interakciu nasadených aplikácií na platforme na sieťovej úrovni (tretej v modeli OSI). Sieťové politiky nemajú niektoré pokročilé funkcie moderných firewallov, ako je kontrola na 7. úrovni OSI a detekcia hrozieb, avšak poskytujú základnú úroveň sieťovej bezpečnosti, čo je dobrý východiskový bod.
Sieťové politiky kontrolujú komunikáciu medzi podmi
Záťaže v Kubernetes sa rozdeľujú na pod'ov, ktoré pozostávajú z jedného alebo viacerých kontajnerov spoločne nasadených. Kubernetes priraďuje každému pod'u IP adresu prístupnú z iných pod'ov. Sieťové politiky Kubernetes definujú prístupové práva pre skupiny pod'ov rovnakým spôsobom, akým sa v cloude používajú bezpečnostné skupiny na správu prístupu k virtuálnym strojom.
Definícia sieťových politík
Rovnako ako ostatné zdroje Kubernetes, sieťové politiky sú definované v jazyku YAML. V nižšie uvedenom príklade má aplikácia balance prístup k postgres:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres
namespace: default
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- podSelector:
matchLabels:
app: balance
policyTypes:
- Ingress 
(Pozn. prekl.: tento snímok, ako aj všetky nasledujúce podobné, nebol vytvorený natívnymi nástrojmi Kubernetes, ale pomocou nástroja Tufin Orca, za ktorým stojí spoločnosť autora pôvodného článku a ktorý je spomenutý na konci materiálu.)
Na definovanie vlastnej sieťovej politiky budú potrebné základné znalosti jazyka YAML. Tento jazyk je založený na odsadení (určenom medzerami, nie tabulátormi). Prvok s odsadením patrí najbližšiemu prvku s odsadením nad ním. Nový prvok zoznamu sa začína pomlčkou, všetky ostatné prvky majú podobu kľúč-hodnota.
Po opise politiky v YAML použite , aby ste ju vytvorili v klastri:
kubectl create -f policy.yamlŠpecifikácia sieťovej politiky
Špecifikácia sieťovej politiky Kubernetes obsahuje štyri prvky:
-
podSelector: určuje pod' y, ktorých sa táto politika týka (ciele) — povinný; -
policyTypes: uvádza, aké typy politík sú zahrnuté v tejto: ingress a/alebo egress — voliteľný, ale odporúčam ho jasne uvádzať vo všetkých prípadoch; -
ingress: určuje povolený prichádzajúci prenos do cieľových pod'ov — voliteľný; -
egress: určuje povolený odchádzajúci prenos z cieľových pod'ov — voliteľný.
Príklad prevzatý z webu Kubernetes (nahradil som role na app), ukazuje, ako sa používajú všetky štyri prvky:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector: # <<<
matchLabels:
app: 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 

Vezmite na vedomie, že všetky štyri prvky nie sú povinné. Povinný je iba podSelector, ostatné parametre môžete použiť podľa potreby.
Ak vynecháte policyTypes, politika sa bude interpretovať nasledovne:
- Predpokladá sa, že určuje prichádzajúcu (ingress) stranu. Ak v politike nie sú explicitne uvedené žiadne pokyny, systém bude predpokladať, že všetok prenos je zakázaný.
- Správanie na odchádzajúcej (egress) strane bude závisieť od prítomnosti alebo absencie príslušného parametra egress.
Aby ste predišli chybám, odporúčam vždy explicitne uvádzať policyTypes.
V súlade s vyššie uvedenou logikou, ak sú parametre ingress a/alebo egress vynechané, politika zakáže celý prenos (pozri „Čisté pravidlo“ nižšie).
Predvolené pravidlo je povoliť
Ak nie sú definované žiadne politiky, Kubernetes predvolene povoľuje celý prenos. Všetky pod’y si môžu voľne vymieňať informácie. Z hľadiska bezpečnosti sa to môže zdať nelogické, ale pamätajte na to, že Kubernetes bol pôvodne vytvorený vývojármi s cieľom zabezpečiť interakciu aplikácií. Sieťové politiky boli pridané neskôr.
Namespaces
Namespaces (priestory mien) sú mechanizmom kolektívnej práce Kubernetes. Slúžia na izoláciu logických prostredí navzájom, pričom výmena údajov medzi priestormi je predvolene povolená.
Rovnako ako väčšina komponentov Kubernetes, sieťové politiky sa nachádzajú v určitom namespace. V bloku metadata môžete uviesť, ktorému konkrétnemu priestoru patrí politika:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: my-namespace # <<<
spec:
... Ak namespace v metadátach explicitne nie je uvedený, systém použije namespace uvedené v kubectl (predvolene namespace=default):
kubectl apply -n my-namespace -f namespace.yamlOdporúčam explicitne uvádzať namespace, ak píšete politiku, ktorá je určená pre viacero oborov.
Hlavný prvok podSelector v politike si vyberá pod’y z oboru, ku ktorému patrí politika (nemá prístup k pod’om z iného oboru).
Podobne podSelector’y v blokoch ingress a egress môžu vyberať pod’y len zo svojho oboru, pokiaľ ich samozrejme nespojíte pomocou namespaceSelector (o tom sa bude hovoriť v sekcii „Filtrovanie podľa oborov a pod’ov“).
Pravidlá pomenovávania politík
Názvy politík sú jedinečné v rámci jedného oboru. Dve politiky s rovnakým názvom v jednom obore nemôžu existovať, ale môžu existovať politiky s rovnakými názvami v rôznych oboroch. Toto je praktické, keď chcete opätovne aplikovať tú istú politiku na viaceré obory.
Osobitne sa mi páči jeden zo spôsobov pomenovávania. Spočíva v tom, že kombinuje názov oboru s cieľovými pod’y. Napríklad:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres # <<<
namespace: default
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- podSelector:
matchLabels:
app: admin
policyTypes:
- Ingress 
Štítky
K objektom Kubernetes, ako sú pod’y a obory, je možné pripojiť vlastné štítky. Štítky (labels — tagy) sú ekvivalentom tagov v cloude. Sieťové politiky Kubernetes používajú štítky na výber pod'y, na ktoré sa aplikujú:
podSelector:
matchLabels:
role: db… alebo oborov, na ktoré sa aplikujú. V tomto príklade sú vyberané všetky pod’y v oboroch s príslušnými štítkami:
namespaceSelector:
matchLabels:
project: myproject Jedno varovanie: pri použití namespaceSelector sa uistite, že vyberané obory obsahujú požadovaný štítok. Majte na pamäti, že vstavané obory, ako napríklad default a kube-system, predvolene neobsahujú žiadne štítky.
Pridať štítok k oboru možno nasledovne:
kubectl label namespace default namespace=default Pri tom namespace v sekcii metadata musí odkazovať na skutočné meno oboru, a nie na štítok:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default # <<<
spec:
...Zdroj a adresát
Politiky pre firewall sa skladajú z pravidiel so zdrojmi a adresátmi. Sieťové politiky Kubernetes sú určené pre cieľ — súbor podov, na ktoré sa aplikujú, a následne nastavujú pravidlá pre prichádzajúci (ingress) a/alebo odchádzajúci (egress) sieťový traffic. V našom príklade bude cieľom politiky všetky pody v namespace default s labelom s kľúčom app a hodnotou db.:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
app: 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 

Podrobnosť ingress v tejto politike otvára prichádzajúci traffic k cieľovým podom. Inými slovami, ingress funguje ako zdroj, a cieľ je príslušným adresátom. Analogicky je egress adresátom, a cieľ je jeho zdrojom.

To zodpovedá dvom pravidlám pre firewall: Ingress → Cieľ; Cieľ → Egress.
Egress a DNS (dôležité!)
Obmedzovaním odchádzajúceho trafficu, venujte osobitnú pozornosť DNS — Kubernetes používa túto službu na mapovanie služieb na IP adresy. Napríklad, nasledujúca politika nebude fungovať, pretože ste nepripustili aplikáciu balance pristupovať k DNS:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
egress:
- to:
- podSelector:
matchLabels:
app: postgres
policyTypes:
- Egress 
Môžete to opraviť umožnením prístupu k DNS službe:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
egress:
- to:
- podSelector:
matchLabels:
app: postgres
- to: # <<<
ports: # <<<
- protocol: UDP # <<<
port: 53 # <<<
policyTypes:
- Egress 
Posledná položka to — prázdna, a preto nepriamo vyberá všetky pody vo všetkých namespace, čím umožňuje balance posielať DNS dotazy na príslušnú službu Kubernetes (vo všeobecnosti funguje v namespace kube-system).
Tento prístup funguje, avšak je príliš dovolenkový a nebezpečný, pretože umožňuje smerovať DNS dotazy mimo cluster.
Je možné ho zlepšiť tromi postupnými krokmi.
1. Umožniť DNS dotazy iba vnútri clusteru, pridaním namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
egress:
- to:
- podSelector:
matchLabels:
app: postgres
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
policyTypes:
- Egress 
2. Povoliť DNS dotazy len v rámci mena kube-system.
Na to je potrebné pridať štítok do mena kube-system: kubectl label namespace kube-system namespace=kube-system — a uviesť ju v politike pomocou namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
egress:
- to:
- podSelector:
matchLabels:
app: postgres
- to:
- namespaceSelector:
matchLabels:
namespace: kube-system
ports:
- protocol: UDP
port: 53
policyTypes:
- Egress 
3. Paranoidní môžu ísť ešte ďalej a obmedziť DNS dotazy na konkrétnu DNS službu v kube-system. V sekcii „Filter podľa priestorov mien a podov“ sa dozviete, ako to dosiahnuť.
Inou možnosťou je povoliť DNS na úrovni priestoru mien. V takom prípade ho nebude potrebné otvárať pre každú službu:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.dns
namespace: default
spec:
podSelector: {}
egress:
- to:
- namespaceSelector: {}
ports:
- protocol: UDP
port: 53
policyTypes:
- Egress Prázdny podSelector vyberá všetky pady v priestore mien.

Prvé zodpovedanie a poradie pravidiel
V bežných firewally je akcia ("Povoliť" alebo "Zakažiť") vo vzťahu k paketu určená prvým pravidlom, ktorému vyhovuje. V Kubernetes poradie politík nemá žiadny význam.
Ako predvolené, keď nie sú stanovené politiky, je komunikácia medzi padmi povolená a môžu si slobodne vymieňať informácie. Keď začnete formulovať politiky, každý pad, ktorého sa aspoň jedna z nich dotkila, sa stáva izolovaným podľa disjunkcie (logického ALEBO) všetkých politík, ktoré ho vybrali. Pady, ktorých sa žiadna politika nedotkla, zostávajú otvorené.
Toto správanie môžete zmeniť pomocou pravidla čistenia.
Pravidlo čistenia ("Zakažiť")
Politiky firewallov zvyčajne zakazujú akýkoľvek explicitne neumožnený prenos.
V Kubernetes neexistuje akcia "zakázať" (deny),, avšak podobného efektu môžete dosiahnuť pomocou bežnej (povoľujúcej) politiky, výberom prázdnej skupiny padov zdrojov (ingress):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress 
Táto politika vyberá všetky pod (pod) v priestore mien a zostavuje ingress ako neurčitý, čím zakazuje celý prichádzajúci prenos.
Podobným spôsobom je možné obmedziť celý odchádzajúci prenos z priestoru mien:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress 
Majte na pamäti, že akékoľvek ďalšie politiky, ktoré povoľujú prenos k podom v priestore mien, majú prednosť pred týmto pravidlom (podobne ako pridanie povoľujúceho pravidla pred zakazujúcim v konfigurácii firewallu).
Povoliť všetko (Any-Any-Any-Allow)
Ak chcete vytvoriť politiku 'Povoliť všetko', musíte doplniť vyššie uvedenú zakazujúcu politiku prázdnym prvkom ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
namespace: default
spec:
podSelector: {}
ingress: # <<<
- {} # <<<
policyTypes:
- Ingress 
Otvára prístup zo všetkých podov vo všetkých priestoroch mien (a všetkých IP) k každému podu v priestore mien default. Takéto správanie je predvolene zapnuté, a preto ho zvyčajne netreba dodatočne definovať. Občas však môže byť potrebné dočasne zakázať niektoré konkrétne povolenia na diagnostiku problému.
Pravidlo možno zúžiť a povoliť prístup iba k určitej skupine podov (app:balance) v priestore mien default:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-to-balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
ingress:
- {}
policyTypes:
- Ingress 
Nasledujúca politika povoľuje celý prichádzajúci (ingress) a odchádzajúci (egress) prenos, vrátane prístupu k akémukoľvek IP mimo klastra:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress 

Kombinovanie niekoľkých politík
Politiky sa kombinujú pomocou logického OR na troch úrovniach; povolenia každého podu sa určujú podľa disjunkcie všetkých politík, ktoré sa ho dotýkajú:
1. V poliach z a to môžete definovať tri typy prvkov (všetky sa kombinujú pomocou OR):
-
namespaceSelector— vyberá celý priestor mien; -
podSelector— vyberá podov; -
ipBlock— vyberá podsieť.
Pri tom počet prvkov (aj rovnakých) v podsekciách z/to nie je obmedzený. Všetky budú kombinované logickým OR.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres
namespace: default
spec:
ingress:
- from:
- podSelector:
matchLabels:
app: indexer
- podSelector:
matchLabels:
app: admin
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress 
2. Vnútri politiky môže byť sekcia ingress množstvo prvkov z (spájajú sa logickým OR). Podobne sekcia egress môže obsahovať množstvo prvkov to (tiež spojené disjunkciou):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres
namespace: default
spec:
ingress:
- from:
- podSelector:
matchLabels:
app: indexer
- from:
- podSelector:
matchLabels:
app: admin
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress 
3. Rôzne politiky sa tiež spájajú logickým OR
Ale pri ich kombinácii existuje jedno obmedzenie, na ktoré : Kubernetes môže kombinovať politiky iba s rôznymi policyTypes (Ingress alebo Egress). Politiky, ktoré určujú ingress (alebo egress), si navzájom prepisujú pravidlá.
Vzťah medzi priestormi názvov
Predvolene je výmena informácií medzi priestormi názvov povolená. To je možné zmeniť pomocou obmedzujúcej politiky, ktorá obmedzí odchádzajúcu a/alebo prichádzajúcu prevádzku v priestore názvov (pozri "Zásadu čistenia" vyššie).
Zablokovaním prístupu do priestoru názvov (pozri "Zásadu čistenia" vyššie) môžete urobiť výnimky z obmedzujúcej politiky, ktorá umožní pripojenia z určitého priestoru názvov pomocou namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database.postgres
namespace: database
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- namespaceSelector: # <<<
matchLabels:
namespace: default
policyTypes:
- Ingress 
Výsledkom je, že všetky pod-y v priestore názvov default budú mať prístup k pod-om postgres v priestore názvov database. Ale čo ak chcete otvoriť prístup k postgres iba konkrétnym pod-om v priestore názvov default?
Filter podľa priestorov názvov a pod-ov
Kubernetes verzie 1.11 a vyššie umožňuje kombinovať operátory namespaceSelector a podSelector pomocou logického AND. Vyzerá to nasledovne:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database.postgres
namespace: database
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- namespaceSelector:
matchLabels:
namespace: default
podSelector: # <<<
matchLabels:
app: admin
policyTypes:
- Ingress 
Prečo je to interpretované ako AND namiesto bežného OR?
Všimnite si, že podSelector nezapína sa pomlčkou. V YAML to znamená, že podSelector a stojaci pred ním namespaceSelector patria do tej istej položky zoznamu. Preto sa spájajú logickým AND.
Pridanie pomlčky pred podSelector vytvorí nový prvok zoznamu, ktorý sa skombinuje s predchádzajúcim namespaceSelector s pomocou logického ALE.
Aby ste vybrali pod’y s konkrétnym labelom vo všetkých menných priestoroch, zadajte prázdny namespaceSelector:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: database.postgres
namespace: database
spec:
podSelector:
matchLabels:
app: postgres
ingress:
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
app: admin
policyTypes:
- Ingress 
Viaceré labely sa kombinujú s A
Pravidlá pre firewall s viacerými objektmi (hostiteľmi, sieťami, skupinami) sa kombinujú pomocou logického ALE. Nasledujúce pravidlo sa spustí, ak zdroj balíka súhlasí s Host_1 ALEBO Host_2:
| Zdroj | Cieľ | Služba | Akcia |
| ----------------------------------------|
| Host_1 | Subnet_A | HTTPS | Povoliť |
| Host_2 | | | |
| ----------------------------------------| Naopak, v Kubernetes sa rôzne labely podSelector alebo namespaceSelector kombinujú logickým A. Napríklad, nasledujúce pravidlo vyberie pod’y, ktoré majú obidva labely, role=db A version=v2:
podSelector:
matchLabels:
role: db
version: v2Tá istá logika sa aplikuje na všetky typy operátorov: selektory cieľovej politiky, selektory pod’ov a selektory menných priestorov.
Podnety a IP adresy (IPBlocks)
Na segmentáciu siete firewally používajú VLAN, IP adresy a podnety.
V Kubernetes sa IP adresy priraďujú pod’om automaticky a môžu sa často meniť, preto sa pre výber pod’ov a menných priestorov v sieťových politikách používajú labely.
Podnety (ipBlocks) sa používajú pri správe vstupných (ingress) alebo výstupných (egress) externých (North-South) pripojení. Napríklad, táto politika otvára všetkým pod’om z menného priestoru default prístup k DNS službe Google:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-dns
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 8.8.8.8/32
ports:
- protocol: UDP
port: 53 
Prázdny selektor pod’ov v tomto príklade znamená „vybrať všetky pod’y v mennom priestore“.
Táto politika otvorí prístup iba k 8.8.8.8; prístup k akémukoľvek inému IP je zakázaný. Týmto spôsobom v podstate blokujete prístup k vnútorným službám DNS Kubernetes. Ak to však chcete povoliť, uveďte to výslovne.
Obvykle ipBlocks a podSelectors sú vzájomne sa vylučujúce, pretože vnútorné IP adresy pod’ov nie sú používané v ipBlocks. Uvedením vnútorných IP pod’ov, v podstate povolíte pripojenia k/z pod'ov s týmito adresami. V praxi nebudete vedieť, ktorý IP-adres použiť, preto ich netreba aplikovať pri voľbe pod'ov.
Ako protikladný príklad nasledujúca politika zahŕňa všetky IP a tým pádom povoľuje prístup ku všetkým ostatným pod'om:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-any
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0 
Môžete otvoriť prístup iba k externým IP, pričom vylúčite vnútorné IP adresy pod'ov. Napríklad, ak je podsieť vášho pod'u 10.16.0.0/14:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-any
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.16.0.0/14 
Porty a protokoly
Zvyčajne pod'y počúvajú na jednom porte. To znamená, že môžete jednoducho neuvádzať čísla portov v politikách a nechať všetko zaujať predvolené hodnoty. Avšak odporúča sa, aby politiky boli maximálne obmedzujúce, takže v niektorých prípadoch je možné uvádzať porty:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres
namespace: default
spec:
ingress:
- from:
- podSelector:
matchLabels:
app: indexer
- podSelector:
matchLabels:
app: admin
ports: # <<<<
- port: 443 # <<<<
protocol: TCP # <<<<
- port: 80 # <<<<
protocol: TCP # <<<<
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress 
Všimnite si, že selektor ports sa aplikuje na všetky prvky v bloku to alebo z, v ktorom je obsiahnutý. Aby ste uviedli rôzne porty pre rôzne skupiny prvkov, rozdeľte ingress alebo egress na niekoľko podsekcií s to alebo z a v každej uveďte svoje porty:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default.postgres
namespace: default
spec:
ingress:
- from:
- podSelector:
matchLabels:
app: indexer
ports: # <<<<
- port: 443 # <<<<
protocol: TCP # <<<<
- from:
- podSelector:
matchLabels:
app: admin
ports: # <<<<
- port: 80 # <<<<
protocol: TCP # <<<<
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress 
Funkcia portov predvolene:
- Ak úplne vynecháte definíciu portov (
ports), znamená to všetky protokoly a všetky porty; - Ak vynecháte definíciu protokolu (
protocol), znamená to TCP; - Ak vynecháte definíciu portu (
port), znamená to všetky porty.
Najlepšia prax: nespoliehajte sa na predvolené hodnoty, uvádzajte to, čo potrebujete, jednoznačne.
Upozorňujeme, že je potrebné používať porty podov, a nie služieb (podrobnosti v nasledujúcom odstavci).
Sú politiky definované pre body alebo služby?
Zvyčajne sa podi v Kubernetes navzájom obracajú cez služby — virtuálny vyrovnávač záťaže, ktorý presmerúva dopravu k podom, ktoré realizujú službu. Môže sa zdať, že sieťové politiky kontrolujú prístup k službám, ale nie je tomu tak. Sieťové politiky Kubernetes pracujú s portami podov, a nie služieb.
Napríklad, ak služba počúva na 80. porte, ale presmerováva dopravu na 8080 svojich podov, je potrebné v sieťovej politike uviesť práve 8080.
Takýto mechanizmus je potrebné považovať za suboptimálny: pri zmene vnitorného usporiadania služby (porty, ktoré počúvajú podi) bude potrebné aktualizovať sieťové politiky.
Nový architektonický prístup pomocou Service Mesh (napríklad pozri nižšie o Istio — pozn. prekl.) umožňuje riešiť tento problém.
Je potrebné nastaviť ako Ingress, tak aj Egress?
Krátka odpoveď je áno, aby pod A mohol komunikovať s podom B, je potrebné mu povoliť vytvorenie odchádzajúceho spojenia (na to je potrebné nastaviť egress politiku), a pod B musí mať možnosť prijímať prichádzajúce spojenie (na to, samozrejme, potrebujeme ingress politiku).
V praxi sa však môžete spoľahnúť na politiku predvolene, ktorá povoľuje spojenia v jednom alebo oboch smeroch.
Ak pod-zdroj je vybraný jednou alebo viacerými egress-politikami, obmedzenia, ktoré sa na neho vzťahujú, budú určené ich disjunkciou. V takom prípade bude potrebné výslovne povoliť pripojenie k podu-cieľu. Ak pod nie je vybraný žiadnou politikou, jeho odchádzajúca (egress) doprava je povolená predvolene.
Podobne osud podu-cieľa, ktorý je vybraný jednou alebo viacerými ingress-politikami, bude určený ich disjunkciou. V takom prípade je potrebné jednoznačne mu povoliť prijímať dopravu od podu-zdroja. Ak pod nie je vybraný žiadnou politikou, všetka prichádzajúca (ingress) doprava pre neho je povolená predvolene.
Pozri bod „Stateful alebo Stateless“ nižšie.
Logy
Sieťové politiky Kubernetes nevedia zaznamenávať dopravu. To sťažuje určenie, či politika funguje správne, a značne komplikuje analýzu v oblasti bezpečnosti.
Kontrola nad dopravou k externým službám
Sieťové politiky Kubernetes neumožňujú uvádzať úplné doménové meno (DNS) v sekciách egress. Tento fakt spôsobuje výrazné nevýhody pri pokuse o obmedzenie prenosu k vonkajším adresátom, ktorí nemajú pevný IP adresa (ako napríklad aws.com).
Kontrola politiky
Firewally vás upozornia alebo dokonca odmietnu prijať neplatnú politiku. Kubernetes tiež vykonáva niektoré verifikácie. Pri zadávaní sieťovej politiky cez kubectl môže Kubernetes oznámiť, že je neplatná, a odmietnuť ju prijať. V iných prípadoch Kubernetes politiku prijme a doplní chýbajúce detaily. Tieto môžete získať pomocou príkazu:
kubernetes get networkpolicy -o yamlMajte na pamäti, že overovací systém Kubernetes nie je neomylný a môže prehliadnúť niektoré typy chýb.
Vykonanie
Kubernetes sám o sebe nerealizuje sieťové politiky, ale slúži len ako API brána, pričom ťažkú prácu kontroly načíta na podriadený systém nazývaný Container Networking Interface (CNI). Nastavenie politík v klustre Kubernetes bez priradenia zodpovedajúceho CNI je podobné vytvoreniu politík na správcovskom serveri firewall bez ich následného nastavenia v firewally. Musíte sa sami uistiť, že máte dôstojný CNI alebo, v prípade platforiem Kubernetes umiestnených v cloude, (zo zoznamom poskytovateľov sa môžete oboznámiť — pozn. prekl.), implementovať sieťové politiky, ktoré CNI nastaví za vás.
Všimnite si, že Kubernetes vás neupozorní, ak nastavíte sieťovú politiku bez zodpovedajúceho pomocného CNI.
Stateful alebo Stateless?
Všetky CNI Kubernetes, s ktorými som sa stretol, uchovávajú stavy (napríklad Calico používa Linux conntrack). To umožňuje podu prijímať odpovede na jeho iniciované TCP pripojenia bez nutnosti jeho opätovného nadväzovania. V tejto súvislosti nepoznám štandard Kubernetes, ktorý by zaručil uchovávanie stavu (statefulness).
Pokročilé riadenie bezpečnostnej politiky
Tu je niekoľko spôsobov, ako zvýšiť účinnosť vykonávania bezpečnostnej politiky v Kubernetes:
- Architektonický vzor Service Mesh využíva sidecar kontajnery na poskytovanie podrobnej telemetrie a kontroly prenosu na úrovni služieb. Ako príklad možno uviesť .
- Niektorí poskytovatelia CNI vylepšili svoje nástroje, aby presiahli rámec sieťových politík Kubernetes.
- poskytuje transparentnosť a automatizáciu sieťových politík Kubernetes.
Balík Tufin Orca spravuje sieťové politiky Kubernetes (a slúži ako zdroj snímok obrazovky uvedených vyššie).
Ďalšie informácie
- ;
- ;
- ;
- .
Záver
Sieťové politiky Kubernetes ponúkajú slušný súbor nástrojov na segmentáciu klastrov, avšak sú intuitívne nezrozumiteľné a majú množstvo jemností. Myslím, že kvôli tejto zložitosti politiky mnohých existujúcich klastrov obsahujú chyby. Možné riešenia tohto problému zahŕňajú automatizáciu definícií politík alebo použitie iných nástrojov na segmentáciu.
Dúfam, že táto príručka pomôže objasniť niektoré otázky a vyrieši problémy, s ktorými sa môžete stretnúť.
P.S. od prekladateľa
Prečítajte si tiež na našom blogu:
- „Späť k mikroslužbám s Istio“: , , ;
- „Ilustrovaný sprievodca architektúrou siete v Kubernetes“: , ;
- «»;
- «»;
- «».
Zdroj: habr.com
