
Megjegyzés fordítás.: A cikk szerzője, Reuven Harrison, több mint 20 éves szoftverfejlesztési tapasztalattal rendelkezik, és jelenleg a Tufin technikai igazgatója és társalapítója, amely biztonsági irányelvek kezelésére készült megoldásokat fejleszt. A Kubernetes hálózati irányelveit mint a klaszterekben történő hálószegmentálás hatékony eszközét tartja, ugyanakkor azt is megjegyzi, hogy ezek alkalmazása a gyakorlatban nem olyan egyszerű. Ez az anyag (meglehetősen terjedelmes) arra hivatott, hogy javítsa a szakemberek tájékozottságát erről a kérdésről és segítsen nekik a szükséges konfigurációk létrehozásában.
Ma már sok cég egyre inkább a Kubernetes-t választja alkalmazásaik futtatására. Az érdeklődés a szoftver iránt olyan magas, hogy néhányan a Kubernetes-t a "központi adatfeldolgozó rendszerek új operációs rendszerének" nevezik. Fokozatosan a Kubernetes (vagy k8s) kritikus fontosságú üzleti elemmé válik, amely megköveteli a kiforrott üzleti folyamatok kialakítását, beleértve a hálózati biztonság biztosítását is.
A biztonsági szakemberek számára, akiknek gondot okoz a Kubernetes használata, meglepetés lehet a platform alapértelmezett politikája: mindent engedélyezni.
Ez a kézikönyv segít megérteni a hálózati irányelvek belső működését; világossá tenni, miben különböznek a hagyományos tűzfalakkal kapcsolatos szabályoktól. Szó lesz néhány buktatóról, valamint ajánlásokat is ad, amelyek segítenek a Kubernetes alkalmazások védelmében.
Kubernetes hálózati irányelvek
A Kubernetes hálózati irányelvek mechanizmusa lehetővé teszi a platformon futó alkalmazások hálózati szintű (az OSI modell harmadik szintje) kommunikációjának kezelését. A hálózati irányelvekből hiányoznak a modern tűzfalak néhány fejlett funkciója, mint például a 7. szintű OSI kontroll és a fenyegetésészlelés, azonban alapvető szintű hálózati biztonságot biztosítanak, ami kedvező kiindulópontot jelent.
A hálózati irányelvek ellenőrzik a podok közötti kommunikációt
A Kubernetesben lévő munkaterhelések pod-ok közé vannak elosztva, amelyek egy vagy több, közösen telepített konténerből állnak. A Kubernetes minden pod-nak egy IP-címet rendel, amely más pod-okból elérhető. A Kubernetes hálózati politikái hozzáférési jogokat rendelnek a pod-csoportokhoz, hasonlóan ahhoz, ahogy a felhőben a biztonsági csoportokat használják a virtuális gépekhez való hozzáférés kezelésére.
Hálózati politikák meghatározása
A többi Kubernetes-erőforráshoz hasonlóan a hálózati politikák is YAML nyelven vannak meghatározva. Az alábbi példában az alkalmazás balance hozzáférést kap az 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 
(Megjegyzés fordítás.: ez a képernyőkép, mint minden hasonló, nem a Kubernetes beépített eszközeivel készült, hanem a Tufin Orca eszköz segítségével, amelynek fejlesztésében az eredeti cikk szerzője részt vett, és amely a tartalom végén van említve.)
Saját hálózati politika meghatározásához alapvető YAML-ismeretek szükségesek. Ez a nyelv behúzásokon alapul (amelyeket szóközök, nem tabulátorok határoznak meg). A behúzott elem a fölötte lévő legközelebbi behúzott elemhez tartozik. Egy új listaelem mínusszal kezdődik, az összes többi elem pedig a következőképpen néz ki kulcs-érték.
A politikát YAML formátumban leírva használja , hogy létrehozza a klaszterben:
kubectl create -f policy.yamlHálózati politika specifikációja
A Kubernetes hálózati politika specifikációja négy elemet tartalmaz:
-
podSelector: meghatározza azokat a pod-okat, amelyeket ez a politika érint (célok) – kötelező; -
policyTypes: megadja, hogy milyen típusú politikák tartoznak ide: ingress és/vagy egress – nem kötelező, azonban javaslom, hogy minden esetben határozzuk meg; -
ingress: meghatározza a megengedett bejövő forgalmat a célzott pod-okhoz – nem kötelező; -
egress: meghatározza a megengedett kimenő forgalom a célzott pod-okból – nem kötelező.
A Kubernetes weboldaláról kölcsönzött példa (én kicseréltem role Gyorsan emlékezzünk vissza, hogyan működik a moduláris aritmetika. Az óra már egy ismert koncepció. Az órák használata app), megmutatja, hogyan használják a négy elemet:
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 

Kérjük, vegye figyelembe, hogy az összes négy elem megadása nem kötelező. Csak az podSelector, a többi paraméter szabadon használható.
Ha kihagyja policyTypes, akkor a politika a következőképpen lesz értelmezve:
- Alapértelmezés szerint feltételezzük, hogy a bejövő oldalt határozza meg. Ha a politikában nincsenek erre vonatkozó kifejezett utalások, a rendszer úgy fogja tekinteni, hogy minden forgalmat tiltanak.
- A kimenő oldal viselkedését az egress paraméter megléte vagy hiánya határozza meg.
A hibák elkerülése érdekében javaslom, hogy mindig egyértelműen adja meg, policyTypes.
A fenti logika szerint, ha a paraméterek ingress Services egress kihagyásra kerülnek, a politika megtiltja az összes forgalmat (lásd az alábbi "Tisztító szabályt").
Az alapértelmezett politika - engedélyezni
Ha a politikák nincsenek meghatározva, a Kubernetes alapértelmezés szerint engedélyezi az összes forgalmat. Minden pod szabadon információt cserélhet. Biztonsági szempontból logikátlannak tűnhet, de ne feledje, hogy a Kubernetes-et eredetileg a fejlesztők az alkalmazások közötti interakció elősegítésére hozták létre. A hálózati politikák később kerültek bevezetésre.
Névterek
A névterek (Namespaces) a Kubernetes összefogásának mechanizmusa. Azért jöttek létre, hogy elkülönítsék a logikai környezeteket egymástól, ugyanakkor az alapértelmezett beállítás szerint adatcsere megengedett az egyes névterek között.
A Kubernetes legtöbb komponenséhez hasonlóan a hálózati politikák is egy adott névtérben találhatók. A blokkban metadata megadhatja, hogy a politika melyik névtérhez tartozik:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: my-namespace # <<<<
spec:
... Ha a metadatokban a névtér kifejezetten nincs megadva, a rendszer a kubectl által megadott névteret fogja használni (alapértelmezés szerint namespace=default):
kubectl apply -n my-namespace -f namespace.yamlJavaslom, hogy egyértelműen adja meg a névteret., hacsak nem írsz egy politikát, amely egyszerre több névtérre vonatkozik.
Alap elem podSelector a politikában a pod-ok kiválasztása az ahhoz tartozó névtérből történik (nincs hozzáférése más névtérben lévő pod-okhoz).
Hasonlóképpen, a podSelector-ok a bejövő és kimenő blokkokban csak a saját névtérből választhatnak pod-okat, kivéve, ha azokat összevonod a namespaceSelector (erről a „Szűrés névterek és pod-ok szerint” részben lesz szó).
A politikák elnevezési szabályai
A politikák nevei egy névtéren belül egyediek. Két politikának ugyanazzal a névvel nem lehet a ugyanabban a névtérben, de lehetnek ugyanazon néven politikák különböző névterekben. Ez hasznos, amikor ugyanazt a politikát szeretnéd több névtérben alkalmazni.
Különösen tetszik az elnevezés egyik módja. Ez abból áll, hogy a névtér nevét összekapcsoljuk a célzott pod-okkal. Például:
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 
Címkék
A Kubernetes objektumokhoz, mint például a pod-ok és névterek, felhasználói címkék rendelhetők. A címkék (címkéket — címkék) a felhőben található tagek megfelelői. A Kubernetes hálózati politikák a címkéket használják a kiválasztásra, pod-ok, amelyekre alkalmazzák őket:
podSelector:
matchLabels:
role: db… vagy névterek, amelyekre alkalmazzák. Ebben a példában az összes pod-ot választja, a névterekben megfelelő címkékkel:
namespaceSelector:
matchLabels:
project: myproject Egy figyelmeztetés: a namespaceSelector használata során győződj meg arról, hogy a kiválasztott névterek tartalmazzák a szükséges címkét.Ne feledd, hogy az alapértelmezett névterek, mint például alapértelmezett és kube-system, alapértelmezés szerint nem tartalmaznak címkéket.
Címkét az alábbi módon adhatunk hozzá egy névtérhez:
kubectl label namespace default namespace=default Ebben az esetben a namespace a metadata részben a tényleges név hivatkozására kell, hogy utaljon, nem pedig a címkére:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default # <<<
spec:
...Forrás és címzett
A tűzfal politikái forrásokból és címzettekből álló szabályokat tartalmaznak. A Kubernetes hálózati politikák célzottak - a podok összességére, amelyekre alkalmazzák őket, majd meghatározzák a bejövő (ingress) és/vagy kimenő (egress) forgalom szabályait. Példánkban a politika célja az összes pod a névtérben alapértelmezett a következő kulccsal rendelkező címkével app és az értékkel szolgáltatáshoz. A szolgáltatásrácsok általában mTLS segítségével oldják meg az ilyen problémákat: a tanúsítványok ebben az esetben szükséges azonosítóként szolgálnak.:
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 

Rész ingress ebben a politikában a célzott podok számára megnyitja a bejövő forgalmat. Más szóval, az ingress a forrást képviseli, míg a cél a megfelelő címzett. Hasonlóképpen az egress a címzett, a cél pedig a forrás.

Ez két tűzfal szabálynak felel meg: Ingress → Cél; Cél → Egress.
Egress és DNS (fontos!)
A kimenő forgalom korlátozása során külön figyelmet kell fordítani a DNS-re — a Kubernetes ezt a szolgáltatást használja a szolgáltatások IP-címekhez való hozzárendelésére. Például a következő politika nem fog működni, mivel nem engedélyezted az alkalmazásnak balance a DNS-hez való hozzáférést:
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 
Ezt úgy javíthatod, ha hozzáférést adsz a DNS szolgáltatáshoz:
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 
Az utolsó elem to üres, és ezért közvetve kiválasztja az összes podot minden névtérben, lehetővé téve a balance DNS-lekérdezések küldését a megfelelő Kubernetes szolgáltatásnak (általában a névtérben működik) kube-system).
Ez a megközelítés működőképes, de túlzottan engedélyezett és nem biztonságos, mivel lehetővé teszi a DNS-lekérdezések irányítását a klaszteren kívül.
Három lépésben javítható.
1. Engedélyezd a DNS-lekérdezéseket csak bent a klaszternek, a hozzáadásával 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. Csak DNS lekérdezéseket engedélyezhetünk a névtérben kube-system.
Ehhez címkét kell hozzáadni a névtérhez kube-system: kubectl label namespace kube-system namespace=kube-system — és bele kell írni a politikába 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. A paranoid emberek még tovább is elmehetnek, és korlátozhatják a DNS lekérdezéseket egy meghatározott DNS szolgáltatásra kube-system. A „Szűrés névterek és podok szerint” részben olvashat arról, hogyan érhető el ez.
Egy másik lehetőség, hogy a DNS-t névtéren belül engedélyezzük. Ez esetben nem kell azt minden szolgáltatás számára megnyitni:
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 Üres podSelector minden podot kiválaszt a névtérben.

Első egyezés és szabályok sorrendje
Hagyományos tűzfalaknál a cselekvés („Engedélyezés” vagy „Tiltás”) a csomagra vonatkozóan az első szabály alapján kerül meghatározásra, amelynek megfelel. A Kubernetesben a politikák sorrendje nem számít.
Alapértelmezés szerint, amikor nincsenek politikák megadva, a podok közötti kommunikáció engedélyezett, és szabadon cserélhetnek információt. Amint elkezd politikákat megfogalmazni, minden pod, amelyet bármelyik érint, izolálódik az összes olyan politika diszjunkt (logikai VAGY) hatásai szerint, amelyik választotta. Azok a podok, amelyeket egyetlen politika sem érint, nyitva maradnak.
Egy ilyen viselkedést törlési szabállyal lehet módosítani.
Törlési szabály („Tiltani”)
A tűzfalszabályok általában bármilyen kifejezetten nem engedélyezett forgalmat tiltani.
A Kubernetesben nincs „tiltani” (deny) cselekvés, azonban hasonló hatást elérhetünk egy szokásos (engedélyező) politikával, amely egy üres pod forráscsoportot választ (ingress):
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress 
Ez a politika minden pod-ot kiválaszt a névtérben, és az ingress-t határozatlanná hagyja, megtiltva minden bejövő forgalmat.
Hasonló módon korlátozhatjuk az összes kimenő forgalmat a névtérből:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress 
Ne feledje, hogy bármely további politika, amely engedélyezi a forgalmat a névtér pod-jaihoz, prioritással bír ezzel a szabállyal szemben (hasonlóan ahhoz, hogy egy engedélyező szabályt adunk hozzá egy tiltóhoz a tűzfalszabályzatban).
Mindet engedélyezni (Any-Any-Any-Allow)
Ahhoz, hogy létrehozzuk a „Mindent engedélyezni” politikát, kiegészítenünk kell a fent említett tilalmi politikát egy üres elemmel ingress:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
namespace: default
spec:
podSelector: {}
ingress: # <<<
- {} # <<<
policyTypes:
- Ingress 
Ez lehetővé teszi, hogy minden pod-ról minden névtérben (és minden IP-ről) hozzáférjünk bármely pod-hoz a névtérben alapértelmezett. Az ilyen viselkedés alapértelmezés szerint engedélyezett, így általában nem szükséges külön megadni. Néha azonban szükség lehet egyes konkrét engedélyek ideiglenes letiltására a probléma diagnosztizálása érdekében.
A szabályt szűkíthetjük, és csak a meghatározott pod-okhoz engedélyezhetjük a hozzáférést (app:balance) a névtérben alapértelmezett:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-to-balance
namespace: default
spec:
podSelector:
matchLabels:
app: balance
ingress:
- {}
policyTypes:
- Ingress 
A következő politika lehetővé teszi az összes bejövő (ingress) és kimenő (egress) forgalmat, beleértve a hozzáférést bármely IP-hez a klaszter határain kívül:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all
spec:
podSelector: {}
ingress:
- {}
egress:
- {}
policyTypes:
- Ingress
- Egress 

Több politika egyesítése
A politikák logikai VAGY operátorral egyesülnek három szinten; minden pod engedélyezett hozzáférése a rá vonatkozó összes politika diszjunkciójának megfelelően van meghatározva:
1. A mezőkben a és to háromféle elemet lehet megadni (mindegyik VAGY operátorral kombinálható):
-
namespaceSelector— az egész névtér kiválasztása; -
podSelector— pod-ok kiválasztása; -
ipBlock— alhálózat kiválasztása.
Ezeknél a alsorozatokban lévő elemek (még ha azonosak is) száma nincs korlátozva. Mindegyik logikai VAGY operátorral egyesítésre kerül. a/to не ограничено. Все они будут объединены логическим ИЛИ.
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. A politika belsejében ingress több elemet is tartalmazhat a (logikai VAGY formai összegzésük). Hasonló módon a szakasz egress több elemet is tartalmazhat to (ezek is diszjunkcióval összevonhatók):
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. A különböző politikák logikai VAGY-nal összevonhatók
De van egy korlátozás, amelyre : A Kubernetes csak különböző policyTypes (Ingress vagy Egress). Az ingress (vagy egress) politikák felülírják egymást.
Kapcsolat névtér között
Alapértelmezés szerint a névtér közötti információcsere engedélyezett. Ezt megváltoztathatja egy tiltó politikával, amely korlátozza a kimenő és/vagy bejövő forgalmat egy névtérben (lásd a fent említett 'Tisztító Szabályt').
Ha blokkolja a hozzáférést egy névtérben (lásd a fent említett 'Tisztító Szabályt'), akkor kivételeket tehet a tiltó politikában, engedélyezve a kapcsolatot egy adott névtérrel 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 
Ennek eredményeként minden pod a névtérben alapértelmezett hozzáférést kap a podokhoz postgres a névtérben database. De mi van, ha csak bizonyos podokhoz szeretne hozzáférést biztosítani a névtérben postgres Szűrés névterek és podok alapján alapértelmezett?
A Kubernetes 1.11-es és újabb verziói lehetővé teszik az operátorok kombinálását
logikai ÉS segítségével. Ez a következőképpen néz ki: namespaceSelector és 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
Miért értelmezzük ezt ÉS-ként, a megszokott VAGY helyett? 
nem kezdődik kötőjellel. A YAML-ban ez azt jelenti, hogy
p(x) – podSelector és ami előtte áll podSelector ugyanahhoz a listaelemhez tartoznak. Ezért logikai ÉS-ként egyesülnek. namespaceSelector Kötőjel hozzáadása előtt
Добавление дефиса перед podSelector egy új listaelem létrehozásához vezet, amely kombinálódik a korábbival namespaceSelector logikai VAGY használatával.
Címkés podok kiválasztásához minden névtérben, írjon be üreset 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 
Többszörös címkék kombinálódnak ÉS
A tűzfal szabályai több objektummal (hostokkal, hálózatokkal, csoportokkal) logikai VAGY segítségével kombinálódnak. A következő szabály akkor lép életbe, ha a csomag forrása megegyezik Host_1 VAGY Host_2:
| Forrás | Cél | Szolgáltatás | Akció |
| ----------------------------------------|
| Host_1 | Subnet_A | HTTPS | Engedélyez |
| Host_2 | | | |
| ----------------------------------------| Ellenkezőleg, a Kubernetesben a különböző címkék podSelector vagy namespaceSelector logikai ÉS segítségével kombinálódnak. Például a következő szabály olyan podokat választ, amelyek mindkét címkével rendelkeznek, role=db és version=v2:
podSelector:
matchLabels:
role: db
version: v2Ugyanez a logika vonatkozik minden operátor típusra: a politikai célok selektoraira, a pod selektorokra és a névtér selektorokra.
Alhálózatok és IP-címek (IPBlocks)
A hálózat szegmentálásához a tűzfalak VLAN-t, IP-címeket és alhálózatokat használnak.
A Kubernetesben az IP-címeket automatikusan a podokhoz rendelik, és gyakran változhatnak, ezért a podok és névterek kiválasztásához a hálózati politikákban címkéket használnak.
Alhálózatok (ipBlocks) a bejövő (ingress) vagy kimenő (egress) külső (North-South) kapcsolatok kezelésére használatosak. Például ez a politika lehetővé teszi minden pod számára a névtérből alapértelmezett hozzáférést a Google DNS-szolgáltatásához:
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 
A podok üres szelektora ebben a példában azt jelenti, hogy "válassza az összes podot a névtérben."
Ez a politika csak a 8.8.8.8-hoz biztosít hozzáférést; minden más IP elérhetőségét blokkolja. Így lényegében letiltotta a Kubernetes belső DNS-szolgáltatásához való hozzáférést. Ha mégis szeretné megnyitni, azt egyértelműen jelezni kell.
Általában ipBlocks és podSelectors kizárólagosak, mivel a podok belső IP-címei nem használatosak a ipBlocks. A podok belső IP-címeinek megadásával внутренние IP pod’ов, gyakorlatilag engedélyezi a pod-okhoz való csatlakozást ezekkel a címekkel. A gyakorlatban nem fogja tudni, melyik IP-címet használja, ezért ezeket nem szabad használni a pod-ok kiválasztásához.
Egy ellenpélda, amely a következő politikát tartalmazza, minden IP-t magában foglal, ezért hozzáférést biztosít az összes többi pod-hoz:
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 
Csak a külső IP-khez lehet hozzáférést biztosítani, kizárva a pod-ok belső IP-címeit. Például, ha a pod hálózati szegmense 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 
Portok és protokollok
Általában a pod-ok egy portot hallgatnak. Ez azt jelenti, hogy a politikákban egyszerűen nem szükséges megadni a port számokat, és mindent alapértelmezetten lehet hagyni. Mindazonáltal a politikákat a lehető legkorlátozóbban kell megalkotni, ezért bizonyos esetekben érdemes lehet megadni a portokat:
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 
Megjegyzendő, hogy a szelekciós portok alkalmazásra kerül az összes elemre a blokkban to vagy a, amelyben található. Különböző portokat különböző elemcsoportokhoz megadni úgy lehet, hogy ingress vagy egress több alrészre bontjuk to vagy a és mindegyikben a saját portjait rögzítjük:
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 
Alapértelmezetten a portok működése:
- Ha teljesen kihagyja a portok meghatározását (
portok), ez minden protokollt és minden portot jelent; - Ha a protokoll meghatározását kihagyja (
protocol), ez TCP-t jelent; - Ha a port meghatározását kihagyja (
port), ez minden portot jelent.
Legjobb gyakorlat: ne bízzon az alapértelmezett értékekben, határozza meg a szükségeseket egyértelműen.
Felhívjuk figyelmét, hogy a podok portjait, és nem a szolgáltatásokét kell használni (erről a következő bekezdésben olvashat).
A politikák podokhoz vagy szolgáltatásokhoz vannak definiálva?
A Kubernetesben általában a podok egymás között a szolgáltatáson keresztül kommunikálnak — egy virtuális terheléselosztó, amely a forgalmat a szolgáltatást megvalósító podokhoz irányítja. Lehet azt gondolni, hogy a hálózati politikák a szolgáltatásokhoz való hozzáférést szabályozzák, de ez nem így van. A Kubernetes hálózati politikák a podok portjain működnek, és nem a szolgáltatásokén.
Például, ha egy szolgáltatás a 80-as portot hallgatja, de a podok 8080-as portjára irányítja a forgalmat, akkor a hálózati politikában kifejezetten a 8080-as portot kell megadni.
Ez a mechanizmus nem optimális: a szolgáltatás belső felépítése (amelyet a podok portjai hallgatnak) változása esetén a hálózati politikákat is frissíteni kell.
Új architekturális megközelítés a Service Mesh használatával (például lásd Istio-t alább — a fordító megjegyzése) segít megoldani ezt a problémát.
Szükséges megadni mind az Ingress-t, mind az Egress-t?
A rövid válasz — igen, ahhoz, hogy az A pod kommunikálhasson a B poddal, engedélyeznie kell a kimenő kapcsolat létrehozását (ehhez Egress politikát kell beállítani), és a B podnak lehetőséget kell adnia a bejövő kapcsolat fogadására (ehhez, megfelelően, Ingress politikára van szükség).
A gyakorlatban azonban támaszkodhatunk egy alapértelmezett politikára, amely az egy vagy mindkét irányban történő kapcsolatok engedélyezésére vonatkozik.
Ha egy pod-forrás ki lesz választva egy vagy több egress-politikával, azokra vonatkozó korlátozások a diszjunktiójuk alapján fognak megvalósulni. Ebben az esetben kifejezetten engedélyezni kell a kapcsolatot a pod--címzettel.Ha a podot nem választotta ki egy politikai szabály, akkor a kimenő (Egress) forgalma alapértelmezés szerint engedélyezett.
Hasonlóképpen a pod--címzett sorsa, amelyet egy vagy több-politika választ ki, a diszjunktiójuk alapján fog megvalósulni. Ebben az esetben kifejezetten engedélyezni kell számára, hogy kimenő forgalmat fogadjon a pod-forrástól. Ha a podot nem választotta ki egy politikai szabály, akkor az összes bejövő (Ingress) forgalma alapértelmezés szerint engedélyezett. ingressLásd a «Stateful vagy Stateless» pontot alább.
A Kubernetes hálózati politikák nem képesek a forgalom naplózására. Ez megnehezíti annak meghatározását, hogy a politika megfelelően működik-e, és jelentősen megnehezíti a biztonsági elemzést.
Naplok
A forgalom ellenőrzése a külső szolgáltatások felé.
Контроль за трафиком к внешним сервисам
A Kubernetes hálózati politikák nem engedélyezik teljes domain név (DNS) megadását az egress szekciókban. Ez a tény jelentős kényelmetlenséget okoz, amikor a forgalmat külső címzettekhez szeretnénk korlátozni, akiknek nincs fix IP-címük (például aws.com).
Politika ellenőrzése
A tűzfalak figyelmeztetnek vagy akár elutasítják a hibás politikát. A Kubernetes is végez némi ellenőrzést. Amikor a hálózati politikát a kubectl-en keresztül adjuk meg, a Kubernetes jelezheti, hogy az helytelen, és elutasíthatja azt. Más esetekben a Kubernetes elfogadja a politikát, és kiegészíti a hiányzó részletekkel. Ezeket a következő parancs segítségével nézheti meg:
kubernetes get networkpolicy -o yamlNe feledje, hogy a Kubernetes ellenőrző rendszere nem tévedhetetlen, és bizonyos típusú hibákat átugorhat.
Végrehajtás
A Kubernetes nem valósítja meg a hálózati politikákat saját magától, csupán API-híd, amely a költséges ellenőrzési feladatot egy alsóbb szintű rendszerre, a Container Networking Interface (CNI)-re hárítja. A politikák megadása a Kubernetes klaszterben CNI hozzárendelése nélkül egyenértékű a tűzfalkezelő szerver politikáinak létrehozásával anélkül, hogy azokat később telepítené a tűzfalkészülékekre. Önnek magának kell biztosítania a megfelelő CNI-t, vagy, ha a Kubernetes platform felhőben van telepítve, (a szolgáltatók listáját itt találja) — szerk. megj., alkalmazhatja a hálózati politikákat, amelyek beállítják a CNI-t ön helyett.
Vegye észre, hogy a Kubernetes nem figyelmeztet, ha hálózati politikát ad meg a megfelelő támogatói CNI nélkül.
Stateful vagy Stateless?
Minden CNI, amellyel találkoztam a Kubernetes rendszerében állapotot tart fenn (például a Calico Linux conntrack-et használ). Ez lehetővé teszi a pod számára, hogy válaszokat kapjon az általa kezdeményezett TCP-kapcsolaton anélkül, hogy azt újra kellene indítania. Ezen kívül nem tudok olyan Kubernetes szabványról, amely garantálná az állapot kezelését (statefulness).
Fejlett biztonságpolitikai kezelés
Néhány módja van a biztonságpolitika végrehajtásának hatékonyságának növelésére a Kubernetes rendszerében:
- A Service Mesh architekturális minta sidecar-konténereket használ a részletes telemetria és forgalomellenőrzés biztosítása érdekében, szintetizálva a szolgáltatások szintjén. Például... .
- Néhány CNI szolgáltató bővítette eszközeit, hogy túllépjenek a Kubernetes hálózati politikáin.
- átláthatóságot és automatizálást biztosít a Kubernetes hálózati politikáihoz.
A Tufin Orca csomag kezeli a Kubernetes hálózati politikáit (és forrást biztosít a fenti képernyőképekhez).
Dokumentáció
- ;
- ;
- ;
- .
Zárás
A Kubernetes hálózati politikák elég jó szerszámkészletet kínálnak a klaszterek szegmentálásához, azonban nem intuitívak, és számos finomságuk van. Úgy vélem, hogy e bonyolultság miatt sok meglévő klaszter politikái hibásak. E probléma lehetséges megoldásai a politikai határozatok automatizálása vagy más szegmentáló eszközök alkalmazása.
Remélem, hogy ez az útmutató segít tisztázni néhány kérdést és megoldani azokat a problémákat, amelyekkel szembesülhet.
Fejlesztési eszközök, amelyek Kubernetesben futnak
Olvasson további információkat a blogunkban:
- „Vissza a mikroszolgáltatásokhoz az Istióval”: , , ;
- „Illusztrált útmutató a Kubernetes hálózatának felépítéséhez“: , ;
- «»;
- «»;
- «».
Forrás: habr.com
