Docker bridge network with swarm scope does not accept subnet and driver options

Viewed 1739

I want to control which external IP is used to send traffic from my swarm containers, this can be easily used with a bridge network and iptables rules.

This works fine for local-scoped bridge networks:

docker network create --driver=bridge --scope=local --subnet=172.123.0.0/16 -o "com.docker.network.bridge.enable_ip_masquerade"="false" -o "com.docker.network.bridge.name"="my_local_bridge" my_local_bridge

and on iptables:

sudo iptables -t nat -A POSTROUTING -s 172.123.0.0/16 ! -o my_local_bridge -j SNAT --to-source <my_external_ip>

This is the output of docker network inspect my_local_bridge:

[
    {
        "Name": "my_local_bridge",
        "Id": "...",
        "Created": "...",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.123.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            ...
        },
        "Options": {
            "com.docker.network.bridge.enable_ip_masquerade": "false",
            "com.docker.network.bridge.name": "my_local_bridge"
        },
        "Labels": {}
    }
]

But if I try to attach a swarm container to this network I get this error:

network "my_local_bridge" is declared as external, but it is not in the right scope: "local" instead of "swarm"

Alright, great, let's switch the scope to swarm then, right? Wrong, oh so wrong.

Creating the network:

docker network create --driver=bridge --scope=swarm --subnet=172.123.0.0/16 -o "com.docker.network.bridge.enable_ip_masquerade"="false" -o "com.docker.network.bridge.name"="my_swarm_bridge" my_swarm_bridge

Now let's check docker network inspect my_swarm_bridge:

[
    {
        "Name": "my_swarm_bridge",
        "Id": "...",
        "Created": "...",
        "Scope": "swarm",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            ...
        },
        "Options": {},
        "Labels": {}
    }
]

I can now attach it to swarm containers just fine, but neither the options are set, nor the subnet is what I defined...

How can I set these options for "swarm"-scoped bridge networks? Or, how can I set iptables to use a defined external IP if I can't set com.docker.network.bridge.enable_ip_masquerade to false?

Do I need to make a script to check the subnet assigned and manually delete the iptables MASQUERADE rule?

thanks guys

1 Answers

I'm pretty sure you can't use the bridge driver with swarm, and that you should use the overlay driver. From Docker documentation :

Bridge networks apply to containers running on the same Docker daemon host. For communication among containers running on different Docker daemon hosts, you can either manage routing at the OS level, or you can use an overlay network.

I might not understand your particular use case though ...

Related