SoFunction
Updated on 2025-03-09

Method for binding Dokcer container to the host specified network card

If your host has multiple network cards, you may need to bind the Docker container to the specified network card so that all network requests in the container will be sent to the external network through the specified network card.

Unfortunately, Docker does not directly provide a way to implement this requirement. However, it can be easily done with iptables.

One-size-fits-all

Suppose you have two network cards on your host: the IP address of one network card is 192.168.0.100; the IP address of the other network card is 10.0.0.100. You want all services in the Docker container on this host to go to and from the external network through the second network card.

Give the answer first and then explain:

Copy the codeThe code is as follows:
iptables -t nat -I POSTROUTING -p all -s 172.17.0.0/16 -j SNAT --to-source 10.0.0.100

The iptables command above creates a source address translation (SNAT) rule, modifying the source IP addresses of all packets from the 172.17.0.0/16 network segment and about to flow out of this host to 10.0.0.100.

For 10.0.0.100 we know that it is the IP address of the second network card of the host. And where did 172.17.0.0/16 come from?

Simply put, when Docker is running on the host, it creates a bridge named docker0 on the host with an IP address of 172.17.0.1 and a segment of 172.17.0.0/16. By default, Docker assigns an IP address to all containers from this network segment.

For more detailed instructions, please refer to this article "Default Network Configuration of Docker under Single Host".

The IP addresses of all Docker containers are in the 172.17.0.0/16 network segment. Then, the rule created by the iptables command above is to modify the source IP addresses of all packets from the Docker container and about to flow out of the host to the IP address of the second network card of the host, that is, 10.0.0.100.

In this way, the "output" half of our needs is achieved.

The implementation of the "enter" half of the requirements is also very simple. You only need to specify the host IP through the -p parameter when docker run, such as:

docker run -p 10.0.0.100:80:80 ...

Divide and govern

The demand changes very quickly, maybe we have another network card, with an IP address of 10.0.0.101. For some reason, we want to let some container traffic go to the second network card, and at the same time let the other container traffic go to the newly added third network card.

Since Docker does not allow the IP address to be specified for the container when using the default bridge (if you specify an IP address, Docker will give the following error message), we cannot predict in advance what the IP address will be assigned to a container in the end, and we cannot specify an egress network card for it through the iptables rule in advance.

docker: Error response from daemon: user specified IP address is supported on user defined networks only.

In fact, the above error message has given a solution, that is, user-defined network.

Create a custom network with the following command:

Copy the codeThe code is as follows:
docker network create --subnet=172.18.0.0/16 --opt ""="docker1"  docker1

Among them, 172.18.0.0/16 is the network segment where the newly built bridge is located. Because the Dokcer default bridge already occupies 172.17.0.0/16, new bridges can only use other network segments that are not occupied.

The first docker1 is the bridge name displayed when executing the ifconfig -a command. If you do not specify this name with the --opt parameter, then when you use the ifconfig -a command to view network information, you will see a name like br-110eb56a0b22. This is obviously not very good-looking/remember;

The second docker1 is the bridge name displayed when executing the docker network list command.

With a custom network, we can assign a fixed IP address to the container.

docker run --network=docker1 --ip=172.18.0.100 ......
docker run --network=docker1 --ip=172.18.0.101 ......

Once we know the fixed IP address of the container, we can do the same and bind the container to the specified host network card:

iptables -t nat -I POSTROUTING -p all -s 172.18.0.100 -j SNAT --to-source 10.0.0.100
iptables -t nat -I POSTROUTING -p all -s 172.18.0.101 -j SNAT --to-source 10.0.0.101

It should be noted that the parameter followed by the -s option here is the IP address, not the network segment.

Other related commands

View iptables rules

iptables -t nat -L -n --line-number

Delete iptables rules

iptables -t nat -D POSTROUTING 11

Among them, the last 11 is the rule number (num) to be deleted.

Delete Docker custom network

docker network rm docker1

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.