Docker と nftables

Docker は iptables を前提として書かれており、nftables を使っている環境ではそのままだと動かない。 issue は既にあったんだけど nftables を使っている環境はまだまだ少なそうだし進まなそう https://github.com/moby/moby/issues/26824 。 とはいえ iptables でやってることは少ないので、ちょっと設定を足せば動かせる。

とりあえず dockerd に iptables を触らせないようにして、

# /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --iptables=false

あとは nftables の設定で masquerade を足せばいい。nftables だと変数使えて便利ですね。

define docker_bridges = {"docker0", "br-0123456789ab"}

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

    ct state {established, related} accept;
    ct state invalid drop;

    iifname $docker_bridges accept;
  }
}

table ip nat {
  chain prerouting {
    type nat hook prerouting priority 0;
  }

  chain postrouting {
    type nat hook postrouting priority 0;
    oifname != $docker_bridges masquerade;
  }
}

Docker の network を作成すると br-${network_id} というブリッジが作成されるので、Docker の network を作成するたびに手動で編集する必要があるのがだるいけど、まぁ network を増やすことはそんなに発生しないはず。