OpenShift 3.11 SDN OpenFlow


 

Ein Versuch, die OpenShift SDN OpenFlow Regeln zu verstehen

OpenFlow

OpenFlow Regeln werden mit ovs-ofctl --protocols OpenFlow13 dump-flows br0 angezeigt. Das Utility kann im ovs-* Pod im openshift-sdn Namespace gestartet werden.

Variabeln

Es gibt 3 wichtige Variablen, welche im OpenFlow gesetzt/verwendet werden:

  • NXM_NX_REG0 (aka reg0): netid (aka VNID) der Quell-IP
  • NXM_NX_REG1 (aka reg1): netid (aka VNID) der Ziel-IP
  • NXM_NX_REG2 (aka reg2): output port nummer

Tabellen

  • 0: Einstieg
  • 10: Eingehender VXLAN Traffic von anderen Hosts nach Quell-IP filtern
  • 20: Pod Traffic nach in_port und nw_src filtern + Quell-IP netid setzen (NXM_NX_REG0)
  • 21: Start ct() wenn nw_dst SDN CIDR; goto table 30
  • 25: Quell-IP netid (NXM_NX_REG0) setzen
  • 30: Routing SDN und Service Network CIDR
  • 40: ARP nach veth*
  • 50: Routing SDN CIDR Bereich von/zu anderen Hosts mit VXLAN - netid (NXM_NX_REG0) wird VXLAN Tunnel-ID
  • 70: Ziel-IP netid (NXM_NX_REG1) und Output Port-Nummer (NXM_NX_REG2) setzen
  • 80: Output nach veth* (reg2)
    • checks nach reg0+reg1 wenn NetworkPolicy Resourcen vorhanden sind oder
    • prüfen auf reg1 ohne NetworkPolicy Resourcen

Es sind hier nicht alle Tabellen aufgeführt.

Beispiele

Pod zu Service IP zu Pod auf demselben Host

Flow Felder Teil 1:

  • nw_src=10.130.9.153
  • nw_dst=172.30.0.44
  • in_port=vethX
  • ip

Ablauf Teil 1: 0 -> 20 -> 21 -> 30 -> 60 -> Output via tun0

Ablauf Teil 2: iptables/nat KUBE-SERVICE -> KUBE-SVC-XYZ -> KUBE-SEP-XYZ -> Routing via tun0

Flow Felder Teil 3:

  • nw_src=10.130.9.153
  • nw_dst=10.130.9.123
  • in_port=tun0
  • ip

Ablauf Teil 3: 0 -> 25 -> 30 -> 70 -> 80 -> Output via veth+

Es findet kein Source-NAT statt, ausser Source-IP == Ziel-IP. Entsprechend gelten NetworkPolicy Einschränkungen auch für Zugriffe von Pods auf Service-IP’s.

Die netfilter (iptables) Regeln werden vom openshift-node Prozess verwaltet. Der openshift-node Prozess funktioniert analog zu kube-proxy im iptables Modus.

Pod zu Service IP zu Pod auf unterschiedlichen Hosts

Auf Node A:

Auf Node B:

Lokaler Host zu Pod auf demselben Host

Flow Felder:

  • nw_src=10.130.8.1
  • nw_dst=10.130.9.176
  • in_port=tun0
  • ip

Ablauf: 0 -> 30 -> 70 -> 80

Da NXM_NX_REG0 hier nicht gesetzt wird, ist davon auszugehen, dass der Wert 0x0 ist, also netid=0. Was bei einer standard OpenShift Konfiguration dem Namespace default zugewiesen ist.

Lokaler Host zu Pod auf einem anderen Host

Quell-System:

Flow Felder:

  • nw_src=10.130.8.1
  • nw_dst=10.130.13.234
  • in_port=tun0
  • ip

Ablauf: 0 -> 30 -> 50 -> Output via VXLAN

Analog zum vorhergehenden Beispiel: NXM_NX_REG0 wurde nicht gesetzt. Vermuteter Wert: 0x0

Ziel-System:

Flow Felder:

  • nw_src=10.130.8.1
  • nw_dst=10.130.13.234
  • in_port=vxlan0
  • NXM_NX_TUN_ID=0x0
  • ip

Ablauf: 0 -> 10 -> 30 -> 70 -> 80 -> Output via veth*

Pod zu Pod auf demselben Host

Flow Felder:

  • nw_src=10.130.9.153
  • nw_dst=10.130.9.176
  • in_port=vethX
  • ip

Ablauf: 0 -> 20 -> 21 -> 30 -> 70 -> 80 -> Output via veth*

Pod zu Pod auf unterschiedlichen Hosts

Quell System

Flow Felder:

  • nw_src=10.130.9.153
  • nw_dst=10.130.13.236
  • in_port=vethX
  • ip

Ablauf: 0 -> 20 -> 21 -> 30 -> 50 -> Output via VXLAN

Ziel-System

Flow Felder:

  • nw_src=10.130.9.153
  • nw_dst=10.130.13.236
  • in_port=vxlan0
  • NXM_NX_TUN_ID=NXM_NX_REG0 vom Quell-System
  • ip

Ablauf: 0 -> 10 -> 30 -> 70 -> 80 -> Output via veth*

Die Tunnel-ID wird in der Tabelle 0 in die netid Variable (NXM_NX_REG0) gespeichert.

Pod zu Service IP

Am Beispiel vom Kubernetes API. Der Service läuft im Host net namespace und somit nicht im SDN.

Das Kubernets API ist kubernetes service im default Namespace erreichbar. In einer OpenShift Standard-Konfiguration hat der Service die IP 172.30.0.1. Der Service CIDR ist 172.30.0.0/16.

Flow Felder:

  • nw_src=10.130.9.153
  • nw_dst=172.30.0.1
  • in_port=vethX
  • ip

Ablauf: 0 -> 20 -> 21 -> 30 -> 60 -> Output via tun0

Der Zugriff auf eine Service IP verlässt somit das SDN und läuft durch iptables/nat. Dieses wird durch den openshift-node Prozess verwaltet (aka kube-proxy im iptables Modus).

Das Kubernetes API ist im Host-Netzwerk und verlässt den Host durch das “normale” Netzwerk.

 

Beliebte Posts aus diesem Blog