The problem and solution of Docker can't bind to static external network

  • 2020-06-03 08:59:36
  • OfStack

Some time ago, I have been studying how to assign static ip to Docker, the main purpose of which is to let thrift come in and go out 1 ip, and the crawler can be independent of ip address, so as to achieve a good crawler multi-ES6en way... 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, just because of these two problems doesn't mean that we should abandon the problem... .

In Docker run, we can add the -ES16en parameter to control its source source ip. The following command, speaking externally, opens port 192.168.1.200:9200... But we are more than that. docker ES20en-ES21en port is implemented by borrowing iptables... When we are iptables-ES24en nat-ES26en, we can see the nat relationship that docker makes for me... When docker does prerouting of iptables, a custom chain called docker is added... Almost beside the point again, if it's in bridge mode, then it makes it very complicated to change the port map if we have a large port change in the container, one iptables prerouting map for every change... However, if you choose HOST network mode, you will not be able to determine which ip address your app is bound to. Not all servers support bind ip address. Some lousy servers bind the first ip address by default... At this point, it becomes necessary to assign a separate static ip address to the docker container... Anyway, just one ip address, you can toss about... .


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, 1 must change its network card mode to docker's none... When docker customizes the network, the container will have a network like net=none. .

Then, if I want to completely allocate an extranet ip to the container, or manage ip, just a static independent ip, how can I break it? This is possible with pipework. But it's a little more complicated, so let's start with ip netns... Through inspect we know his state pid.

Python


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

So let's start binding static ip addresses, but don't look at the principle, just do it for now...

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 of these, we will find that there is an lo network card in the container and an eth0 network card. The ip address of the network card is exactly the 192.168.1.200 that we just bound

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 to fixed static ip has been explained... After reading the article, you will find that docker binding ip is relatively simple.. The network of docker is not easy to understand. In the past two days, I have devoted myself to the whole process of docker's allocation of ip (docker iptables).


Related articles: