
Pozn. přek.: Autor článku — Reuven Harrison — má více než 20 let zkušeností ve vývoji softwaru a v současné době je technickým ředitelem a spoluzakladatelem společnosti Tufin, která vytváří řešení pro správu bezpečnostních politik. Při zvažování síťových politik Kubernetes jako dostatečně mocného nástroje pro segmentaci sítě v clusteru zároveň tvrdí, že jejich praktické uplatnění není tak jednoduché. Tento materiál (poměrně obsáhlý) má zlepšit povědomí odborníků v této oblasti a pomoci jim při vytváření potřebných konfigurací.
Dnes mnoho společností stále častěji vybírá Kubernetes pro nasazení svých aplikací. Zájem o tento software je tak vysoký, že někteří nazývají Kubernetes „novým operačním systémem pro datová centra“. Postupně je Kubernetes (nebo k8s) vnímán jako kritická součást podnikání, která vyžaduje organizaci zralých obchodních procesů, včetně zajištění síťové bezpečnosti.
Pro bezpečnostní specialisty, kteří jsou zmatení prací s Kubernetes, může být překvapením výchozí politika této platformy: povolit vše.
Tato příručka pomůže pochopit vnitřní fungování síťových politik; poznat, jak se liší od pravidel běžných brán firewall. Také se podíváme na některé úskalí a poskytneme doporučení, která pomohou chránit aplikace v Kubernetes.
Síťové politiky Kubernetes
Mechanismus síťových politik Kubernetes umožňuje řídit vzájemné interakce aplikací nasazených na platformě na síťové úrovni (třetí úroveň modelu OSI). Síťové politiky postrádají některé pokročilé funkce moderních brán firewall, jako je řízení na 7. úrovni OSI a detekce hrozeb, nicméně zajišťují základní úroveň síťové bezpečnosti, což je dobrý výchozí bod.
Síťové politiky ovládají komunikaci mezi pod'y
Pracovní zátěže v Kubernetes jsou rozděleny mezi pod’y, které se skládají z jednoho nebo více kontejnerů, nasazených společně. Kubernetes každému pod’u přiřazuje IP adresu, která je dostupná z jiných pod’ů. Síťové politiky Kubernetes určují přístupová práva pro skupiny pod’ů podobným způsobem, jakým se bezpečnostní skupiny v cloudu používají k řízení přístupu k instancím virtuálních strojů.
Definice síťových politik
Jako všechny ostatní zdroje Kubernetes se síťové politiky definují v jazyce YAML. V následujícím příkladu je aplikaci balance přístup otevřen 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. přek.: tento snímek obrazovky, stejně jako všechny následující podobné, byl vytvořen pomocí nástroje Tufin Orca, jehož vývoj stojí za autorem původního článku, který je zmíněn na konci materiálu.
Pro definici vlastní síťové politiky budete potřebovat základní znalosti YAML. Tento jazyk je založen na odsazeních (určených mezerami, nikoli tabulátory). Element s odsazením náleží nejbližšímu prvku s odsazením nad ním. Nový prvek seznamu začíná pomlčkou, všechny ostatní prvky mají podobu klíč-hodnota.
Po popisu politiky v YAML použijte , abyste ji vytvořili v klastru:
kubectl create -f policy.yamlSpecifikace síťové politiky
Specifikace síťové politiky Kubernetes zahrnuje čtyři prvky:
-
podSelector: určuje pod’y, které jsou touto politikou dotčeny (cíle) — povinné; -
policyTypes: uvádí, jaké typy politik jsou zahrnuty v této: ingress a/nebo egress — nepovinné, doporučuji však jej jasně uvádět ve všech případech; -
ingress: určuje povolený příchozí provoz do cílových pod’ů — nepovinné; -
egress: určuje povolený odchozí provoz z cílových pod’ů — nepovinné.
Příklad převzatý z webu Kubernetes (nahradil jsem role na app), ukazuje, jak jsou používány všechny čtyři 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 

Všimněte si, že není nutné zahrnout všechny čtyři prvky. Povinný je pouze podSelector, ostatní parametry mohou být použity dle potřeby.
Pokud se vynechá policyTypes, bude politiku interpretovat následovně:
- Ve výchozím nastavení se předpokládá, že definuje ingress stranu. Pokud politika neobsahuje žádné jasné pokyny v tomto smyslu, systém bude považovat, že veškerý provoz je zakázán.
- Chování na egress straně bude určeno přítomností nebo nepřítomností odpovídajícího egress parametru.
Abychom se vyhnuli chybám, doporučuji vždy jasně uvést policyTypes.
V souladu s výše uvedenou logikou, pokud jsou parametry ingress a/nebo egress vynechány, politika bude zakazovat veškerý provoz (viz „Pravidlo čištění“ níže).
Výchozí politika — povolit
Pokud nejsou politiky definovány, Kubernetes ve výchozím nastavení povoluje veškerý provoz. Všechny pod jednotky si mohou volně vyměňovat informace. Z pohledu bezpečnosti se to může zdát nelogické, ale pamatujte, že Kubernetes byl původně navržen vývojáři s cílem umožnit interakci aplikací. Síťové politiky byly přidány později.
Prostor jmen
Prostory jmen (Namespaces) jsou mechanismem kolektivní práce Kubernetes. Jsou určeny k izolaci logických prostředí od sebe, přičemž výměna dat mezi prostory je ve výchozím nastavení povolena.
Stejně jako většina komponent Kubernetes, síťové politiky se nacházejí v určitém prostoru jmen. V bloku metadata můžete uvést, kterému prostoru náleží politika:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: my-namespace # <<<
spec:
... Pokud není prostor jmen v metadatech jasně uveden, systém použije namespace uvedené v kubectl (ve výchozím nastavení namespace=default):
kubectl apply -n my-namespace -f namespace.yamlDoporučuji jasně uvést namespace, pokud nepíšete politiku určenou pro více prostorů názvů současně.
Hlavní prvek podSelector v politice bude vybírat pod’y z prostoru názvů, k němuž politika patří (nema přístup k pod’y z jiného prostoru názvů).
Podobně podSelector’y v blocích ingress a egress mohou vybírat pod’y pouze ze svého prostoru názvů, pokud je samozřejmě nesdružíte pomocí namespaceSelector (o tom bude řeč v části „Filtr podle prostorů názvů a pod’y“).
Pravidla pojmenování politik
Názvy politik jsou jedinečné v rámci jednoho prostoru názvů. Dvě politiky se stejným názvem v jednom prostoru nemohou existovat, ale mohou existovat politiky se stejnými názvy v různých prostorech. Je to užitečné, když chcete znovu použít jednu a tutéž politiku na několika prostorech.
Zvlášť se mi líbí jeden z návrhů pojmenování. Spočívá v tom, že se spojuje název prostoru názvů s cílovými pod’y. Napří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 objektům Kubernetes, jako jsou pod’y a prostory názvů, lze připojovat vlastní štítky. Štítky (labels — značky) jsou ekvivalentem tagů v cloudu. Síťové politiky Kubernetes používají štítky k výběru pod’y, na které se vztahují:
podSelector:
matchLabels:
role: db… nebo prostorů názvů, na které se vztahují. V tomto příkladu se vybírají všechny pod’y v prostorech názvů se shodnými štítky:
namespaceSelector:
matchLabels:
project: myproject Jedno varování: při použití namespaceSelector se ujistěte, že vybrané prostory názvů obsahují požadovaný štítek. Mějte na paměti, že vestavěné prostory názvů, jako je default a kube-system, ve výchozím nastavení neobsahují štítky.
Štítek k prostoru se dá přidat následujícím způsobem:
kubectl label namespace default namespace=default Přitom namespace v části metadata by měl odkazovat na skutečné jméno prostoru, a ne na štítek:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default # <<<
spec:
...Zdroj a adresát
Politiky pro firewally se skládají z pravidel s původci a příjemci. Síťové politiky Kubernetes jsou definovány pro cílový soubor podů, na které se vztahují, a nastavují pravidla pro příchozí (ingress) a/nebo odchozí (egress) provoz. V našem příkladu cílem politiky budou všechny pody v prostoru názvů default s označením s klíčem 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 

Podrobnost ingress v této politice otevírá příchozí provoz pro cílové pody. Jinými slovy, ingress je zdrojem, zatímco cíl je příslušným příjemcem. Podobně egress je příjemcem, zatímco cíl je jeho zdrojem.

To odpovídá dvěma pravidlům pro firewall: Ingress → Cíl; Cíl → Egress.
Egress a DNS (důležité!)
Omezením odchozího provozu, věnujte zvláštní pozornost DNS — Kubernetes používá tuto službu pro mapování služeb na IP adresy. Například následující politika nebude fungovat, protože jste nepovolili aplikaci balance přístup 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 
Opravit to lze otevřením přístupu k DNS službě:
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í prvek to — prázdný, a proto nepřímo vybírá všechny pody ve všech prostorech názvů, což umožňuje balance odesílat DNS dotazy na příslušnou službu Kubernetes (obvykle běží v prostoru kube-system).
Tento přístup funguje, nicméně je příliš povolující a nebezpečný, protože umožňuje, aby DNS dotazy směřovaly mimo cluster.
Vylepšit to lze třemi po sobě jdoucími kroky.
1. Povolte DNS dotazy pouze uvnitř na cluster přidání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. Umožněte DNS dotazy pouze v rámci jmenného prostoru kube-system.
K tomu je potřeba přidat štítek do jmenného prostoru kube-system: kubectl label namespace kube-system namespace=kube-system — a zapsat ho do politiky prostřednictví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: # <<<
matchLabels: # <<<
namespace: kube-system # <<<
ports:
- protocol: UDP
port: 53
policyTypes:
- Egress 
3. Paranoici mohou jít ještě dál a omezit DNS dotazy na konkrétní DNS službu v kube-system. V části „Filtr podle jmenných prostorů a podů“ bude popsáno, jak toho dosáhnout.
Další možností je povolit DNS na úrovni jmenného prostoru. V tomto případě ho nebude nutné otevírat pro každou 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ázdný podSelector vybírá všechny pody v jmenném prostoru.

První zápas a pořadí pravidel
Ve standardních firewallech se akce („Povolit“ nebo „Zamezit“) na paket určuje prvním pravidlem, které vyhovuje. V Kubernetes nemá pořadí politik žádný význam.
Ve výchozím nastavení, když nejsou určeny politiky, je komunikace mezi podmi povolena a mohou si volně vyměňovat informace. Jakmile začnete formulovat politiky, každý pod, který je ovlivněn alespoň jednou z nich, se stává izolovaným podle disjunkce (logického NEBO) všech politik, které je vybraly. Pody, které nejsou dotčeny žádnou politikou, zůstávají otevřené.
Toto chování lze změnit pomocí pravidla vyřazení.
Pravidlo vyřazení („Zamezit“)
Politiky firewallu obvykle zamezují jakémukoli výslovně nepovolenému provozu.
V Kubernetes neexistuje akce „zamezit“ (deny),ale podobného efektu lze dosáhnout s běžnou (povolující) politikou, pokud zvolíte prázdnou skupinu podů zdrojů (ingress):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress 
Tato politika vybere všechny podů v prostorách jmen a ponechá ingress neurčený, což zakazuje veškerý příchozí provoz.
Podobným způsobem lze omezit veškerý odchozí provoz z prostorů jmen:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress 
Mějte na paměti, že jakákoli další politika, která povoluje provoz k podům v prostoru jmen, bude mít prioritu před tímto pravidlem (analogicky k přidání povolujícího pravidla před zakázající v konfiguraci firewallu).
Povolit vše (Any-Any-Any-Allow)
Chcete-li vytvořit politiku „Povolit vše“, musíte doplnit uvedenou zakazující politiku prázdným prvkem ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
namespace: default
spec:
podSelector: {}
ingress: # <<<
- {} # <<<
policyTypes:
- Ingress 
Otevírá přístup ze všech podů ve všech prostorech jmen (a všech IP) k libovolnému podu v prostoru jmen default. Takové chování je ve výchozím nastavení povoleno, takže obvykle není potřeba ho dodatečně určovat. Nicméně někdy může být potřeba dočasně zakázat některá konkrétní povolení pro diagnostiku problému.
Pravidlo lze zúžit a povolit přístup pouze k určitému souboru podů (app:balance) v prostoru jmen default:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-to-balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
ingress:
- {}
policyTypes:
- Ingress 
Následující politika povoluje veškerý příchozí (ingress) a odchozí (egress) provoz, včetně přístupu k libovolné IP mimo cluster:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress 

Kombinace několika politik
Politiky se kombinují logickým OR na třech úrovních; povolení každého podu jsou nastavena podle disjunkce všech politik, které se ho dotýkají:
1. V polích from a to můžete definovat tři typy prvků (všechny se kombinují pomocí OR):
-
namespaceSelector— vybírá celé jméno prostoru; -
podSelector— vybírá pody; -
ipBlock— vybírá podsíť.
Přitom počet prvků (i stejných) v podřízených from/to není omezen. Všechny budou sloučeny 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. Uvnitř politiky oddíl ingress může mít mnoho prvků from (kombinují se logickým NEBO). Podobně oddíl egress může zahrnovat mnoho prvků to (také se kombinují disjunktivně):
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ůzné politiky se také kombinují logickým NEBO
Ale při jejich kombinaci existuje jedno omezení, na které : Kubernetes může kombinovat politiky pouze s různými policyTypes (Ingress nebo Egress). Politiky definující ingress (nebo egress) si vzájemně přeepisují.
Spojení mezi pracovními prostory
Ve výchozím nastavení je komunikace mezi pracovními prostory povolena. To lze změnit pomocí restriktivní politiky, která omezuje odchozí a/nebo příchozí provoz do pracovního prostoru (viz "Čistící pravidlo" výše).
Zablokováním přístupu do pracovního prostoru (viz "Čistící pravidlo" výše) můžete udělat výjimku v restriktivní politice, povolením připojení z určitého pracovního prostoru pomocí 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 důsledku toho budou všechny pod’y v pracovním prostoru default mít přístup k pod’m Postgres v jmenném prostoru database. Ale co když chcete otevřít přístup pouze konkrétním pod’m v pracovním prostoru Postgres Filtr podle pracovních prostorů a pod’ů default?
Kubernetes verze 1.11 a výše umožňuje kombinovat operátory
pomocí logického A. Vypadá to následovně: namespaceSelector a podSelector 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
Proč je to interpretováno jako A místo obvyklého NEBO? 
nezačíná pomlčkou. V YAML to znamená, že
Všimněte si, že podSelector a to, co je před ním podSelector se vztahují na stejný prvek seznamu. Proto se kombinují logickým A. namespaceSelector Přidání pomlčky před
Přidání pomlčky před podSelector povede k vytvoření nového prvku seznamu, který se bude kombinovat s předchozím namespaceSelector pomocí logického NEBO.
Chcete-li vybrat pod’y s určitou značkou ve všech prostorách názvů, zadejte prázdný 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 
Vícenásobné značky se kombinují s A
Pravidla pro firewall se spoustou objektů (hostitelé, sítě, skupiny) se kombinují pomocí logického NEBO. Následující pravidlo se spustí, pokud zdroj paketu odpovídá Host_1 NEBO Host_2:
| Source | Destination | Service | Action |
| ----------------------------------------|
| Host_1 | Subnet_A | HTTPS | Allow |
| Host_2 | | | |
| ----------------------------------------| Naopak, v Kubernetes se různé značky v podSelector nebo namespaceSelector kombinují logickým A. Například následující pravidlo vybere pod’y, které mají obě značky, role=db A version=v2:
podSelector:
matchLabels:
role: db
version: v2Stejná logika platí pro všechny typy operátorů: selektory cílů politiky, selektory pod’ů a selektory prostorů názvů.
Podniky a IP adresy (IPBlocks)
Pro segmentaci sítě firewally používají VLAN, IP adresy a podsítě.
V Kubernetes jsou IP adresy automaticky přidělovány pod’am a mohou se často měnit, proto se pro výběr pod’ů a prostorů názvů v síťových politikách používají značky.
Podsítě (ipBlocks) se používají při řízení příchozích (ingress) nebo odchozích (egress) externích (Sever-Jih) připojení. Například tato politika otevírá přístup všem pod’am z prostoru názvů default k DNS službě 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ázdný selektor pod’ů v tomto příkladu znamená „vybrat všechny pod’y v prostoru názvů“.
Tato politika otevírá přístup pouze k 8.8.8.8; přístup k jakékoli jiné IP je zakázán. Tímto způsobem jste v podstatě zablokovali přístup k interní službě DNS Kubernetes. Pokud ji však chcete otevřít, uveďte to výslovně.
Obvykle ipBlocks a podSelectors jsou vzájemně se vylučující, protože interní IP adresy pod’ů se nepoužívají v ipBlocks. Uvedením interní IP pod’ů, skutečně povolíte připojení k/od podů z těchto adres. V praxi nebudete vědět, kterou IP adresu použít, proto je nejlepší je nepoužívat pro výběr podů.
Jako kontra příklad následující politika zahrnuje všechny IP a tudíž povoluje přístup ke všem ostatním podům:
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 povolit přístup pouze k externím IP, vyloučením interních IP adres podů. Například, pokud je podsíť vašeho podu 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
Obvykle pady naslouchají na jednom portu. To znamená, že můžete jednoduše neuveřejňovat čísla portů v politikách a nechat všechno na výchozím nastavení. Nicméně doporučuje se, aby politiky byly co nejvíce restriktivní, proto je v některých případech možné uvést 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šimněte si, že selektor ports se aplikuje na všechny prvky v bloku to nebo from, ve kterém se nachází. Abyste uvedli různé porty pro různé sady prvků, rozdělte ingress nebo egress na několik podoblastí s to nebo from a v každé uveďte své 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 
Funkce portů podle výchozího nastavení:
- Pokud zcela vynecháte definici portů (
ports), znamená to všechny protokoly a všechny porty; - Pokud vynecháte definici protokolu (
protocol), znamená to TCP; - Pokud vynecháte definici portu (
port), znamená to všechny porty.
Nejlepší praxe: nespolehejte se na výchozí hodnoty, zadejte, co potřebujete, jasně.
Všimněte si, že je třeba používat porty podů, nikoli služeb (více o tom v dalším odstavci).
Jsou politiky definovány pro pody nebo služby?
Obvykle se pody v Kubernetes vzájemně komunikují přes službu — virtuální vyrovnávač zatížení, který směruje provoz k podům, které službu realizují. Můžete si myslet, že síťové politiky kontrolují přístup ke službám, ale to není pravda. Síťové politiky Kubernetes fungují s porty podů, nikoli služeb.
Například pokud služba naslouchá na portu 80, ale směruje provoz na port 8080 svých podů, je nutné v síťové politice specifikovat právě 8080.
Takový mechanismus je třeba považovat za suboptimální: při změně vnitřní struktury služby (porty, na kterých naslouchají pody) bude nutné aktualizovat síťové politiky.
Nový architektonický přístup pomocí Service Mesh (například viz Istio níže — pozn. překl.) umožňuje tuto problematiku vyřešit.
Je třeba specifikovat jak Ingress, tak Egress?
Krátká odpověď — ano, aby se pod A mohl spojit s pod B, je třeba mu povolit vytváření výstupního spojení (k tomu je nutné nastavit egress politiku), a pod B musí mít možnost přijímat příchozí spojení (k tomu je zapotřebí ingress politika).
V praxi se však můžete spolehnout na výchozí politiku, která povoluje spojení v jednom nebo obou směrech.
Pokud je určitý podzdroj vybrán jednou nebo více egress-politiky, budou omezení na něj uvalená určena jejich disjunkcí. V tomto případě je třeba explicitně povolit připojení k podu-adresátovi. Pokud pod není vybrán žádnou politikou, jeho výstupní (egress) provoz je ve výchozím nastavení povolen.
Podobně osud podu-adresáta, vybraného jednou nebo více ingress-politiky, bude určen jejich disjunkcí. V tomto případě je potřeba mu explicitně povolit přijímat provoz od podu-zdroje. Pokud pod není vybrán žádnou politikou, celý příchozí (ingress) provoz pro něj je ve výchozím nastavení povolen.
Viz bod „Stateful nebo Stateless“ níže.
Logy
Síťové politiky Kubernetes neumí logovat provoz. To komplikuje určení, zda politika funguje správně, a značně ztěžuje analýzu v oblasti bezpečnosti.
Kontrola nad provozem k externím službám
Kubernetes síťové politiky neumožňují uvést plnohodnotné doménové jméno (DNS) v sekcích egress. Tento fakt způsobuje značné potíže při pokusu o omezení provozu na externí adresáty bez pevné IP adresy (například aws.com).
Kontrola politiky
Firewall vás upozorní nebo dokonce odmítne přijmout chybovou politiku. Kubernetes také provádí určitou verifikaci. Při zadávání síťové politiky přes kubectl může Kubernetes prohlásit, že je špatná, a odmítnout ji přijmout. V jiných případech Kubernetes politiku přijme a doplní ji o chybějící detaily. Ty lze zobrazit pomocí příkazu:
kubernetes get networkpolicy -o yamlMějte na paměti, že systém kontroly Kubernetes není neomylný a může propustit některé typy chyb.
Provádění
Kubernetes sama síťové politiky neimplementuje, ale slouží jako API brána, která přenáší náročnou práci na řízení na podkladový systém zvaný Container Networking Interface (CNI). Nastavení politik v clusterech Kubernetes bez přiřazení odpovídajícího CNI je podobné jako vytváření politik na správce firewallu bez jejich následné instalace do firewallů. Musíte se sami ujistit o přítomnosti kvalitního CNI nebo, v případě cloudových Kubernetes platforem, (se seznamem poskytovatelů můžete seznámit — pozn. př.), aktivovat síťové politiky, které CNI nastaví za vás.
Všimněte si, že Kubernetes vás neupozorní, pokud nastavíte síťovou politiku bez odpovídajícího pomocného CNI.
Stavový nebo stateless?
Všechny CNI Kubernetes, se kterými jsem se setkal, uchovávají stav (například Calico používá Linux conntrack). To umožňuje podu získávat odpovědi na TCP spojení, které inicioval, aniž by bylo nutné jej znovu navazovat. Přitom nevím o žádném standardu Kubernetes, který by zaručoval uchovávání stavu.
Pokročilé řízení bezpečnostní politiky
Zde je několik způsobů, jak zvýšit efektivitu provádění bezpečnostní politiky v Kubernetes:
- Architektonický vzor Service Mesh využívá sidecar kontejnery k zajištění podrobné telemetrie a kontroly provozu na úrovni služeb. Příkladem může být .
- Někteří poskytovatelé CNI rozšířili své nástroje tak, aby přesáhly rámec síťových politik Kubernetes.
- zaručuje transparentnost a automatizaci síťových politik Kubernetes.
Balíček Tufin Orca spravuje síťové politiky Kubernetes (a slouží jako zdroj obrazovek, které byly uvedeny výše).
Další informace
- ;
- ;
- ;
- .
Závěr
Síťové politiky Kubernetes nabízejí slušnou sadu nástrojů pro segmentaci clusterů, ale jsou intuitivně nesrozumitelné a mají mnoho nuancí. Domnívám se, že kvůli této složitosti obsahuje mnoho existujících clusterů chyby. Možnými řešeními této situace jsou automatizace definic politik nebo použití jiných prostředků segmentace.
Doufám, že tato příručka pomůže objasnit některé otázky a vyřešit problémy, se kterými se můžete setkat.
P.S. od překladatele
Přečtěte si také náš blog:
- „Zpět k mikroslužbám s Istio“: , , ;
- část 1 a 2 (síťový model, overlay sítě) , ;
- «»;
- «»;
- «».
Zdroj: habr.com
