Einführung in die Kubernetes-Netzwerkrichtlinien für Sicherheitsexperten



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:

  1. podSelector : podSelector die von dieser Richtlinie betroffenen Pods (Ziele) - obligatorisch;
  2. 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.
  3. ingress : Definiert den zulässigen eingehenden Verkehr zu den Ziel-Pods - optional;
  4. 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:

  1. Service Mesh sidecar- . Istio .
  2. CNI , Kubernetes.
  3. Tufin Orca Kubernetes.

Tufin Orca Kubernetes ( , ).



Fazit


Kubernetes , . , - . .

, , .

PS vom Übersetzer


Lesen Sie auch in unserem Blog:

Source: https://habr.com/ru/post/de443190/


All Articles