Kubernetes/OpenShift Networking mit Cluster Network Operator und Multus

Red Hat OpenShift (Kubernetes) Networking

OpenShift-Netzwerkinfrastruktur

Der Cluster Network Operator (CNO) ist die zentrale Komponente, die das Netzwerk bereitstellt und den Lifecycle verwaltet. Er stellt sicher, dass der Netzwerkzustand der Konfiguration entspricht. Der Operator verwaltet das primäre Container Network Interface (CNI) und meldet den Status seiner Komponenten.

Der CNO läuft als DaemonSet, das OVN-Kubernetes oder andere Plug-ins zur Verfügung stellt. Zudem ist der CNO eine Custom Resource (CR) in der globalen operator.openshift.io-API-Gruppe. OVN-Kubernetes ist das Standard-Plugin von OpenShift.

Um zu prüfen, ob der CNO gut funktioniert, prüft man am besten den Cluster Operator mittels:

$ oc get clusteroperators network 
NAME      VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE   MESSAGE
network   4.22.13   True        False         False      404d

Um zu prüfen, ob die richtigen Subnetze den Nodes zugewiesen sind, müssen die Annotations angeschaut werden:

oc get node cp01 -o yaml | grep node-subnets
    k8s.ovn.org/node-subnets: '{"default":["10.130.0.0/23"]}'

Um das Deployment von OVN-Kubernetes zu überprüfen, listen wir die Pods vom openshift-ovn-kubernetes Namespace:

$ oc get pods -n openshift-ovn-kubernetes
NAME                                     READY   STATUS    RESTARTS   AGE
ovnkube-control-plane-64c4c465fc-cc7xn   2/2     Running   0          25d
ovnkube-control-plane-64c4c465fc-dhswc   2/2     Running   0          25d
ovnkube-node-2fwbk                       8/8     Running   16         26d
ovnkube-node-8p88h                       8/8     Running   8          26d
ovnkube-node-c5hqr                       8/8     Running   32         26d
ovnkube-node-m5fhp                       8/8     Running   8          26d
ovnkube-node-q9zh6                       8/8     Running   8          26d
ovnkube-node-sfwlg                       8/8     Running   34         26d
ovnkube-node-st9x9                       8/8     Running   16         26d

Mit dem folgenden Kommando kann man überprüfen, welches CNI Plugin installiert und wie es konfiguriert ist.

$ oc get network.config.openshift.io cluster -o yaml
apiVersion: config.openshift.io/v1
kind: Network
metadata:
  creationTimestamp: "2025-09-05T13:43:49Z"
  generation: 96
  name: cluster
  resourceVersion: "652252262"
  uid: 4e84913e-5983-4fc2-a577-82e8c87daadb
spec:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  externalIP:
    policy: {}
  networkDiagnostics:
    mode: ""
    sourcePlacement: {}
    targetPlacement: {}
  networkType: OVNKubernetes
  serviceNetwork:
  - 172.30.0.0/16
status:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  clusterNetworkMTU: 1400
  conditions:
  - lastTransitionTime: "2026-10-05T13:56:10Z"
    message: ""
    observedGeneration: 0
    reason: AsExpected
    status: "True"
    type: NetworkDiagnosticsAvailable
  networkType: OVNKubernetes
  serviceNetwork:
  - 172.30.0.0/16

Obwohl, sobald einmal konfiguriert und installiert, viele Parameter nicht mehr verändert werden können, können gewisse Änderungen zur Laufzeit gemacht werden. Zum Beispiel kann der CIDR Block angepasst werden.

$ oc patch Network.config.openshift.io cluster --type='merge' --patch \
  '{
    "spec":{
      "clusterNetwork": [ {"cidr":"10.128.0.0/14","hostPrefix": 23} ], 
      "networkType": "OVNKubernetes"
    }
  }'

Bei CNI-Plug-ins, die kube-proxy verwenden, kann die kube-proxy-Konfiguration zur Laufzeit angepasst werden.

Network Configuration APIS

Es gibt zwei verschiedene API-Objekte, die für das Verwalten des Cluster-Netzwerkes verwendet werden können. Jedes Objekt erfüllt in der Konfigurationshierarchie einen anderen Zweck.

  • network.config.openshift.io/cluster Dieses Objekt definiert den Zielzustand des Cluster-Netzwerkes. Es enthält read-only Felder, die bei der Installation gesetzt wurden.
$ oc get network.config.openshift.io cluster -o yaml
apiVersion: config.openshift.io/v1
kind: Network
metadata:
  creationTimestamp: "2025-09-05T13:43:49Z"
  generation: 96
  name: cluster
  resourceVersion: "652252262"
  uid: 4e84913e-5983-4fc2-a577-82e8c87daadb
spec:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  externalIP:
    policy: {}
  networkDiagnostics:
    mode: ""
    sourcePlacement: {}
    targetPlacement: {}
  networkType: OVNKubernetes
  serviceNetwork:
  - 172.30.0.0/16
... omitted
  • network.operator.openshift.io/cluster Dieses API-Objekt kann dazu verwendet werden, um betriebliche Aspekte vom CNI-Plug-in zu konfigurieren, wie zum Beispiel Features, Logging-Level und erweiterte Netzwerkoptionen. Dieses Objekt hat also veränderbare Felder:
$  oc get network.operator.openshift.io cluster -o yaml
apiVersion: operator.openshift.io/v1
kind: Network
metadata:
  creationTimestamp: "2025-09-05T13:50:01Z"
  generation: 2
  name: cluster
  resourceVersion: "620500841"
  uid: 71f4851a-0e9d-42ad-8cfd-868516f4babf
spec:
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  defaultNetwork:
    ovnKubernetesConfig:
      egressIPConfig: {}
      gatewayConfig:
        ipv4: {}
        ipv6: {}
        routingViaHost: false # Steuert, ob Gateway-Verkehr über das Host-Netzwerk gesendet werden soll
      genevePort: 6081 # UDP Port für den Geneve Tunnel
      ipsecConfig:
        mode: Disabled
      mtu: 1400 # Definiert die MTU (max) vom Overlay Netzwerk
      policyAuditConfig:
        destination: "null"
        maxFileSize: 50
        maxLogFiles: 5
        rateLimit: 20
        syslogFacility: local0
    type: OVNKubernetes # Network Plug-in Type
  deployKubeProxy: false
  disableMultiNetwork: false
  disableNetworkDiagnostics: false
  logLevel: Normal
  managementState: Managed
  observedConfig: null
  operatorLogLevel: Normal
  serviceNetwork:
  - 172.30.0.0/16
  unsupportedConfigOverrides: null
  useMultiNetworkPolicy: false
... omitted

Multus CNI Plug-in

Container-Runtimes können das Kubernetes-Netzwerkmodell auf viele verschiedene Arten implementieren, z. B. durch Custom Resources (CR) oder durch CNI-Plug-ins. Ähnlich wie bei einem Wrapper ruft das Multus-CNI-Plug-in andere CNI-Plug-ins für weiterführende Netzwerkfunktionen auf, wie zum Beispiel das Anschliessen von mehreren Netzwerkschnittstellen. Red Hat OpenShift verwendet das Multus-CNI, um andere CNI-Plug-ins einzubinden.

Der Cluster Network Operator (CNO) ist für das Deployment des Multus-Plug-ins auf jeden Node im Cluster per DaemonSet verantwortlich. Während einer Installation oder eines Updates deployt der CNO Multus als Meta-Plug-in. Ein Meta-Plug-in ist ein spezieller Typ von CNI-Plug-in. Es fungiert als Manager, Dispatcher oder Wrapper für andere CNI-Plug-ins. Der kubelet-Agent auf den Cluster-Nodes interagiert mit Multus, welches wiederum mit dem “Primary”-CNI oder sekundären CNIs interagiert.

Hier die Beziehung zwischen Multus CNI, CNO und dem Primary CNI (hier OVN-Kubernetes).

Multus

Die Aktivität zwischen Multus und CNI

Nun schauen wir uns an, was passiert, wenn wir einen Pod starten. Dazu muss man den Multus-Pod identifizieren, der auf dem entsprechenden Node läuft.

NAME                                          READY   STATUS    RESTARTS   AGE   IP              NODE   NOMINATED NODE   READINESS GATES
multus-6f8v2                                  1/1     Running   5          26d   192.168.1.138   wr03   <none>           <none> multus-879mv                                  1/1     Running   3          26d   192.168.1.247   wr01   <none>           <none> 
. # omitted
multus-f7jct                                  1/1     Running   2          26d   192.168.1.142   cp02   <none>           <none>
multus-ffdhz                                  1/1     Running   3          26d   192.168.1.121   cp01   <none>           <none>
multus-g925m                                  1/1     Running   7          26d   192.168.1.123   cp03   <none>           <none>
multus-lmdf9                                  1/1     Running   2          26d   192.168.1.122   wr02   <none>           <none>
multus-tznm9                                  1/1     Running   2          26d   192.168.1.132   wr04   <none>           <none>
. # omitted

Nach dem Erstellen des Pods sieht man im Log des Multus-Pods:

...output omitted...
2026-10-14T14:27:00Z [verbose] Add: postgres:pgadmin-7784657685-pt5zv:953f73f4-e4fe-46c8-b13d-d2b849685b34:ovn-kubernetes(ovn-kubernetes):eth0 {"cniVersion":"1.1.0","interfaces":[{"mac":"8a:bc:44:1f:71:3e","name":"4e9dddc7ab8643d"},{"mac":"0a:58:0a:83:00:92","name":"eth0","sandbox":"/var/run/netns/098155fb-15f2-4570-b1a6-c2eaf3e727d0"}],"ips":[{"address":"10.131.0.146/23","gateway":"10.131.0.1","interface":1}]}
I1014 14:27:00.676379    3665 event.go:377] Event(v1.ObjectReference{Kind:"Pod", Namespace:"postgres", Name:"pgadmin-7784657685-pt5zv", UID:"953f73f4-e4fe-46c8-b13d-d2b849685b34", APIVersion:"v1", ResourceVersion:"669227647", FieldPath:""}): type: 'Normal' reason: 'AddedInterface' Add eth0 [10.131.0.146/23] from ovn-kubernetes
2026-10-14T14:27:00Z [verbose] ADD finished CNI request...

Wir könnten auch über die Events gehen und sehen, dass das NIC für den Pod erstellt wurde:

oc get events --field-selector involvedObject.name=pgadmin-7784657685-pt5zv -n postgres
LAST SEEN   TYPE      REASON           OBJECT                         MESSAGE
10m         Normal    Scheduled        pod/pgadmin-7784657685-pt5zv   Successfully assigned postgres/pgadmin-7784657685-pt5zv to wr01
10m         Normal    AddedInterface   pod/pgadmin-7784657685-pt5zv   Add eth0 [10.131.0.146/23] from ovn-kubernetes
10m         Normal    Pulled           pod/pgadmin-7784657685-pt5zv   Container image "dpage/pgadmin4:9.18.0" already present on machine and can be accessed by the pod
10m         Normal    Created          pod/pgadmin-7784657685-pt5zv   Container created
10m         Normal    Started          pod/pgadmin-7784657685-pt5zv   Container started
... output omitted

Cluster-, Service- und Pod-Netzwerke für OVN-Kubernetes

Der CNO ist von bestimmten Feldern im Netzwerk-Konfigurationsobjekt abhängig (vgl. oben).

  • clusterNetwork

    Dieses Feld definiert den IP-Adresspool für die Pods. Es handelt sich um eine Liste von CIDR-Blöcken, aus denen der CNO IP-Adressen für jeden Pod im Cluster zuweist.

    cidr: 10.128.0.0/14 hostPrefix: 23

  • networkType

    Dieses Feld gibt dem CNO an, welches CNI-Plugin ausgeführt werden soll. Für OVN-Kubernetes setzen Sie diesen Wert auf „OVNKubernetes“.

    networkType: OVNKubernetes

  • serviceNetwork

    Dieses Feld ist ein IP-Adressblock, der ausschliesslich für Kubernetes-Service-Objekte reserviert ist. Der CNO konfiguriert OVN-Load-Balancer so, dass sie den für diese IP-Adressen bestimmten Datenverkehr verarbeiten. Das OVN-Kubernetes-Plugin unterstützt nur einen einzigen IP-Adressblock für das Servicenetzwerk, zum Beispiel 172.30.0.0/16. Im Gegensatz zum Feld „clusterNetwork“ können Sie hier für OVN-Kubernetes nicht mehrere nicht zusammenhängende IP-Adressbereiche definieren.

    serviceNetwork: 172.30.0.0/16

Netzwerk Typen und ihre Verwendung

Das Overlay Netzwerk

Das Overlay-Netzwerk ist eine logische Transportschicht, die über der physischen Infrastruktur sitzt. Es abstrahiert die Container-zu-Container-Kommunikation von der darunterliegenden Hardware und erstellt ein Tunnel-Mesh über alle Knoten.

Node-to-Node Tunnels

Die Node-to-Node-Tunnels ermöglichen eine Punkt-zu-Punkt-Kommunikation über das physische Netzwerk, wie oben beschrieben. Hierfür verwendet OVN-Kubernetes die Geneve-Overlay-Kapselung. Falls der Datenverkehr zwischen verschiedenen Knoten durch Firewalls geleitet werden muss, muss der UDP-Port 6081 geöffnet sein.

Pod Network

Dieses Netzwerk ist ausschliesslich für die Pods reserviert. Es ist normalerweise sehr gross und flach, da jeder Pod eine eigene IP-Adresse enthält. Der CIDR-Block ist per Default 10.128.0.0/14 und darf auf keinen Fall mit einem anderen Netzwerk überlappen. Wenn der gewählte Range sich mit einem bestehenden physischen Netzwerk oder einem verbundenen VPS überschneidet, schlägt das Routing fehl und die Kommunikation ist unterbrochen.

Service Network

Das Service Network hat einen Pool von virtuellen IP-Adressen (VIPs) für die internen Kubernetes-Services. Anders als beim Pod-Netzwerk sind diese Adressen stabil und fungieren als interne Load Balancer, die den Netzwerkverkehr zu den Back-End-Pods weiterleiten. Die primäre Anforderung für dieses Netzwerk ist die Isolierung. Auch wenn diese IP-Adressen nicht routbar sein müssen, dürfen sie nicht mit dem Host- oder Pod-Netzwerk überlappen.