Alle Rezepte
OVN-Kubernetes · OpenShift 4.16+ · Netzwerk-Policies

ANP, NP & BANP:
drei Tiers, eine ACL-Engine

Sieben Abschnitte: Der OVN-Kubernetes-Controller übersetzt Netzwerk-Policies in OVN-ACLs und wertet sie in drei Tiers aus – ANP schlägt NP schlägt BANP schlägt Default Allow. Hier steht, wer wann entscheidet, was Pass von No Match unterscheidet und wo Implicit Deny still zuschlägt.

0AblaufDrei Tiers, eine Reihenfolge 1Tier 1 · ANPClusterweit, Priority 0–99 2Tier 2 · NPNamespace, Implicit Deny 3Tier 3 · BANPSingleton, Auffangnetz 4ZusammenspielPass-Kette, Egress-Peers 5PraxisVerfügbarkeit, Best Practices 6DebuggenStatus, Metriken, nbdb
0

Ablauf: Wie ein Paket durch die drei Tiers läuft

Der OVN-Kubernetes-Controller übersetzt Netzwerk-Policies in OVN-ACLs. Jedes Paket durchläuft die Tiers in fester Reihenfolge – und sobald ein Tier eine Entscheidung trifft, ist Schluss: Die restlichen Tiers werden übersprungen.

Die drei Tiers und ihre Reihenfolge

TierTypGeltungsbereichWer definiert
1ANP (AdminNetworkPolicy)clusterweit, höchste PrioritätCluster-Admin
2NP (NetworkPolicy)namespace-scopedNamespace-Owner / Entwickler
3BANP (BaselineAdminNetworkPolicy)clusterweit, niedrigste PrioritätCluster-Admin
Default AllowKubernetes-Standard, wenn nichts greiftniemand

Der Pfad eines Pakets, wenn kein Tier vorzeitig entscheidet:

OVNKubernetes-Controller & ACL-Engine TIER 1 · ANP Match? YES / ALLOW YES / DENY YES / PASS NO MATCH Paket durch Tier 2 & 3 übersprungen Paket drop Tier 2 & 3 übersprungen TIER 2 · NP Namespace-scoped podSelector matched? Rule matched Kein Rule-Match Keine NP vorhanden Paket durch Tier 3 übersprungen Implicit Deny · drop Tier 3 übersprungen TIER 3 · BANP Cluster-Singleton Match? YES / ALLOW YES / DENY No Match Paket durch Paket drop Default Allow (k8s-Standard)
Drei Kontrollpunkte am Flughafen: Die Bundespolizei (ANP) hat das erste und letzte Wort – ihre Entscheidung kann keiner überstimmen. Das Gate-Personal (NP) prüft nur die eigenen Passagierlisten. Die Hausordnung (BANP) greift für alle, um die sich sonst niemand gekümmert hat. Und wer nirgends aufgehalten wird, geht einfach durch (Default Allow).
1

Tier 1: AdminNetworkPolicy (ANP)

Clusterweite Regeln mit der höchsten Priorität, definiert von Cluster-Admins und von Namespace-Ownern nicht überschreibbar. Jedes Paket wird zuerst gegen die ANP-Regeln geprüft.

Was in Tier 1 passieren kann

ErgebnisAktionNächster Schritt
ALLOWPaket wird durchgelassenTier 2 & 3 werden übersprungen
DENYPaket wird verworfen (drop)Tier 2 & 3 werden übersprungen
PASSANP trifft zu, delegiert die Entscheidungweiter zu Tier 2
NO MATCHkeine ANP-Regel greiftweiter zu Tier 2

PASS und NO MATCH landen beide in Tier 2 – sind aber nicht dasselbe: PASS ist eine aktive Delegation („diese Verbindung sollen die NetworkPolicies der Tenants entscheiden“), NO MATCH heißt schlicht, dass sich keine ANP für das Paket interessiert hat. Ein ANP-Allow dagegen ist absolut: NetworkPolicies werden dann komplett ignoriert – kein Tenant kann sich z. B. selbst vom Monitoring abschotten.

Die Auswertungsreihenfolge unter mehreren ANPs steuert spec.priority: Werte 0–99, maximal 100 ANPs pro Cluster, je niedriger der Wert, desto höher der Vorrang.

Priority ist die Startaufstellung: 0 ist die Pole-Position, 99 der letzte Startplatz. Wer die kleinere Zahl hat, fährt zuerst.
Der leere Selektor räumt den ganzen Cluster ab: namespaces: {} selektiert alle Namespaces – auch openshift-*, kube-system und default. ANP/BANP auf System-Namespaces anzuwenden ist unsupported und kann den Cluster in einen nicht funktionsfähigen Zustand versetzen. Immer explizite Labels statt Catch-all.
YAML: Grundgerüst einer ANP

Subject wählt die betroffenen Pods (über Namespaces bzw. Namespace+Pod-Selektoren), Ingress- und Egress-Regeln tragen jeweils Name, Action und Peers. Actions: Allow, Deny, Pass.

apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
  name: sample-anp-deny-pass-rules
spec:
  priority: 50                  # 0-99, niedriger = mehr Vorrang
  subject:
    namespaces:
      matchLabels:
        kubernetes.io/metadata.name: example.name
  ingress:
    - name: "deny-all-ingress-tenant-1"
      action: "Deny"
      from:
        - pods:
            namespaceSelector:
              matchLabels:
                custom-anp: tenant-1
            podSelector:
              matchLabels:
                custom-anp: tenant-1
  egress:
    - name: "pass-all-egress-to-tenant-1"
      action: "Pass"
      to:
        - pods:
            namespaceSelector:
              matchLabels:
                custom-anp: tenant-1
            podSelector:
              matchLabels:
                custom-anp: tenant-1
Die drei Actions als Monitoring-Trio (Allow / Deny / Pass)

Drei ANPs zeigen die Abstufung: block-monitoring (Priority 5) schützt restriktive Tenants absolut vor Scraping, pass-monitoring (Priority 7) lässt interne Tenants per NetworkPolicy selbst entscheiden, allow-monitoring (Priority 9) garantiert Monitoring für den Rest. Die kleinste Zahl gewinnt bei Überlappung.

apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
  name: block-monitoring
spec:
  priority: 5
  subject:
    namespaces:
      matchLabels:
        security: restricted
  ingress:
    - name: "deny-ingress-from-monitoring"
      action: "Deny"
      from:
        - namespaces:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
---
apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
  name: pass-monitoring
spec:
  priority: 7
  subject:
    namespaces:
      matchLabels:
        security: internal
  ingress:
    - name: "pass-ingress-from-monitoring"
      action: "Pass"
      from:
        - namespaces:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
---
apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
  name: allow-monitoring
spec:
  priority: 9
  subject:
    namespaces: {}   # Vorsicht: selektiert auch OpenShift-Namespaces
  ingress:
    - name: "allow-ingress-from-monitoring"
      action: "Allow"
      from:
        - namespaces:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
2

Tier 2: NetworkPolicy (NP)

Namespace-Ebene, Werkzeug der Entwickler und Namespace-Owner. Die Engine prüft, ob eine NP den Ziel-Pod per podSelector selektiert – erst dann wird überhaupt entschieden.

Was in Tier 2 passieren kann

ErgebnisAktionNächster Schritt
NP selektiert Pod + Traffic matcht Allow-RegelPaket wird durchgelassenTier 3 wird übersprungen
NP selektiert Pod + kein Rule-MatchImplicit Deny – Paket wird verworfenTier 3 wird übersprungen
Keine NP selektiert den Podkeine Entscheidungweiter zu Tier 3

Anders als ANPs kennen NetworkPolicies keine expliziten Deny-Regeln: Das Deny entsteht implizit durch die Selektion. Und anders als ANPs entscheidet Tier 2 auch dann final, wenn nichts erlaubt wurde – ein selektierter Pod ohne passende Allow-Regel kommt nie bei der BANP an.

Die erste NP kippt den Schalter: Solange keine NetworkPolicy einen Pod selektiert, ist alles offen. Sobald irgendeine NP ihn selektiert, gilt Implicit Deny – alles Nicht-Erlaubte ist zu. Wer „nur mal eben“ eine Ingress-Regel für Port 8080 anlegt, hat damit still jeden anderen Ingress-Traffic auf diesen Pod blockiert. Es gibt keinen Fehler, nur Verbindungen, die plötzlich hängen.
Implicit Deny = Gästeliste an der Tür: Ohne Liste kommt jeder rein. Sobald eine Liste aushängt – und sei sie noch so kurz –, bleibt draußen, wer nicht draufsteht.
YAML: NP, die gepassten Monitoring-Traffic erlaubt

Passt zum Pass-Beispiel aus Abschnitt 1: Der Tenant entscheidet per NP selbst, ob Monitoring ihn scrapen darf.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring
  namespace: tenant-1
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
3

Tier 3: BaselineAdminNetworkPolicy (BANP)

Das Auffangnetz: BANPs greifen nur, wenn weder ANP noch NP entschieden haben. Sie setzen eine überschreibbare Grundlinie – Namespace-Owner können sie per NetworkPolicy gezielt aushebeln, denn Tier 2 kommt immer vor Tier 3.

Was in Tier 3 passieren kann

ErgebnisAktion
ALLOWPaket wird durchgelassen
DENYPaket wird verworfen (drop)
NO MATCHDefault Allow (Kubernetes-Standard) – Paket wird zugelassen

Zwei Eigenheiten gegenüber der ANP: Es gibt kein Pass (unter Tier 3 kommt nichts mehr, an das man delegieren könnte) und keine Priority – denn pro Cluster existiert genau eine BANP. Typischer Einsatz: Default-Deny für Intra-Cluster-Traffic in User-Namespaces, sodass Entwickler bekannten Traffic explizit per NetworkPolicy freigeben müssen.

Singleton mit Namenszwang: Die BANP-Ressource muss default heißen – sie ist ein Cluster-Singleton. Und wie bei der ANP gilt: nur auf User-Namespaces scopen. System-Namespaces haben keine NetworkPolicies, die eine zu strenge BANP übersteuern könnten – ein Deny trifft sie dort ungebremst.
YAML: BANP mit Deny-Grundlinie

Actions in BANP-Regeln: nur Allow und Deny. Dieses Beispiel verweigert Monitoring-Ingress für interne Tenants als Grundzustand – Abschnitt 4 zeigt, wie Tenants das per NP übersteuern.

apiVersion: policy.networking.k8s.io/v1alpha1
kind: BaselineAdminNetworkPolicy
metadata:
  name: default              # Pflichtname, Cluster-Singleton
spec:
  subject:
    namespaces:
      matchLabels:
        security: internal
  ingress:
    - name: "deny-ingress-from-monitoring"
      action: "Deny"
      from:
        - namespaces:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
4

Zusammenspiel: Pass-Kette und Egress-Peers

Die Stärke des Modells zeigt sich erst in Kombination: ANP-Pass delegiert an die Tenants, die BANP fängt alle auf, die nichts entschieden haben. Und Richtung Norden (raus aus dem Cluster) kommen nodes- und networks-Peers dazu.

Das Multi-Tenant-Pattern: Pass → NP → BANP-Deny

  1. ANP pass-monitoring (Priority 7)Delegiert Monitoring-Ingress für security: internal aktiv an Tier 2 – der Admin diktiert nicht, er lässt wählen.
  2. Tenant-NP entscheidetTenant 1 legt die allow-monitoring-NP an und wird gescrapt. Tenant 2 legt nichts an – für ihn fällt die Entscheidung eine Etage tiefer.
  3. BANP default verweigertDie Deny-Grundlinie fängt Tenant 2 ab: kein Monitoring ohne explizite Freigabe. Opt-in statt Opt-out.

Ergebnis: Der Admin hat nie einzelne Tenants konfiguriert – er hat nur den Rahmen gesetzt, in dem Tenants selbst entscheiden.

Nordverkehr: nodes- und networks-Peers

Neben Ost-West-Traffic steuern ANP und BANP auch Traffic, der den Cluster verlässt oder zu Nodes geht – mit zwei zusätzlichen Peer-Typen, die es nur in Egress-Regeln gibt:

  • nodes-Peer – Egress zu Cluster-Nodes per Node-Selektor, z. B. zum Kubernetes-API-Server über die Control-Plane-Nodes; Regeln überstehen Node-Zu- und -Abgänge ohne Policy-Änderung
  • networks-Peer – Egress zu externen Zielen per CIDR-Range, z. B. Intranet erlauben, bestimmte externe DNS-Server sperren
Deny auf 0.0.0.0/0 sperrt auch die Lebensadern: Ein pauschales Egress-Deny ins Internet trifft ohne Gegenmaßnahme auch Kubernetes-API und DNS. Vor dem Deny braucht es höher priorisierte Allow-Regeln für die essenziellen Ziele – sonst steht der Cluster, und die Policy sieht dabei völlig korrekt aus.
YAML: Egress-Kontrolle mit nodes- und networks-Peers

ANP erlaubt API-Server (Port 6443 auf Control-Plane-Nodes) und Intranet, verbietet externe DNS-Server, passt den Rest – die BANP macht daraus ein Default-Deny Richtung Internet.

apiVersion: policy.networking.k8s.io/v1alpha1
kind: AdminNetworkPolicy
metadata:
  name: network-as-egress-peer
spec:
  priority: 70
  subject:
    namespaces:
      matchLabels:
        tenant-tier: standard   # explizite Labels statt {} verwenden
  egress:
    - name: "allow-to-kubernetes-api-server"
      action: "Allow"
      ports:
        - portNumber:
            protocol: TCP
            port: 6443
      to:
        - nodes:
            matchExpressions:
              - key: node-role.kubernetes.io/control-plane
                operator: Exists
    - name: "deny-egress-to-external-dns-servers"
      action: "Deny"
      to:
        - networks:
            - 8.8.8.8/32
            - 8.8.4.4/32
            - 208.67.222.222/32
      ports:
        - portNumber:
            protocol: UDP
            port: 53
    - name: "allow-all-egress-to-intranet"
      action: "Allow"
      to:
        - networks:
            - 89.246.180.0/22
            - 60.45.72.0/22
    - name: "pass-all-egress-to-internet"
      action: "Pass"
      to:
        - networks:
            - 0.0.0.0/0
---
apiVersion: policy.networking.k8s.io/v1alpha1
kind: BaselineAdminNetworkPolicy
metadata:
  name: default
spec:
  subject:
    namespaces:
      matchLabels:
        tenant-tier: standard
  egress:
    - name: "deny-all-egress-to-internet"
      action: "Deny"
      to:
        - networks:
            - 0.0.0.0/0
5

Praxis: Verfügbarkeit und Best Practices

ANP und BANP stammen aus der sig-network-policy-api Working Group und liegen als policy.networking.k8s.io/v1alpha1 vor. In OpenShift: Tech Preview ab 4.14, GA ab 4.16 mit OVN-Kubernetes als CNI.

Prioritäten planen

  • Mittleren Bereich nutzen (z. B. 30–70) und Lücken lassen – so passen später neue ANPs dazwischen, ohne alles neu zu nummerieren
  • Gleiche Priority vermeiden: Bei überlappenden Regeln auf derselben Priority ist nicht garantiert, welche greift
  • Selektoren nicht überlappen lassen – dieselben IPs in mehreren Policies kosten Performance und Skalierung

Regeln entwerfen

  • Allow = Verbindung gilt immer, NetworkPolicies werden ignoriert; Pass = Entscheidung liegt bei den Tenants
  • Explizite Labels statt {} – der Catch-all-Selektor erwischt auch Infrastruktur-Namespaces
  • namedPorts nicht mit portNumber/portRange mischen – erzeugt 6 ACLs pro Regel und macht den Cluster ineffizient
  • ANP hat kein Implicit Deny: Anders als bei der NP muss jedes Allow und Deny explizit formuliert werden
6

Debuggen: Status, Metriken, nbdb

Ob eine Policy wirklich verdrahtet wurde, steht nicht im Apply-Output, sondern im Status der CR – und im Zweifel direkt in der OVN Northbound-Datenbank (nbdb) auf dem Node.

Erst der Status, dann die Datenbank

Jeder Zone-Controller (pro Node) meldet im Status, ob das „OVN DB plumbing“ geklappt hat. Erwartet: SetupSucceeded pro Zone.

oc describe anp cluster-control
oc describe banp default

# gut:  Reason: SetupSucceeded / Message: Setting up OVN DB plumbing was successful
# bös:  Reason: SetupFailed  / z. B. "OVNK only supports priority ranges 0-99"
Apply grün, Netzwerk unverändert: oc apply nimmt auch eine ANP mit Priority 600 klaglos an – die CRD-Validierung lässt sie durch, aber der OVN-Controller meldet erst im Status SetupFailed, weil nur 0–99 unterstützt wird. Wer nach dem Apply nicht oc describe anp prüft, wundert sich über eine Policy, die nie gegriffen hat.
ACLs, Address Sets und Port Groups in der nbdb ansehen

Für den Blick in die nbdb per Remote-Shell in den nbdb-Container des ovnkube-node-Pods auf dem betreffenden Node wechseln. In den ACL-Objekten steht die übersetzte Logik: action (allow-related, drop, pass), match und tier: 1 für ANP-ACLs.

oc get pods -n openshift-ovn-kubernetes -owide
oc rsh -c nbdb -n openshift-ovn-kubernetes ovnkube-node-524dt
# alle ACLs einer Policy (Typ: AdminNetworkPolicy oder BaselineAdminNetworkPolicy)
ovn-nbctl find ACL 'external_ids{>=}{"k8s.ovn.org/owner-type"=AdminNetworkPolicy,"k8s.ovn.org/name"=cluster-control}'

# eine einzelne Regel (gress-index = Position in ingress/egress, ab 0)
ovn-nbctl find ACL 'external_ids{>=}{"k8s.ovn.org/owner-type"=AdminNetworkPolicy,direction=Ingress,"k8s.ovn.org/name"=cluster-control,gress-index="1"}'

# zugehörige Address Sets (aufgelöste Peer-IPs) und Port Groups (Subject-Ports)
ovn-nbctl find Address_Set 'external_ids{>=}{"k8s.ovn.org/owner-type"=AdminNetworkPolicy,"k8s.ovn.org/name"=cluster-control}'
ovn-nbctl find Port_Group 'external_ids{>=}{"k8s.ovn.org/owner-type"=AdminNetworkPolicy,"k8s.ovn.org/name"=cluster-control}'
Metriken für ANP und BANP
  • ovnkube_controller_admin_network_policies – Anzahl ANPs im Cluster
  • ovnkube_controller_baseline_admin_network_policies – Anzahl BANPs; muss 0 oder 1 sein
  • ovnkube_controller_admin_network_policies_rules – Regeln je Direction (Ingress/Egress) und Action (Pass/Allow/Deny)
  • ovnkube_controller_baseline_admin_network_policies_rules – dito für BANP (nur Allow/Deny)
  • ovnkube_controller_admin_network_policies_db_objects – erzeugte nbdb-Objekte je table_name (ACL, Address_Set)