← Übersicht  ·  Skripte & Dateien  ·  cloud-host · OpenShift · Betrieb

NetworkPolicy in OpenShift

Das Modell steht in Atlas-Diagramm F2. Hier spielst du es von Hand durch: ab Werk darf jeder Pod jeden erreichen – eine NetworkPolicy schaltet das ab, du siehst den Traffic wirklich brechen, und erlaubst gezielt wieder. Plus die zwei Fallen, die jedem passieren. EX280-relevant.

Stand: 4. September 2026 OKD 4.x / OCP 4.x ns library

Voraussetzung: ein Cluster mit oc login, Namespace library mit mindestens zwei laufenden Pods (z. B. catalog-service und api-gateway). Alles hier wirkt sofort, ohne Pod-Neustart – OVN (F1) erzwingt die Regeln direkt.

1 Default-allow, live

Ab Werk gilt default-allow: jeder Pod erreicht jeden Pod, clusterweit. Ein Namespace ist eine RBAC- und Quota-Grenze (A2), aber keine Netz-Grenze.

Laptop · Bash
# von einem Pod aus einen anderen Pod erreichen - geht ab Werk:
oc rsh -n library deploy/api-gateway curl -s -o /dev/null -w '%{http_code}\n' \
  http://catalog-service:8080/actuator/health

# es gibt noch keine einzige Policy:
oc get netpol -n library

Eine NetworkPolicy, die per podSelector eine Pod-Menge auswählt, schaltet genau diese Pods auf default-deny – aber nur für die Richtungen (ingress/egress), die sie überhaupt nennt. Eine Policy ohne egress-Block ändert am Egress nichts.

2 deny-all-ingress anlegen

Jetzt brechen wir den Traffic wirklich – und sehen es.

Laptop · Bash
cat <<'YAML' | oc apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: library
spec:
  podSelector: {}
  policyTypes: [Ingress]
YAML

# derselbe Aufruf wie eben - jetzt bricht er:
oc rsh -n library deploy/api-gateway curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 \
  http://catalog-service:8080/actuator/health
# Timeout oder Connection refused - sofort, kein Pod-Neustart noetig

podSelector: {} (leer) wählt alle Pods im Namespace. policyTypes: [Ingress] begrenzt die Wirkung auf eingehenden Verkehr – Egress bleibt unangetastet.

3 Gezielt wieder erlauben

Laptop · Bash
cat <<'YAML' | oc apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-from-api-gateway
  namespace: library
spec:
  podSelector:
    matchLabels: { app: catalog-service }
  policyTypes: [Ingress]
  ingress:
  - from:
    - podSelector:
        matchLabels: { app: api-gateway }
    ports:
    - port: 8080
YAML

oc rsh -n library deploy/api-gateway curl -s -o /dev/null -w '%{http_code}\n' \
  http://catalog-service:8080/actuator/health
# 200 - api-gateway darf wieder rein. Jeder ANDERE Pod bleibt draussen

Zwei Policies auf demselben Pod (deny-all-ingress wählt ihn per podSelector: {} mit) – sie summieren sich, dazu mehr in Schritt 5.

4 Die Selektoren

Selektorwählt
podSelectorPods per Label, im eigenen Namespace
namespaceSelectoralle Pods in Namespaces mit passendem Label – für Verkehr zwischen Namespaces
podSelector + namespaceSelector zusammennur Pods mit beiden Labels (UND-Verknüpfung), im genannten Namespace
ipBlockein CIDR-Bereich, optional mit except – für Verkehr von/zu ausserhalb des Clusters
portsschränkt zusätzlich auf bestimmte Ports/Protokolle ein
Beispiel: aus jedem Namespace mit Label
  ingress:
  - from:
    - namespaceSelector:
        matchLabels: { network.openshift.io/policy-group: ingress }   # der Router-Namespace

5 Mehrere Policies summieren

Es gibt kein deny in einer NetworkPolicy – nur Auswahl und Allow.

1 Policywählt sie einen Pod aus, schaltet er für die genannte Richtung auf default-deny
mehrere Policiestreffen mehrere Policies denselben Pod, gilt die Vereinigung aller ingress/egress-Regeln – nie eine schränkt eine andere ein
AdminNetworkPolicyclusterweit, admin-owned, OVN-Erweiterung – wird vor den Namespace-Policies ausgewertet und kann explizit verbieten (Deny-Aktion), anders als die normale NetworkPolicy

Praktisch: eine breite deny-all-ingress plus mehrere kleine, gezielte allow-from-<dienst>-Policies ist der übliche Aufbau – nie eine einzige riesige Policy pflegen.

6 Zwei Fallen: DNS und Probes

FalleSymptomFix
DNSeine Egress-Policy ohne Regel für openshift-dns (Port 53) – die Namensauflösung bricht, alles läuft in Timeouts, nicht nur der gemeinte VerkehrEgress-Policies bekommen immer eine Ausnahme für DNS mit
ProbesHealth-Probes (B5) kommen vom kubelet, nicht von einem Pod – ein zu enges podSelector in der from-Liste blockt sie, der Pod geht auf NotReadyProbes brauchen keine extra Regel (sie laufen node-lokal), aber prüfen: kommt der Traffic wirklich von einem „Pod“ oder vom Node selbst
Laptop · Bash · DNS-Ausnahme
cat <<'YAML' | oc apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: library
spec:
  podSelector: {}
  policyTypes: [Egress]
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - { protocol: UDP, port: 53 }
    - { protocol: TCP, port: 53 }
YAML

7 Egress-Policy

Genau umgekehrt: nur den Traffic raus einschränken, Ingress bleibt offen.

Laptop · Bash
# testen: kann catalog-service gerade irgendwohin raus?
oc rsh -n library deploy/catalog-service curl -s -o /dev/null -w '%{http_code}\n' --max-time 5 \
  http://api-gateway:8080/actuator/health

# Egress auf nur Postgres + DNS begrenzen (DNS-Ausnahme aus Schritt 6 vorausgesetzt):
cat <<'YAML' | oc apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: catalog-egress-db-only
  namespace: library
spec:
  podSelector:
    matchLabels: { app: catalog-service }
  policyTypes: [Egress]
  egress:
  - to:
    - podSelector:
        matchLabels: { app.kubernetes.io/name: postgresql }
    ports:
    - { port: 5432 }
YAML
# jetzt bricht der Aufruf zu api-gateway - Egress ist jetzt auf Postgres beschraenkt

Egress-Policies sind seltener als Ingress-Policies (das Risiko liegt meist im Reinkommen), aber genau richtig für einen Dienst, der nur zu seiner eigenen DB darf und sonst nirgendwohin – ein kompromittierter Pod kann dann nicht querschlagen.

8 Wie die Bibliothek es macht

PolicyWirkung
deny-all-ingressBasis im Namespace library – ab hier ist alles zu
allow-from-routerIngress für api-gateway und library-frontend nur aus openshift-ingress (der Router-Namespace, B4) – die einzigen zwei Dienste mit einer Route
allow-internaldie 8 Spring-Dienste + Bitnami-Infra reden untereinander über podSelector auf gemeinsame Labels – kein Dienst ist von aussen direkt erreichbar

Ergebnis: nur zwei Dienste haben überhaupt einen Weg von aussen (plus Keycloak über seine eigene Route, B4) – die sechs restlichen Fachdienste sind nur clusterintern erreichbar, selbst wenn ihre Route aus Versehen angelegt würde, würde die NetworkPolicy den Zugriff trotzdem blocken.

9 Nachschauen

Befehlzeigt
oc get netpol -n librarywelche Policies existieren
oc describe netpol deny-all-ingress -n librarySelektor + Regeln im Klartext
oc rsh deploy/<dienst> -n library + curlder einzige verlässliche Test – von einem echten Pod aus prüfen, nicht vom Laptop

Web-Konsole: Networking → NetworkPolicies zeigt eine Liste, aber keine Simulation – ob eine Verbindung wirklich durchkommt, testet man immer live aus einem Pod.

+ Die Kurzfassung

Vorgabedefault-allow, clusterweit – ein Namespace ist keine Netz-Grenze
eine Policywählt Pods per podSelector, schaltet sie für die genannte Richtung auf default-deny
mehrere Policiessummieren sich – nie deny, nur Vereinigung von Allow
zwei FallenDNS-Egress vergessen (alles bricht) · Probes kommen vom kubelet, nicht von einem Pod