300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Docker容器——容器间的通信(端口映射 互联机制)

Docker容器——容器间的通信(端口映射 互联机制)

时间:2024-04-03 16:26:20

相关推荐

Docker容器——容器间的通信(端口映射 互联机制)

容器如何与外部世界通信,这里涉及两个方向

1.容器访问外部世界

2.外部世界访问容器

当宿主机可以上网时,容器不用配置就可以访问外网

[root@su1 harbor]# ping PING www. (39.156.66.14) 56(84) bytes of data.64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=1 ttl=50 time=72.8 ms64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=2 ttl=50 time=74.4 ms[root@su1 harbor]# docker run -it busybox/ # ping PING (39.156.66.14): 56 data bytes64 bytes from 39.156.66.14: seq=0 ttl=49 time=63.303 ms64 bytes from 39.156.66.14: seq=1 ttl=49 time=46.477 ms

busybox位于docker0这个私有bridge网络中(172.17.0.0/16)

busybox从容器向外ping时,数据包是怎样到达的呢 这里的关键就是NAT 我们查看以下docker host 上的iptables规则

查看iptables规则

[root@su1 ~]# iptables -t nat -S -P PREROUTING ACCEPT-P INPUT ACCEPT-P OUTPUT ACCEPT-P POSTROUTING ACCEPT-N DOCKER-N OUTPUT_direct-N POSTROUTING_ZONES-N POSTROUTING_ZONES_SOURCE-N POSTROUTING_direct-N POST_public-N POST_public_allow-N POST_public_deny-N POST_public_log-N PREROUTING_ZONES-N PREROUTING_ZONES_SOURCE-N PREROUTING_direct-N PRE_public-N PRE_public_allow-N PRE_public_deny-N PRE_public_log-A PREROUTING -j PREROUTING_direct-A PREROUTING -j PREROUTING_ZONES_SOURCE-A PREROUTING -j PREROUTING_ZONES-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER-A OUTPUT -j OUTPUT_direct-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER-A POSTROUTING -s 172.22.0.0/24 ! -o br-74fb4d7b7af1 -j MASQUERADE-A POSTROUTING -s 172.20.0.0/16 ! -o br-88c3c24e0863 -j MASQUERADE-A POSTROUTING -s 172.19.0.0/16 ! -o br-ba6e4fa36e51 -j MASQUERADE-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

解析:如果网桥docker0收到来自172.17.0.0/16网段的外出包,把它交给MASQUERADE处理,而MASQUERADE的处理方式是将包的源地址替换成host的地址发送出去,经过MASQUERADE进行ip地址伪装与外界通信,即做了一次网络地址转换(NAT)

下面我们通过tcpdump查看地址是如何转换的 先查看docker host路由表

[root@su1 ~]# ip r默认路由通过eth0发出去的,所以我们要同时监控eth0 和docker0上的icpm(ping)数据包default via 172.25.34.250 dev eth0 proto static metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 172.19.0.0/16 dev br-ba6e4fa36e51 proto kernel scope link src 172.19.0.1 172.20.0.0/16 dev br-88c3c24e0863 proto kernel scope link src 172.20.0.1 172.22.0.0/24 dev br-74fb4d7b7af1 proto kernel scope link src 172.22.0.1 172.25.34.0/24 dev eth0 proto kernel scope link src 172.25.34.8 metric 100

监控数据流向

[root@su1 ~]# yum install -y tcpdump-4.9.2-3.el7.x86_64

1.busybox发送ping包:172.17.0.2 >

2.docker0收到包,发现是发送到外网站的,交给NAT处理

3.NAT将源地址转换成eth0的IP地址:172.25.0.7 >

4.ping包从eth0发送出去,到达

容器ip---->docker0(NAT)----->eth0(NAT)---->enp0s25(NAT)----->

外部世界访问容器

外部如何访问到容器?

端口映射 docker可将容器对外提供服务的端口映射到host的某个端口,外网通过该端口访问容器

将容器的80端口映射到宿主机

[root@su1 harbor]# docker run -d -p 80 httpdUnable to find image 'httpd:latest' locallylatest: Pulling from library/httpd8d691f585fa8: Pull complete 8eb779d8bd44: Pull complete 574add29ec5c: Pull complete 30d7fa9ec230: Pull complete ede292f2b031: Pull complete Digest: sha256:35fcab73dc9ae55db5c4ac33f5e0c7e76b7735aaddb628366bab04db6f8ae96eStatus: Downloaded newer image for httpd:latest09ca48d094a3a53af41b60dff2192b2244eefb86bfc8c8cd6cf5a2fe90800a9d[root@su1 harbor]# docker psCONTAINER ID IMAGECOMMAND CREATED STATUS PORTS NAMES09ca48d094a3 httpd"httpd-foreground" 22 seconds agoUp 20 seconds 0.0.0.0:32768->80/tcp youthful_volhard[root@su1 harbor]# curl 172.25.34.8:32768<html><body><h1>It works!</h1></body></html>除了映射动态端口,也可以在-p中指定映射到host某个特定端口,例如可以将80端口映射到host的8080端口[root@su1 harbor]# docker run -d -p 8080:80 httpdf3f0d046efbff7f4deab4ce0a05fcdd1d6c226baeabe9193320f0c3bfc539b4e[root@su1 harbor]# docker psCONTAINER ID IMAGECOMMAND CREATED STATUS PORTS NAMESf3f0d046efbf httpd"httpd-foreground" 13 seconds agoUp 10 seconds 0.0.0.0:8080->80/tcp trusting_shtern09ca48d094a3 httpd"httpd-foreground" 2 minutes ago Up 2 minutes 0.0.0.0:32768->80/tcp youthful_volhard[root@su1 harbor]# curl 172.25.34.8:8080<html><body><h1>It works!</h1></body></html>

每一个映射的端口,host都会启动一个docker-proxy进程来处理访问容器的流量

[root@su1 harbor]# ps -ef | grep docker_proxyroot2529 2122 0 23:05 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32768 -container-ip 172.17.0.2 -container-port 80root2672 2122 0 23:11 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.3 -container-port 80root2792 2099 0 23:11 pts/0 00:00:00 grep --color=auto docker-proxy

因为端口映射,会有docker-proxy,当访问172.25.34.8:32768时会经过以下流程

172.25.34.8:32768---->docker-proxy----->容器ip:80-----httpd容器响应请求并返回结果----->docker-proxy---->172.25.34.8:32768

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。