Podman macvlan bridge

jb_alvarado

Lt. Junior Grade
Registriert
Sep. 2015
Beiträge
492
Hallo Allerseits,
ich schaue mir gerade Podman etwas an. Situation ist diese, dass ich zwei Server habe, die mittels vSwitch miteinander kommunizieren können. Aktuell hängen da auch KVM VM drinnen, die alle statische IPs haben.

In das gleiche Netz möchte ich gerne Podman Container einhängen. Mein Befehl dazu schaut in etwas so aus:
Bash:
podman network create -d macvlan -o parent=br2 -o mode=bridge -o mtu=1400 \
    --ipam-driver=host-local --subnet=10.20.0.0/24 --gateway=10.20.0.3 --disable-dns vswitch

Das gibt mir diese Settings:

JSON:
[
     {
          "name": "vswitch",
          "id": "06f7c130b9202d787feb1016955e6bd074b32d9e032df90a8d347868b72dfc0c",
          "driver": "macvlan",
          "network_interface": "br2",
          "created": "2024-03-06T20:45:16.85772749+01:00",
          "subnets": [
               {
                    "subnet": "10.20.0.0/24",
                    "gateway": "10.20.0.3"
               }
          ],
          "ipv6_enabled": false,
          "internal": false,
          "dns_enabled": false,
          "options": {
               "mode": "bridge",
               "mtu": "1400"
          },
          "ipam_options": {
               "driver": "host-local"
          }
     }
]

Gateway habe ich so auch bei den VMs eingestellt und dort geht auch alles wie gewünscht.

Einen Container erstelle ich dann mit:

Code:
podman run -it --rm --net=vswitch --ip=10.20.0.243 alpine sh

Nun kann ich von meinen VMs zu diesem Container pingen, vom Container zu den VMs, vom zweiten Root Server zum Container und umgekehrt. Alles über das vSwitch. Allerdings kann ich aus dem Container heraus keine Verbindung mit dem Internet herstellen.

Laut Doku gibt es noch den Parameter --route, jedoch nicht in Verbindung mit dem Driver macvlan. Wenn ich lokal das Ganze testen, da habe ich auch ein bridge Interface, funktioniert das ganze wie gewünscht. Allerdings liegt da die Bridge direkt am Netzwerk an und ich muss da nichts routen.

Habt ihr Ideen, wie ich das Problem lösen kann?
 
Wenn ich das jetzt richtig verstehe hatte ich ein Denkfehler in der ganzen Geschichte, daher geht das so ohne weiteres nicht.

Habe noch diese Lösung gefunden, damit kann man sogar rootless Container erstellen, die direkt an einer Bridge anliegen. Bin aber noch am abwägen ob das auf Dauer praktikabel ist.
 
Keine Ahnung ob es überhaupt jemand interessiert, aber ich habe jetzt eine gute Lösung für mich gefunden.

1. Neues vLan und entsprechendes Interface erstellt:
Code:
auto eno1.4001
iface eno1.4001 inet manual
  vlan-raw-device eno1
  mtu 1400
  post-up ifconfig $IFACE up
  pre-down ifconfig $IFACE down

2. podman Netzwerk erstellen:
Code:
podman network create -d macvlan -o parent=eno1.4001 -o mode=bridge -o mtu=1400 --ipam-driver=host-local --subnet=10.30.0.0/24 --gateway=10.30.0.1 vswitch

3. zweites Macvlan Interface auf dem Host erstellen, für die Kommunikation: Host <-> Container
Code:
ip link add vswitch-shim link eno1.4001 type macvlan mode bridge

4. Adresse hinzufügen, aktivieren und route erstellen:
Code:
ip addr add 10.30.0.1/32 dev vswitch-shim
ip link set vswitch-shim up
ip route add 10.30.0.0/24 dev vswitch-shim

Um 3 und 4 dauerhaft zu konfigurieren, kann man auch die /etc/network/interfaces Datei erweitern:

Code:
auto eno1.4001
iface eno1.4001 inet manual
  vlan-raw-device eno1
  mtu 1400
  post-up ifconfig $IFACE up
  post-up ip link add vswitch-shim link eno1.4001 type macvlan mode bridge
  post-up ip addr add 10.30.0.1/32 dev vswitch-shim
  post-up ip link set vswitch-shim up
  post-up ip route add 10.30.0.0/24 dev vswitch-shim
  pre-down ip route del 10.30.0.0/24 dev vswitch-shim
  pre-down ip link set vswitch-shim down
  pre-down ip addr del 10.30.0.1/32 dev vswitch-shim
  pre-down ip link del vswitch-shim link eno1.4001 type macvlan mode bridge
  pre-down ifconfig $IFACE down

5. Bestehendes nftables Regelwerk erweitern mit:
Bash:
define dev_pod_shim = vswitch-shim
define pod_net4 = 10.30.0.0/24

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;

        iifname $dev_pod_shim ct state { established, related } accept

         # allow some port connections from podman network to host, like dns and ping
        iifname $dev_pod_shim meta l4proto udp udp dport { 53, 67 } counter accept
        iifname $dev_pod_shim meta l4proto tcp tcp dport { 53, 67 } counter accept
        iifname $dev_pod_shim ip protocol icmp icmp type echo-request counter accept

        log prefix "drop input   " group 0 drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;

        iifname $dev_wan oifname $dev_pod_shim ip daddr $pod_net4 ct state { established, related } accept
        iifname $dev_pod_shim oifname $dev_wan ip saddr $pod_net4 accept comment "allow traffic from podman bridge to wan"
    }

table inet nat {
    chain input {
        type nat hook input priority 100; policy accept;
    }

    chain output {
        type nat hook output priority -100; policy accept;
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;

        oifname $dev_wan ip saddr $pod_net4 ip daddr 224.0.0.0/24 return
        oifname $dev_wan ip saddr $pod_net4 ip daddr 255.255.255.255 return

        ip saddr $pod_net4 oifname $dev_wan snat $wan_ipv4
    }
}

Container erstellen: podman run -it --rm --net=vswitch --ip=10.30.0.200 alpine sh

So funktioniert die Kommunikation vom Container ins Internet, vom Host zum Container und umgekehrt. Regeln vom Internet zum Container müssten dann noch nach Wunsch hinzugefügt werden.

Rootless braucht es im Produktivbetrieb auch nicht, dazu gibt es den Parameter --userns=auto. Somit kann man auch seine Container bequem mit systemd starten.
 
Zuletzt bearbeitet:
Zurück
Oben