Moderator: centos7
Docker: installed by yum install -y docker, version number is 1. 10.3.
Docker image:
# version: 0.0.1from Ubuntu: Paul Liu, the latest maintainer, "pollux.liu@msn.com "Run apt-get update, run apt-get install -y net-tools, run apt-get install-y ip utils-ping cmd/bin/bash.
Scene map:
My host is connected to the wireless router, and I dial up the Internet through ADSL. The fixed IP of the network card eth0 is 192. 168.0.200, and the gateway is IP192.168.0/.
Install docker on the host and run the container.
Install docker with the following command.
yum install -y docker
Enable docker,
System startup docker
Then run the ifconfig or ip a command on the host, and you can see that there is a docker0 besides the host's original network cards eth0 and loopback lo.
Docker0 IP is172.17.0.1,and the default network segment is Class B private network address172.17.0.0/16. Docker0 can be regarded as the virtual network card of the host. In this way, the host is equivalent to configuring a dual network card, and the two network cards can communicate, but only if ip_forward is enabled.
This is the first identity of docker0.
Run two containers, docker 1 and docker2, and then run brctl show on the host.
Here you can see the second identity of docker0, the virtual switch. Every time the container runs, it generates a pair of veths, one end of which is connected to docker0 and the other end is connected to eth0 of the container. In this way, all containers connected to docker0 form a local area network. As shown in the figure below:
Running ifconfig on the host will also find two other network interfaces similar to veth.
Run ip addr show veth6d9a69 1 on the host, and you can see that veth has a mac address, which also shows the identity of docker0' s virtual switch. Switches communicate through mac addresses, and devices connected to the switches must have mac addresses.
Docker0 has its own mac address, which is different from pure layer 2 switches and is bound to IP172.17.0.1.docker0 is used as the gateway by default. In other words, docker0 also has the function of routing, so docker0 can be regarded as a three-layer switch, which can do two-layer packet forwarding and three-layer routing forwarding.
Run route -n in the container to see the following path:
Run route -n on the host to view the route, as follows:
In host, visiting this network segment 192. 168.0.0 is to forward packets through eth0, and visiting network segment 172. 17.0.0 is to forward packets through docker0. For other public networks, packets should be forwarded to gateway/kloc-0.
Run ping sohu.com or ping 192. 168.0.200 in the container to ping.
By default, no additional configuration is required. On a host, the containers can communicate with each other through docker0, and can also be connected to the external network through the host's eth0.
Generally speaking, an Ethernet with a network segment of172.17.0.0/16 is formed through docker0. When the docker container initiates a request, it will be forwarded to the target machine through docker0. If it is a different network segment, it will be forwarded to eth0, another network card of the host, which is responsible for the next step.
Let's further analyze how messages are sent to the outside.
The public network request message is sent inside the container and received at veth through eth0. At this point, the message has arrived at the host. If it is found that the message should be sent from the default gateway through the host's eth0 by querying the host's routing table (route -n), the message will be forwarded from docker0 to the host's eth0, but the packet can only be passed between the host's docker0 and eth0 network cards if the ip_forward function is enabled first.
Because the target address does not belong to the network segment where the host is located, it will match the rules in the POSTROUTING chain of nat table in iptables on the machine.
Run the command iptables-l-n-t nat-line-numbers on the host and check the nat table. Here, just look at the routing back chain:
The first line shows that the packet with the source address of172.17.0.0/16 has been disguised by MQSQUERADE before being sent out. The linux kernel will modify the address where the source address of the packet is the host eth0 (that is, 192. 168.0.200), and then forward the packet. The message is sent from the host eth0 to the outside.
Because the machines in the LAN are all private IP, they can't access the Internet directly (the packets can be sent out, but they can't come back). ) If you want to surf the Internet, you can add SNAT rules to the POSTROUTING chain in the NAT table of iptables, not only through hardware routers, but also through software routing.
Test, run the command iptables-t NAT-d post routing1on the host to delete the first rule, and then run the command ping sohu.com in the container, which also doesn't work. But you can still ping the host.
Run the command on the host to recover:
Iptables-t NAT-i post routing-s172.17.0.016-oeth0-jsnat to the source 192. 168.0.200.
or
Iptables-t NAT-i post routing-s172.17.0.0/16-j disguise.
About SNAT and masked ball, this article has already been described. You can refer to it: Docker prequel linux iptables.
Create a new Dockerfile file to run the nginx container:
# version: 0.0.1frompaulliu/Ubuntu _ IP run apt-get install -y nginx EXPOSE 80.
Run the build command on the host to build the image docker build -t paulliu/nginx.
Run the container startup command docker run-d-p 80-name nginx1paulliu/nginx nginx-g "to guard the host;
Check the port mapping docker port nginx 1 80 of the container on the host.
Run the command iptables -nat -L -n on the host, and you can see that the following DNAT rules are added to the pre-routing chain:
That is, when the container is started, the host192.168.0.200: 32773 is mapped to the container 172. 17.0.4:80 through -p 80.
Note: the IP address obtained by docker container is not necessarily the same every time it is started, and -p 80 randomly selects a port number on the host for mapping, and the port number is not necessarily the same every time it is started. However, the related rules in iptables are automatically changed.
Running curl localhost:32773 on the host or curl192 438+068.0.200: 32773 on other hosts will produce the following results: