springloaded
springloaded

Reputation: 1079

How to give a docker container its own routable IP (different from the host's)?

I am trying to give containers a routable IP. My local network is 192.168.1.0/24 and I'd like to use 192.168.1.17/29 to give containers.

The goal is to have each container have their own IP. This way if two containers run a webserver on port 80, I can reach them directly from any other host on the local network via their unique IP on port 80 instead of mapping them to different ports on the shared host's IP.

Similar to how a physical machine with its own network card would each have distinct 192.168.1.xxx IPs on the network.

I tried this:

docker network create --subnet 192.168.1.0/24 --ip-range 192.168.1.17/29 --gateway 192.168.1.1 test_nw

which yields the following:

$ docker network inspect test_nw 
[
    {
        "Name": "test_nw",
        "Id": "96bd574300059ef3710527a9bd0b3010d3b3c22d8de321ff459697eda96ab5e6",
        "Created": "2017-12-06T21:50:08.591070587-05:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.1.0/24",
                    "IPRange": "192.168.1.17/29",
                    "Gateway": "192.168.1.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

In this case from within a container, I can ping 192.168.1.1 but I can't ping anything on the internet (either by IP or by hostname.), and I can't even ping other devices on the local network (192.168.1.2 exists but is unreachable)

The host (my laptop) is also unable to reach anything on the internet or on my local network anymore until I remove this network with docker network rm.

I'm obviously missing something, but I can't understand what. Is there any way to achieve what I'm trying to do?

Upvotes: 2

Views: 3227

Answers (1)

larsks
larsks

Reputation: 311605

This way if two containers run a webserver on port 80, I can reach them directly from any other host on the local network via their unique IP on port 80 instead of mapping them to different ports on the shared host's IP.

I think maybe you are thinking about this problem wrong. You don't have to map them to different ports on the shared host's IP. The most common way of solving this problem is to assign multiple ip addresses to the host. For example, if my host is 192.168.1.100, I might add some additional addresses:

ip addr add 192.168.1.200/24 dev eth0
ip addr add 192.168.1.201/24 dev eth0

Now I can start up one webserver and bind it to the first ip address:

docker run -p 192.168.1.200:80:80 mywebserver1

And I can start another webserver and map that to port 80 on the other address:

docker run -p 192.168.1.201:80:80 mywebserver2

This seems to meet your goal.

Upvotes: 1

Related Questions