docker Port Mapping and External Inaccessibility Problems

  • 2021-10-11 19:58:58
  • OfStack

The docker container provides services and listens on port 8888, which requires port mapping for external access.


docker run -it --rm -p 8888:8888 server:v1

There is a problem at this point. After deployment on virtual machine A, port 8888 service can be accessed in A, but not in B.

This should be due to the request being blocked.

1. View firewall-cmd--state

If the output is "not running", FirewallD is not running, and all the protection policies are not started, then the firewall blocking the connection can be eliminated.

If the output is "running", indicating that FirewallD is currently running, you need to enter the following command to see which ports and services are open now:


firewall-cmd --list-ports
firewall-cmd --list-services

There are two solutions:

1. Shut down the FirewallD service:

If you don't need a firewall, just turn off the FirewallD service


systemctl stop firewalld.service

2. Add a policy to open the specified port externally:

For example, if we want to open the external 5000/tcp port now, we can use the following command:


firewall-cmd --add-port=5000/tcp --permanent
firewall-cmd --reload

If you only temporarily open the port and remove the "--permanent" parameter in the command line 1, this policy will be invalid when the FirewallD service is restarted again.

2. ip forwarding is not turned on


sysctl net.ipv4.ip_forward

Displaying net. ipv4.ip_forward=0 means it is not open.

3. service iptables opens and intercepts

service iptables can be turned off


service iptables stop

If an error occurs during docker run:

iptables: No chain/target/match by that name.

Simply restart the docker service


service docker restart

Or:


# Settings iptables Firewall is the boot entry  
systemctl enable iptables.service

# Start the firewall to make the configuration file effective  
systemctl start iptables.service

# Stop the firewall  
systemctl stop iptables.service

# Restart the firewall for the configuration file to take effect  
systemctl restart iptables.service

Final version:

After starting docker and port mapping, docker will add DNAT rules to iptables, convert received packets from corresponding ports to ip and forward them, and add rules to convert all ip from docker domain.

However, on Centos7, docker can normally access the external network, but the request sent by the external network cannot be delivered to docker0 after being received and forwarded by eth1, or it appears (oui Unknown). It is not clear why docker0 cannot be delivered after DNAT.

The final solution is to restart iptables after starting docker


service iptables restart

Empty all rules added by docker, and then add rules


iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

Replace all ip of packet 172.17. 0.0/16 from docker with native ip and send it to achieve the purpose of docker accessing external network.


Related articles: