端口映射
1.就是把容器的端口映射为宿主机的一个随机或者特定端口
2.使得外部用户可以访问容器服务
3.本质其实就是在底层做了iptables地址转发
4.出去的流量是做SNAT原地址转发
5.进来的流量是做DNAT目标地址转发
分为四种情况:
1.随机映射,就是把容器的端口随机映射为宿主机的一个端口 -P --publish-all
2.特定映射,映射为宿主机的特定端口 -p
3.特定映射,映射为宿主机的特定网卡的随机端口 -p
4.特定映射,映射为宿主机的特定网卡的特定端口 -p
例子1:随机映射 -P #-P是把容器内的所有端口随机映射为宿主机的随机端口
[root@ken1 ~]# docker run -d -P httpd
例子2:特定映射,映射为宿主机的特定端口
[root@ken1 ~]# docker run -d -p 81:80 httpd #注意-p后面顺序 宿主机端口:容器端口
例子3:特定映射,映射为宿主机的特定网卡的随机端口
[root@ken1 ~]# docker run -d -p 192.168.64.5::80 httpd
例子4:特定映射,映射为宿主机的特定网卡的特定端口 -p
[root@ken1 ~]# docker run -d -p 192.168.64.5:82:80 httpd
端口映射分析:
每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量:
[root@ken3 ~]# ps aux | grep docker-proxy root 3414 0.0 0.1 364368 7040 ? Sl 22:29 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 56 -container-ip 172.17.0.3 -container-port 80
以 0.0.0.0:32773->80/tcp 为例分析整个过程:
1. docker-proxy 监听 host 的 32773 端口。
2. 当 curl 访问 10.0.2.15:32773 时,docker-proxy 转发给容器 172.17.0.2:80。
3. httpd 容器响应请求并返回结果。
底层依然是iptables:
[root@ken3 ~]# iptables -t nat -S -P PREROUTING ACCEPT -P INPUT ACCEPT -P OUTPUT ACCEPT -P POSTROUTING ACCEPT -N DOCKER -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 172.18.0.0/16 ! -o br-060b813f7eeb -j MASQUERADE -A POSTROUTING -s 192.168.6.0/24 ! -o br-1f44876ac489 -j MASQUERADE -A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE -A DOCKER -i docker0 -j RETURN -A DOCKER -i br-060b813f7eeb -j RETURN -A DOCKER -i br-1f44876ac489 -j RETURN -A DOCKER ! -i docker0 -p tcp -m tcp --dport 56 -j DNAT --to-destination 172.17.0.3:80