Hinweis perev. : Der Autor des Artikels - Reuven Harrison - verfügt über mehr als 20 Jahre Erfahrung in der Softwareentwicklung und ist heute technischer Direktor und Mitbegründer von Tufin, einem Unternehmen, das Lösungen für das Management von Sicherheitsrichtlinien entwickelt. In Anbetracht der Kubernetes-Netzwerkrichtlinien als leistungsstarkes Tool für die Netzwerksegmentierung in einem Cluster ist er der Ansicht, dass sie in der Praxis nicht so einfach anzuwenden sind. Dieses Material (ziemlich umfangreich) soll das Wissen von Spezialisten auf diesem Gebiet verbessern und ihnen bei der Erstellung der erforderlichen Konfigurationen helfen. Heutzutage entscheiden sich viele Unternehmen zunehmend für Kubernetes, um ihre Anwendungen auszuführen. Das Interesse an dieser Software ist so groß, dass manche Kubernetes als "neues Betriebssystem für Rechenzentren" bezeichnen. Allmählich wird Kubernetes (oder k8s) als kritischer Teil des Geschäfts wahrgenommen, der die Organisation ausgereifter Geschäftsprozesse einschließlich der Netzwerksicherheit erfordert.
Für Sicherheitsexperten, die durch die Arbeit mit Kubernetes verwirrt sind, kann die Standardrichtlinie dieser Plattform eine echte Entdeckung sein: Lassen Sie alles zu.
Dieses Handbuch hilft Ihnen beim Verständnis der internen Struktur von Netzwerkrichtlinien. Verstehen Sie, wie sie sich von den Regeln für normale Firewalls unterscheiden. Es werden auch einige Fallstricke beschrieben und Empfehlungen gegeben, die zum Schutz von Anwendungen in Kubernetes beitragen.
Kubernetes-Netzwerkrichtlinien
Mit dem Netzwerkrichtlinienmechanismus von Kubernetes können Sie die Interaktion von Anwendungen steuern, die auf der Plattform auf Netzwerkebene bereitgestellt werden (die dritte im OSI-Modell). In Netzwerkrichtlinien fehlen einige der erweiterten Funktionen moderner Firewalls, wie z. B. die Überwachung von OSI Level 7 und die Erkennung von Bedrohungen. Sie bieten jedoch ein grundlegendes Maß an Netzwerksicherheit, was ein guter Ausgangspunkt ist.
Netzwerkrichtlinien steuern die Kommunikation zwischen Pods
Kubernetes-Workloads werden auf Pods verteilt, die aus einem oder mehreren zusammen bereitgestellten Containern bestehen. Kubernetes weist jedem Pod eine IP-Adresse zu, auf die von anderen Pods aus zugegriffen werden kann. In den Netzwerkrichtlinien von Kubernetes werden Berechtigungen für Pod-Gruppen auf dieselbe Weise festgelegt wie Sicherheitsgruppen in der Cloud, um den Zugriff auf Instanzen virtueller Maschinen zu steuern.
Netzwerkrichtlinien definieren
Wie bei anderen Kubernetes-Ressourcen werden Netzwerkrichtlinien in YAML festgelegt. Im folgenden Beispiel wird dem
balance
Zugriff auf
postgres
gewährt:
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
( Hinweis : Dieser Screenshot wurde wie alle nachfolgenden ähnlichen nicht mit den nativen Tools von Kubernetes erstellt, sondern mit dem Tufin Orca-Tool, das vom Autor des Originalartikels entwickelt und am Ende des Artikels erwähnt wurde.)Das Definieren Ihrer eigenen Netzwerkrichtlinie erfordert grundlegende YAML-Kenntnisse. Diese Sprache basiert auf Einrückungen (angegeben durch Leerzeichen, nicht durch Tabulatoren). Ein eingerücktes Element gehört zum nächsten eingerückten Element darüber. Ein neues Listenelement beginnt mit einem Bindestrich, alle anderen Elemente sind
Schlüsselwerte .
Nachdem Sie die Richtlinie in YAML
beschrieben haben , erstellen Sie sie mit
kubectl im Cluster:
kubectl create -f policy.yaml
Netzwerkrichtlinienspezifikation
Die Kubernetes-Netzwerkrichtlinienspezifikation enthält vier Elemente:
podSelector
: podSelector
die von dieser Richtlinie betroffenen Pods (Ziele) - obligatorisch;policyTypes
: policyTypes
an, welche Arten von Richtlinien darin enthalten sind: Ingress und / oder Egress - optional. Ich empfehle jedoch, dass Sie sie in allen Fällen explizit registrieren.ingress
: Definiert den zulässigen eingehenden Verkehr zu den Ziel-Pods - optional;egress
: Definiert den zulässigen ausgehenden Datenverkehr von den Ziel-Pods - optional.
Ein Beispiel von der Kubernetes-Website (ich habe die
role
durch die
app
) zeigt, wie alle vier Elemente verwendet werden:
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


Bitte beachten Sie, dass alle vier Elemente optional sind. Es wird nur
podSelector
, andere Parameter können nach Wunsch verwendet werden.
Wenn Sie
policyTypes
weglassen, wird die Richtlinie wie folgt interpretiert:
- Standardmäßig wird davon ausgegangen, dass es die Eingangsseite definiert. Wenn die Richtlinie dies nicht ausdrücklich angibt, wird das System berücksichtigen, dass der gesamte Datenverkehr verboten ist.
- Das Verhalten auf der Austrittsseite wird durch das Vorhandensein oder Fehlen des entsprechenden Austrittsparameters bestimmt.
Um Fehler zu vermeiden, empfehle ich
, policyTypes
immer explizit anzugeben .
In Übereinstimmung mit der obigen Logik verbietet die Richtlinie den gesamten Datenverkehr, wenn die
ingress
und / oder
egress
weggelassen werden (siehe "Stripping-Regel" unten).
Die Standardrichtlinie lautet Zulassen
Wenn keine Richtlinien definiert sind, lässt Kubernetes standardmäßig den gesamten Datenverkehr zu. Alle Pods können Informationen miteinander austauschen. Aus Sicherheitsgründen mag dies nicht intuitiv erscheinen, aber denken Sie daran, dass Kubernetes ursprünglich von Entwicklern erstellt wurde, um die Interoperabilität von Anwendungen sicherzustellen. Netzwerkrichtlinien wurden später hinzugefügt.
Namespaces
Namespaces sind ein kollaborativer Mechanismus von Kubernetes. Sie dienen dazu, logische Umgebungen voneinander zu isolieren, während der Datenaustausch zwischen Leerzeichen standardmäßig zulässig ist.
Wie die meisten Kubernetes-Komponenten befinden sich Netzwerkrichtlinien in einem bestimmten Namespace. Im
metadata
können Sie angeben, zu welchem Bereich die Richtlinie gehört:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: my-namespace # <<< spec: ...
Wenn der Namespace nicht explizit in die Metadaten geschrieben wird, verwendet das System den in kubectl angegebenen Namespace (standardmäßig
namespace=default
):
kubectl apply -n my-namespace -f namespace.yaml
Ich empfehle
, einen Namespace explizit anzugeben, es sei denn, Sie schreiben eine Richtlinie, die für mehrere Namespaces gleichzeitig vorgesehen ist.
Das Hauptelement
podSelector
in einer Richtlinie wählt Pods aus dem Namespace aus, zu dem die Richtlinie gehört (der Zugriff auf Pods aus einem anderen Namespace wird verweigert).
In ähnlicher Weise können podSelectors
in Eingangs-
und Ausgangsblöcken Pods nur aus ihrem Namespace auswählen, es sei denn, Sie kombinieren sie natürlich mit
namespaceSelector
(dies wird im Abschnitt „Filtern nach Namespaces und Pods“ erläutert). .
Richtlinienbenennungsregeln
Richtliniennamen sind innerhalb eines einzelnen Namespace eindeutig. Es können keine zwei Richtlinien mit demselben Namen in einem Bereich vorhanden sein, aber es können Richtlinien mit demselben Namen in verschiedenen Bereichen vorhanden sein. Dies ist nützlich, wenn Sie dieselbe Richtlinie auf mehrere Bereiche erneut anwenden möchten.
Ich mag besonders eine Art zu benennen. Es besteht darin, den Namespace-Namen mit den Ziel-Pods zu kombinieren. Zum Beispiel:
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

Etiketten
Benutzerdefinierte Beschriftungen können an Kubernetes-Objekte wie Pods und Namespaces angehängt werden. Beschriftungen entsprechen Tags in der Cloud. Kubernetes-Netzwerkrichtlinien verwenden Beschriftungen, um die
Pods auszuwählen, für die sie gelten:
podSelector: matchLabels: role: db
... oder
die Namespaces, für die sie gelten. In diesem Beispiel werden alle Pods in den Namespaces mit den entsprechenden Beschriftungen ausgewählt:
namespaceSelector: matchLabels: project: myproject
Eine Einschränkung: Wenn Sie
namespaceSelector
stellen Sie sicher, dass die von Ihnen ausgewählten namespaceSelector
die gewünschte Bezeichnung enthalten .
kube-system
Sie, dass integrierte Namespaces wie
default
und
kube-system
standardmäßig keine Beschriftungen enthalten.
Sie können dem Bereich wie folgt eine Beschriftung hinzufügen:
kubectl label namespace default namespace=default
In diesem Fall sollte sich der Namespace im
metadata
auf den tatsächlichen Namen des Space und nicht auf die Bezeichnung beziehen:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default # <<< spec: ...
Quelle und Ziel
Richtlinien für Firewalls bestehen aus Regeln mit Quellen und Zielen. Kubernetes Netzwerkrichtlinien werden für diesen Zweck definiert - eine Reihe von Pods, auf die sie angewendet werden, und legen dann Regeln für eingehenden (eingehenden) und / oder ausgehenden (ausgehenden) Verkehr fest. In unserem Beispiel sind das Richtlinienziel alle Pods im
default
Namespace mit einer Bezeichnung mit dem
app
Schlüssel und dem
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


Der Eingangsunterabschnitt in dieser Richtlinie öffnet eingehenden Datenverkehr für die Ziel-Pods. Mit anderen Worten, Ingress ist die Quelle und das Ziel ist der geeignete Empfänger. In ähnlicher Weise ist der Ausgang das Ziel und das Ziel ist seine Quelle.
Dies entspricht zwei Regeln für die Firewall: Ingress → Target; Ziel → Austritt.Ausgang und DNS (wichtig!)
Achten Sie bei der Begrenzung des ausgehenden Datenverkehrs
besonders auf DNS. Kubernetes verwendet diesen Dienst, um Dienste IP-Adressen zuzuordnen. Die folgende Richtlinie funktioniert beispielsweise nicht, da Sie der
balance
Anwendung keinen Zugriff auf DNS gewährt haben:
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

Sie können das Problem beheben, indem Sie den Zugriff auf den DNS-Dienst öffnen:
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

Das letzte to-Element ist leer und wählt daher indirekt
alle Pods in allen Namespaces aus , sodass
balance
DNS-Abfragen an den entsprechenden Kubernetes-Dienst senden kann (dies funktioniert normalerweise im
kube-system
).
Dieser Ansatz funktioniert, ist jedoch zu
freizügig und unsicher , da Sie damit DNS-Abfragen außerhalb des Clusters leiten können.
Sie können es in drei aufeinander folgenden Schritten verbessern.
1. Erlauben Sie DNS-Abfragen nur
innerhalb des Clusters, indem Sie
namespaceSelector
hinzufügen:
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. Erlauben Sie DNS-Abfragen nur im Namespace des
kube-system
.
kubectl label namespace kube-system namespace=kube-system
eine Bezeichnung
kube-system
:
kubectl label namespace kube-system namespace=kube-system
- und registrieren Sie sie mit
namespaceSelector
in der Richtlinie:
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. Paranoide können noch weiter gehen und DNS-Abfragen auf einen bestimmten DNS-Dienst im
kube-system
. Im Abschnitt „Filtern nach Namespaces & Pods“ wird erläutert, wie dies erreicht wird.
Eine weitere Option ist das Auflösen von DNS auf Namespace-Ebene. In diesem Fall muss es nicht für jeden Dienst geöffnet werden:
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
Ein leerer
podSelector
wählt alle Pods im Namespace aus.

Erste Übereinstimmung und Regelreihenfolge
In normalen Firewalls wird die Aktion ("Zulassen" oder "Verweigern") für ein Paket durch die erste Regel bestimmt, die es erfüllt.
In Kubernetes spielt die Reihenfolge der Richtlinien keine Rolle.Wenn keine Richtlinien festgelegt sind, ist standardmäßig die Kommunikation zwischen Pods zulässig und sie können Informationen frei austauschen. Sobald Sie mit der Formulierung von Richtlinien beginnen, wird jeder von mindestens einer davon betroffene Pod gemäß der Disjunktion (logisches ODER) aller Richtlinien, die ihn ausgewählt haben, isoliert. Pods, die von keiner Richtlinie betroffen sind, bleiben geöffnet.
Sie können dieses Verhalten mithilfe der Abisolierregel ändern.
Abisolierregel (Verweigern)
Firewall-Richtlinien verbieten im Allgemeinen explizit nicht autorisierten Datenverkehr.
Kubernetes hat keine Verweigerungsaktion . Ein ähnlicher Effekt kann jedoch mit einer regulären (zulässigen) Richtlinie erzielt werden, indem eine leere Gruppe von Quell-Pods (Eingang) ausgewählt wird:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: default spec: podSelector: {} policyTypes: - Ingress

Diese Richtlinie wählt alle Pods im Namespace aus und lässt den Eingang undefiniert, wodurch der gesamte eingehende Datenverkehr blockiert wird.
Ebenso können Sie den gesamten ausgehenden Datenverkehr aus dem Namespace begrenzen:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-egress namespace: default spec: podSelector: {} policyTypes: - Egress

Beachten Sie, dass
alle zusätzlichen Richtlinien, die den Datenverkehr zu Pods im Namespace zulassen, Vorrang vor dieser Regel haben (ähnlich wie beim Hinzufügen einer Zulassungsregel über eine Verweigerungsregel in der Firewall-Konfiguration).
Alle zulassen (Any-Any-Any-Allow)
Um eine Allow All-Richtlinie zu erstellen, müssen Sie die oben genannte Verbotsrichtlinie mit einem leeren
ingress
Element hinzufügen:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all namespace: default spec: podSelector: {} ingress: # <<< - {} # <<< policyTypes: - Ingress

Es ermöglicht den Zugriff von
allen Pods in allen Namespaces (und allen IPs) auf alle Pods im default
Namespace . Dieses Verhalten ist standardmäßig aktiviert und muss daher normalerweise nicht zusätzlich definiert werden. Manchmal kann es jedoch erforderlich sein, bestimmte Berechtigungen vorübergehend zu deaktivieren, um das Problem zu diagnostizieren.
Die Regel kann eingegrenzt werden und nur auf einen
bestimmten Satz von Pods (
app:balance
) im
default
Namespace zugreifen:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-to-balance namespace: default spec: podSelector: matchLabels: app: balance ingress: - {} policyTypes: - Ingress

Die folgende Richtlinie ermöglicht den gesamten eingehenden und ausgehenden Datenverkehr, einschließlich des Zugriffs auf IP-Adressen außerhalb des Clusters:
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {} egress: - {} policyTypes: - Ingress - Egress


Mehrere Richtlinien kombinieren
Richtlinien werden mithilfe des logischen ODER auf drei Ebenen kombiniert. Die Berechtigungen für jeden Pod werden in Übereinstimmung mit der Disjunktion aller Richtlinien festgelegt, die ihn betreffen:
1. In den Feldern
from
und
to
können Sie drei Arten von Elementen definieren (alle werden mit ODER kombiniert):
namespaceSelector
- Wählt den gesamten Namespace aus.podSelector
- wählt Pods aus;ipBlock
- wählt ein Subnetz aus.
Gleichzeitig ist die Anzahl der Elemente (auch der gleichen) in den Unterabschnitten
from
/
to
nicht begrenzt. Alle von ihnen werden durch logisches ODER kombiniert.
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. Innerhalb der Richtlinie kann der
ingress
viele Elemente enthalten (kombiniert durch logisches ODER). In ähnlicher Weise kann der
egress
viele Elemente enthalten (auch durch eine Klausel verbunden):
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. Verschiedene Richtlinien werden auch durch logisches ODER kombiniert
Beim Kombinieren gibt es jedoch eine Einschränkung, auf die
Chris Cooney hingewiesen hat : Kubernetes kann Richtlinien nur mit verschiedenen
policyTypes
(
Ingress
oder
Egress
) kombinieren. Die Richtlinien, die den Eingang (oder Ausgang) definieren, überschreiben sich gegenseitig.
Die Beziehung zwischen Namespaces
Standardmäßig ist der Informationsaustausch zwischen Namespaces zulässig. Dies kann mithilfe einer unzulässigen Richtlinie geändert werden, die ausgehenden und / oder eingehenden Datenverkehr in den Namespace einschränkt (siehe "Stripping-Regel" oben).
Durch Blockieren des Zugriffs auf den Namespace (siehe "Stripping-Regel" oben) können Sie Ausnahmen von der restriktiven Richtlinie machen, indem Sie Verbindungen von einem bestimmten Namespace mit
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

Infolgedessen haben alle Pods im
default
Namespace Zugriff auf die
postgres
Pods im
database
Namespace. Was aber, wenn Sie den Zugriff auf
postgres
nur für bestimmte Pods im
default
Namespace öffnen möchten?
Filtern nach Namespaces & Pods
Mit Kubernetes Version 1.11 und höher können Sie die Operatoren
namespaceSelector
und
podSelector
mit logischem I kombinieren. Es sieht folgendermaßen aus:
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

Warum wird es als UND anstelle des üblichen ODER interpretiert?
Beachten Sie, dass
podSelector
nicht mit einem Bindestrich beginnt. In YAML bedeutet dies, dass sich
podSelector
und der davor stehende
namespaceSelector
auf dasselbe Listenelement beziehen. Daher werden sie durch logisches I kombiniert.
Das Hinzufügen eines Bindestrichs vor
podSelector
führt zu einem neuen Listenelement, das mit dem vorherigen
namespaceSelector
mithilfe eines logischen ODER kombiniert wird.
Geben Sie einen leeren
namespaceSelector
ein, um Pods mit einer bestimmten Bezeichnung
in allen Namespaces auszuwählen:
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

Mehrere Beschriftungen werden mit UND kombiniert
Regeln für eine Firewall mit vielen Objekten (Hosts, Netzwerke, Gruppen) werden mithilfe eines logischen ODER kombiniert. Die folgende Regel funktioniert, wenn die Quelle des Pakets mit
Host_1
ODER
Host_2
:
| Source | Destination | Service | Action | | ----------------------------------------| | Host_1 | Subnet_A | HTTPS | Allow | | Host_2 | | | | | ----------------------------------------|
Umgekehrt werden in Kubernetes verschiedene Beschriftungen in
podSelector
oder
namespaceSelector
durch logisches I kombiniert. Mit der folgenden Regel werden beispielsweise Pods ausgewählt, die beide Beschriftungen haben:
role=db
AND
version=v2
:
podSelector: matchLabels: role: db version: v2
Die gleiche Logik gilt für alle Arten von Operatoren: Richtlinienzielselektoren, Pod-Selektoren und Namespace-Selektoren.
Subnetze und IP-Adressen (IPBlocks)
Firewalls verwenden VLANs, IP-Adressen und Subnetze, um ein Netzwerk zu segmentieren.
In Kubernetes werden Pods automatisch IP-Adressen zugewiesen und können sich häufig ändern. Daher werden Beschriftungen verwendet, um Pods und Namespaces in Netzwerkrichtlinien auszuwählen.
ipBlocks
(
ipBlocks
) werden verwendet, um eingehende (eingehende) oder ausgehende (ausgehende) externe (Nord-Süd) Verbindungen zu steuern. Diese Richtlinie gewährt beispielsweise allen Pods aus dem
default
Namespace Zugriff auf den Google DNS-Dienst:
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

Der leere Pod-Selektor in diesem Beispiel bedeutet "Alle Pods im Namespace auswählen".
Diese Richtlinie bietet nur Zugriff auf 8.8.8.8; Der Zugriff auf eine andere IP wird verweigert. Daher haben Sie im Wesentlichen den Zugriff auf den internen DNS-Dienst von Kubernetes blockiert. Wenn Sie es dennoch öffnen möchten, geben Sie es explizit an.
Normalerweise schließen sich
ipBlocks
und
podSelectors
gegenseitig aus, da die internen IP-Adressen von Pods in
ipBlocks
nicht verwendet
ipBlocks
.
Indem Sie interne IP-Pods angeben , lassen Sie tatsächlich Verbindungen zu / von Pods mit diesen Adressen zu. In der Praxis wissen Sie nicht, welche IP-Adresse Sie verwenden sollen, weshalb sie nicht zur Auswahl von Pods verwendet werden sollten.
Als Gegenbeispiel enthält die folgende Richtlinie alle IPs und ermöglicht daher den Zugriff auf alle anderen Pods:
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

Sie können den Zugriff nur auf externe IPs öffnen, indem Sie die internen IP-Adressen von Pods ausschließen. Wenn das Subnetz Ihres Pods beispielsweise 10.16.0.0/14 lautet:
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

Ports und Protokolle
Normalerweise lauschen Pods an einem Port. Dies bedeutet, dass Sie Portnummern in Richtlinien einfach weglassen und alles als Standard belassen können. Es wird jedoch empfohlen, die Richtlinien so restriktiv wie möglich zu gestalten, sodass Sie in einigen Fällen weiterhin Ports angeben können:
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

Beachten Sie, dass der
ports
Selektor für alle Elemente in dem darin enthaltenen to- oder
from
Block gilt. Um verschiedene Ports für verschiedene
egress
anzugeben, teilen Sie den
ingress
oder
egress
in mehrere Unterabschnitte mit oder
from
und auf und listen Sie Ihre Ports in jedem auf:
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

Die Standardports funktionieren:
- Wenn Sie die Definition von Ports vollständig weglassen, bedeutet dies alle Protokolle und alle Ports.
- Wenn Sie die Protokolldefinition weglassen, bedeutet dies TCP.
- Wenn Sie die Definition eines Ports weglassen, bedeutet dies alle Ports.
Best Practice: Verlassen Sie sich nicht auf die Standardwerte, sondern geben Sie explizit an, was Sie benötigen.
Bitte beachten Sie, dass Pod-Ports und keine Dienste verwendet werden müssen (mehr dazu im nächsten Absatz).
Sind Richtlinien für Pods oder Services definiert?
Normalerweise kontaktieren sich Pods in Kubernetes über einen Dienst - einen virtuellen Load Balancer, der den Datenverkehr zu Pods umleitet, die den Dienst implementieren. Sie könnten denken, dass Netzwerkrichtlinien den Zugriff auf Dienste steuern, dies ist jedoch nicht der Fall.
Kubernetes-Netzwerkrichtlinien funktionieren mit Pod-Ports, nicht mit Diensten., 80- , 8080 pod', 8080.
: ( pod') .
Service Mesh
(, . Istio — . .) .
Ingress, Egress?
— , pod pod' , ( egress-), pod ( , , ingress-).
, .
pod-
egress -, . pod'-
. pod - , (egress) .
pod'-
,
ingress -, . pod'-. pod - , (ingress) .
. «Stateful Stateless» .
Kubernetes . , , .
Kubernetes (DNS) egress. , IP- ( aws.com).
. Kubernetes . kubectl Kubernetes , , . Kubernetes . :
kubernetes get networkpolicy <policy-name> -o yaml
, Kubernetes .
Ausführung
Kubernetes , API-, , Container Networking Interface (CNI). Kubernetes CNI . CNI , Kubernetes,
( — . .) , , CNI .
, Kubernetes , CNI.
Stateful Stateless?
CNI Kubernetes, , (, Calico Linux conntrack). pod' TCP- . Kubernetes, (statefulness).
Kubernetes:
- Service Mesh sidecar- . Istio .
- CNI , Kubernetes.
- Tufin Orca Kubernetes.
Tufin Orca Kubernetes ( , ).
Fazit
Kubernetes , . , - . .
, , .
PS vom Übersetzer
Lesen Sie auch in unserem Blog: