SoFunction
Updated on 2025-03-10

Docker cannot bind static external network fixed IP problem and solution

Some time ago, I have been studying how to assign static IPs to Docker. The main purpose is to let Thrift come in and out and go through an IP, and the crawler can have an IP address independently, which can realize the multi-IP method of crawlers... But with the addition of nginx tcp and the development of an IP polling access module based on Python socket, these two problems were solved... Of course, you cannot discard this problem because of these two problems...

When Docker run, we can add the -p parameter to control its source source ip. The following command, for the external purpose, opens the port of 192.168.1.200:9200... But we are not just about this. The implementation of docker run -p port is achieved by borrowing iptables... When we iptables -t nat -L, we can see that docker has done a nat relationship for me... When docker does iptables prerouting, it adds a custom chain called docker... I almost went off topic again. If it is bridge mode, then when we change the port in the container, it will cause the complexity of the operation of changing the port mapping. We need to make an iptables prerouting mapping every time... But if you choose the HOST network mode, then you are not sure which IP address is bound to your app, and not all servers support bind ip addresses... Some servers that are rubbished will bind the first IP address by default... At this time, it is necessary to assign an independent static IP address to the docker container... Anyway, it's just an IP address, you can make a lot of trouble...

Python

docker run -it -p 192.168.1.200:9200:9200 redis_cluster 9200
Python

root@ubuntu:~#
 iptables -t nat -L -n
ChainPREROUTING(policyACCEPT)
target  protoptsource       destination
DOCKER  all -- 0.0.0.0/0      0.0.0.0/0      ADDRTYPEmatchdst-typeLOCAL
ChainINPUT(policyACCEPT)
target  protoptsource       destination
ChainOUTPUT(policyACCEPT)
target  protoptsource       destination
DOCKER  all -- 0.0.0.0/0     !127.0.0.0/8     ADDRTYPEmatchdst-typeLOCAL
ChainPOSTROUTING(policyACCEPT)
target  protoptsource       destination
MASQUERADE all -- 172.17.0.0/16    0.0.0.0/0
MASQUERADE all -- 172.17.0.0/16   !172.17.0.0/16
MASQUERADE tcp -- 172.17.0.1     172.17.0.1     tcpdpt:9200
ChainDOCKER(2references)
target  protoptsource       destination
DNAT   tcp -- 0.0.0.0/0      0.0.0.0/0      tcpdpt:9200to:172.17.0.1:9200

It should be noted that when docker run creates a container, it must change its network card mode to docker's none... Generally, when docker customizes the network, it will turn –net=none, and then make the docker container have a network through a later tossing...

Next, if I want to completely assign an external network IP or manage IP to the container, it is just a static independent IP anyway, how can I break it? It can be achieved with pipework. But this thing is a little more complicated, so we first use the system's ip netns to solve it... Through inspect we know its state pid.

Python

root@ubuntu:~# docker ps -a
CONTAINER ID    IMAGE        COMMAND        CREATED       STATUS       PORTS        NAMES
232621e9e9fb    redis_cluster    "/app/ 9000  41 minutes ago   Up 41 minutes              agitated_blackwell
root@ubuntu:~# docker inspect -f "{{.}}" 232621e9e9fb
4777
root@ubuntu:~# pid=4777

So let's start binding the static IP address, don't look at the principle first, just follow it temporarily...

Python

mkdir-p/var/run/netns
ln-s/proc/$pid/ns/net/var/run/netns/$pidiplinkaddAtypevethpeernameB
brctladdifdocker0A
iplinksetAup
iplinksetBnetns$pid
ipnetnsexec$pidiplinksetdevBnameeth0
ipnetnsexec$pidiplinkseteth0up
ipnetnsexec$pidipaddradd192.168.1.200/24deveth0
ipnetnsexec$pidiprouteadddefaultvia192.168.1.1

After all these are finished, we will find that there is an extra eth0 network card in the container's network card. The IP address of the network card is exactly the 192.168.1.200 we just bound just now

Python

bash-4.1#
 ip a
1:lo:<LOOPBACK,UP,LOWER_UP>mtu65536qdiscnoqueuestateUNKNOWN
  link/loopback00:00:00:00:00:00brd00:00:00:00:00:00
  inet127.0.0.1/8scopehostlo
   valid_lftforeverpreferred_lftforever
  inet6::1/128scopehost
   valid_lftforeverpreferred_lftforever
22:eth0:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscpfifo_faststateUPqlen1000
  link/etherca:aa:87:05:c9:5abrdff:ff:ff:ff:ff:ff
  inet192.168.1.200/24scopeglobaleth0
   valid_lftforeverpreferred_lftforever
  inet6fe80::c8aa:87ff:fe05:c95a/64scopelink
   valid_lftforeverpreferred_lftforever
bash-4.1#

So far, the method of docker binding fixed static ip has been explained clearly... After reading the article, you will find that docker binding ip is relatively simple... The docker network is not easy to understand. In the past two days, I will provide more details on the entire process of docker allocation of ips (docker iptables)

The above is the problem and solution that the Docker cannot bind to static external network fixed IPs that the editor introduces to you. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!