这篇博客主要是记录一下docker配置问题的笔记,不一定适合所有配置,各位如果按照网上大多数人的配置配置完之后还是不能正常实现端口映射,可以将以下配置作为参考。因为之前我在按照网上许多教程配置的时候遇到许多问题,最终就是不能访问docker内部服务,经过一番摸索得出,记录一下,以后配置可作参考,也希望帮到更多人。
docker端口映射,百度之后一大堆都是说在docker run的时候通过-p设置端口映射,这种方法也就一句话就能解决,如果想用这种方法直接百度即可。
现在我想说的是当docker已经创建之后,没有绑定端口,如何通过配置iptables,设置docker端口映射,使外网能够访问服务器内部docker运行的服务。前提是需要已经安装iptables。此处只讲如何配置,可以通过百度iptables配置docker端口映射查看许多大牛讲解原理。
首先,sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' docker_name,docker_name就是自己的容器名或者容器id,查看自己的docker ip,假设是172.17.0.2,下文的docker ip就用这个ip,根据自己的输出自己做调整。
第二,输入sudo iptables -nvxL,看一下chain docker里面有没有:
ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 172.17.0.2 tcp dpt:port_num
port_number就是对应的服务器端口,之前没有配置过的情况下一般没有。执行:
sudo iptables -A DOCKER -d 172.17.0.2 -j ACCEPT -p tcp --dport port_number ! -i docker0 -o docker0
port_number是想要映射的主机端口。在sudo iptable -nvxL查看配置之后的结果,可见多了一条规则,可以发现设置的参数对应为:-A对应在哪个Chain append规则,-d对应destination,-j对应target,--dport对应端口号,-i对应input,-o对应output。以下类似。
第三,输入sudo iptables -t nat -nvxL,查看Chain POSTROUTING ,如果没有配置过,Chain POSTROUTING 下也没有相关的规则:
MASQUERADE tcp -- * * 172.17.0.3 172.17.0.3 tcp dpt:5001
执行:
sudo iptables -t nat -A POSTROUTING -j MASQUERADE -s 172.17.0.2 -d 172.17.0.2 -p tcp --dport11000
输入sudo iptables -t nat -nvxL,可以看到Chain POSTROUTING中加入了配置的规则。但是后面的Chain DOCKER还是少一条规则:
DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:port_number to:172.17.0.2:docker_port
注意!此处的Chain DOCKER是在输入sudo iptables -t nat -nvxL之后查看的,不是输入sudo iptables -nvxL之后查看的,此处设置的是NAT规则,不要混淆。docker_port对应docker上运行的服务的端口。执行:
sudo iptables -t nat -A DOCKER -j DNAT -p tcp ! -i docker0 -s 0.0.0.0/0 -d 0.0.0.0/0 --dport port_number --to 172.17.0.2:docker_port
再次sudo iptables -t nat -nvxL,可以发现规则已经添加上去。
如果配置过程中规则配置错误,可以sudo iptables -nxvL --line-number(或者sudo iptables -t nat -nxvL --line-number)查看错误的规则和这个规则对应的number,通过sudo iptables -D chain_name number(或者sudo iptables -t nat -D chain_name number)删除规则,再重新配置,chain_name就是DOCKER或者POSTOUTING,具体看你的错误规则在那个chain下面,number就是上面说的错误规则对应的number,是否加-t nat就看是否设置的是NAT规则。
好了,其实配置也主要这几步,测试可行
补充脚本:
#!/bin/bash
if [ "$#" -lt "3" ]; then
echo "Usage: sh ./$0 docker_name port_num"
exit
fi
docker_name=$1
port_number=$2
docker_ip=`sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' ${docker_name}`
sudo iptables -A DOCKER -d ${docker_ip} -j ACCEPT -p tcp --dport ${port_number} ! -i docker0 -o docker0
sudo iptables -t nat -A POSTROUTING -j MASQUERADE -s ${docker_ip} -d ${docker_ip} -p tcp --dport ${port_number}
sudo iptables -t nat -A DOCKER -j DNAT -p tcp ! -i docker0 -s 0.0.0.0/0 -d 0.0.0.0/0 --dport ${port_number} --to ${docker_ip}:${port_number}
脚本将docker内的端口映射到宿主机同端口。