Docker-Bridge Network 02 容器与外部通信
本小节介绍bridge network模式下,容器与外部的通信。
1.前言2.容器访问外部2.1 访问外网2.2 原理2.3 一张图总结2.4 抓包3.外部访问容器3.1 创建nginx容器并从外部访问3.2 原理3.3 一张图总结3.4 抓包3.5 docker-proxy4.小结
1.前言
上一节介绍了容容器之间的通信过程。容器中部署了服务,我们肯定要从外部去访问这个服务,那么,容器如何与外部进行通信呢?
2.容器访问外部
这一节,我们仍然使用bbox1容器进行实验。首先要确保虚拟机Host1能访问外网。在“准备Docker环境”那一节,介绍了虚拟机如何直接ping通百度。
要说明一点,外部网络不一定指互联网,外部与内部是相对的概念。只要是容器网络以外的网络,都可以称作外部网络,比如Host1所在的网络。
2.1 访问外网
[root@docker1 ~]# docker exec -it bbox1 sh
/ # ping www.baidu.com
PING www.baidu.com (180.101.49.11): 56 data bytes
64 bytes from 180.101.49.11: seq=0 ttl=51 time=21.308 ms
64 bytes from 180.101.49.11: seq=1 ttl=51 time=24.613 ms
2.2 原理
回顾一下当前容器的网络连接情况:
我们试着分析一下,bbox1发出ping包,根据bbox1的路由表,报文被送到了docker0。那docker0和enp0s3是怎么连接的呢?
Linux本身就有路由转发功能,所以其实linux系统本身可以作为一个路由器。执行命令cat /proc/sys/net/ipv4/ip_forward
,能看到ip_forward=1,说明系统开启了路由转发。
那么docker0发出数据包后,应该是根据Host的路由表进行转发。而Host的默认路由是指向enp0s3的,所以enp0s3收到了数据包。
我个人理解,此时enp0s3上数据包的源IP是bbox1的,目的IP是baidu,应该是能够到达baidu的;但是在baidu发回应答包的时候,它不知道这个私网IP在哪,通过任何一级路由都找不到,所以enp0s3这里发出报文前就得进行SNAT。
具体回包过程我不太明白,有明白的同学麻烦具体解释一下,感谢。
说到SNAT,就必须得提到Linux内核的大杀器——IPtables了。
在虚拟机中执行iptables -t nat -vnL
,查看nat表。
Chain POSTROUTING (policy ACCEPT 21 packets, 1479 bytes)
pkts bytes target prot opt in out source destination
3 202 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
docker0发出报文后会经过linux内核的路由转发,到达enp0s3。而到达enp0s3之前,会经过iptables的POSTROUTING
链进行SNAT,就是上面这条规则。大意是指把源IP为172.17.0.0/16、目的IP任意的报文,进行MASQUERADE(伪装),也就是SNAT,即把源IP和MAC替换,替换成路由选择之后的enp0s3的IP和MAC。
2.3 一张图总结
- bbox1 ping 百度,报文发往docker0;
- docker0发出报文,经过内核的路由转发和SNAT处理,将报文的源IP及MAC换成了enp0s3的IP和MAC,到达enp0s3;
- enp0s3发出报文,访问百度。
2.4 抓包
当前网络设备及地址如下:
设备 | IP | MAC |
---|---|---|
容器bbox1 | 172.17.0.2 | 02:42:ac:11:00:02 |
网桥docker0 | 172.17.0.1 | 02:42:a8:64:6c:32 |
虚拟机网卡enp0s3 | 192.168.0.11 | 08:00:27:70:b6:ef |
在bbox1内部执行ping www.baidu.com
- 在docker0上抓包:
[root@docker1 ~]# tcpdump -nei docker0 icmp
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:49:11.669684 02:42:ac:11:00:02 > 02:42:a8:64:6c:32, ethertype IPv4 (0x0800), length 98: 172.17.0.2 > 180.101.49.11: ICMP echo request, id 9728, seq 0, length 64
12:49:11.697374 02:42:a8:64:6c:32 > 02:42:ac:11:00:02, ethertype IPv4 (0x0800), length 98: 180.101.49.11 > 172.17.0.2: ICMP echo reply, id 9728, seq 0, length 64
- 在enp0s3上抓包:
[root@docker1 ~]# tcpdump -nei enp0s3 icmp
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
12:49:11.669700 08:00:27:70:b6:ef > 48:0e:ec:3b:b3:41, ethertype IPv4 (0x0800), length 98: 192.168.0.11 > 180.101.49.11: ICMP echo request, id 9728, seq 0, length 64
12:49:11.697340 48:0e:ec:3b:b3:41 > 08:00:27:70:b6:ef, ethertype IPv4 (0x0800), length 98: 180.101.49.11 > 192.168.0.11: ICMP echo reply, id 9728, seq 0, length 64
从enp0s3的报文可以看出,源IP和MAC已经是enp0s3的了。
3.外部访问容器
3.1 创建nginx容器并从外部访问
创建一个nginx容器,执行docker run -it -d --name=nginx01 -p 8081:80 nginx
该命令将容器的80端口映射到主机的8081端口。
从本虚拟机上curl 127.0.0.1:8081
,能返回nginx欢迎信息。从另一台虚拟机上curl 192.168.0.11:8081
,也能返回nginx欢迎信息。说明外部网络能访问nginx容器。
3.2 原理
使用了IPtables的DNAT功能。
执行iptables -t nat -vnL
查看IPtables规则,可以发现目的端口8081被替换为172.17.0.4:80。
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0
0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8081 to:172.17.0.4:80
3.3 一张图总结
- 在Host2里面
curl 192.168.0.11:8081
,报文到达Host1的enp0s3; - Host1的enp0s3发出报文后,经由内核的转发及DNAT处理,将目的IP替换成nginx01的IP和端口;
- docker0收到报文后,根据目的mac找到对应端口,送出报文到nginx01。
3.4 抓包
使用tcpdump,在Host1的网卡及docker0上抓包验证。
- Host1的enp0s3
[root@docker1 ~]# tcpdump -nei enp0s3 tcp port 8081
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
13:25:14.725366 08:00:27:d4:6f:d1 > 08:00:27:70:b6:ef, ethertype IPv4 (0x0800), length 74: 192.168.0.12.48392 > 192.168.0.11.tproxy: Flags [S], seq 1433025043, win 29200, options [mss 1460,sackOK,TS val 4294829465 ecr 0,nop,wscale 7], length 0
13:25:14.725559 08:00:27:70:b6:ef > 08:00:27:d4:6f:d1, ethertype IPv4 (0x0800), length 74: 192.168.0.11.tproxy > 192.168.0.12.48392: Flags [S.], seq 404119170, ack 1433025044, win 28960, options [mss 1460,sackOK,TS val 59419808 ecr 4294829465,nop,wscale 7], length 0
- Host1的docker0
[root@docker1 ~]# tcpdump -nei docker0 tcp
listening on docker0, link-type EN10MB (Ethernet), capture size 262144 bytes
13:26:07.014766 02:42:a8:64:6c:32 > 02:42:ac:11:00:04, ethertype IPv4 (0x0800), length 74: 192.168.0.12.48396 > 172.17.0.4.http: Flags [S], seq 1839700092, win 29200, options [mss 1460,sackOK,TS val 4294881751 ecr 0,nop,wscale 7], length 0
13:26:07.015357 02:42:ac:11:00:04 > 02:42:a8:64:6c:32, ethertype IPv4 (0x0800), length 74: 172.17.0.4.http > 192.168.0.12.48396: Flags [S.], seq 3312305882, ack 1839700093, win 28960, options [mss 1460,sackOK,TS val 59472098 ecr 4294881751,nop,wscale 7], length 0
可以看出,docker0上收到的报文,目的IP及MAC已经是nginx01的了。
3.5 docker-proxy
注意:对于外部访问容器,除了iptables DNAT处理外,还有一种方式docker-proxy。网上很多文章写得并不全面,只说了docker-proxy。其实通过上面的分析,只通过DNAT就可以完成外部访问容器了,那docker-proxy什么时候起作用呢?
[root@docker1 ~]# ps -ef|grep proxy
root 4073 927 0 13:07 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8081 -container-ip 172.17.0.4 -container-port 80
root 4143 1521 0 13:32 pts/0 00:00:00 grep --color=auto proxy
查看进程可以发现,我们的host上也开启了docker-proxy,将host的0.0.0.0:8081转发到容器172.17.0.4:80。
关于docker-proxy和DNAT何时起作用,有一篇文章分析的很好,分享给大家《docker-proxy存在合理性分析》。
4.小结
- 容器访问外部,由iptables SNAT实现
- 外部访问容器,由iptables DNAT实现,另外在一些场景下,通过docker-proxy进行转发
下一节,我们介绍bridge network的自定义网络。 点击此处回到docker系列文章目录。
原创文章,转载请声明出处!
-----------------------------------------------------------------------------------------------
本人微信公众号同步更新云计算、容器、网络、编程等文章,欢迎参观!
Docker-Bridge Network 02 容器与外部通信的更多相关文章
- Docker:macvlan实现容器跨主机通信 [十四]
一.什么是macvlan 1.macvlan 本身是 linux kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址, 2.即多个 interface,每个 interface ...
- Docker容器跨主机通信之:直接路由方式
一.Docker网络基本原理 直观上看,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)与外界相通,并可以收发数据包:此外,如果不同子网之间要进行通信,需要额外的路由机制. Docker ...
- centos7下安装docker(15.5容器跨主机网络--flanneld)
flannel是由CoreOS研究的一种覆盖网络(overlay network)网络工具,目的是帮助每一个host主机有一个完整的子网: 功能是:让集群中不同节点的主机创建的容器都有一个唯一的虚拟I ...
- AspNetCore容器化(Docker)部署(二) —— 多容器通信
一.前言 着上一篇 AspNetCore容器化(Docker)部署(一) —— 入门,在单个容器helloworld的基础上引入nginx反向代理服务器组成多容器应用. 二.配置反向代理转接 配置转接 ...
- Docker-Bridge Network 01 容器间通信
本小节介绍bridge network模式下,单机上的容器网络拓扑及通信. 1.前言 对于单机上的容器,Docker提供了bridge.host.none三种网络.我们首先介绍经典的bridge模式. ...
- Docker容器跨主机通信--overlay网络
一.Docker主机间容器通信的解决方案 Docker网络驱动 Overlay: 基于VXLAN封装实现Docker原生Overlay网络 Macvlan: Docker主机网卡接口逻辑上分为多个子接 ...
- Docker 网络管理及容器跨主机通信
1.网络模式 docker支持四种网络模式,使用--net选项指定: host,--net=host,如果指定此模式,容器将不会获得一个独立的network namespace,而是和宿主机共用一个. ...
- docker容器之间的通信
容器之间互通 新建两个容器 docker run -d --name box1 busybox /bin/sh -c "while true;do sleep 3600;done" ...
- (转)Docker - 创建 Docker overlay network (containers 通信)
原文链接: http://www.cnblogs.com/AlanWalkOn/p/6101875.html --- 创建基于Key-Value的Docker overlay network. 这样运 ...
随机推荐
- Journal of Proteome Research | Prediction of an Upper Limit for the Fraction of Interprotein Cross-Links in Large-Scale In Vivo Cross-Linking Studies (分享人:张宇星)
题目:Prediction of an Upper Limit for the Fraction of Interprotein Cross-Links in Large-Scale In Vivo ...
- spring容器概述
这篇博客写一下对spring和springmvc父子容器的理解. 一.首先明确: (1)spring是一个大的父容器,springmvc是其中的一个子容器.父容器不能访问子容器对象,但是子容器可以访问 ...
- elasticsearch基础及在Python中的简单使用
目录 一. 安装java环境与elasticsearch.kibana 二. elasticsearch.kibana的部分文件说明 三. Kibana的Dev tools中ES的简单命令 四. ES ...
- vue one one
目录 Vue 渐进式 JavaScript 框架 一.走进Vue 1.what -- 什么是Vue 2.why -- 为什么要学习Vue 3.special -- 特点 4.how -- 如何使用Vu ...
- 终极解决方案之——Centos7由于误删或更新python导致 No module named yum
之前由于不懂yum和python之间的关系,因为一直在学python3,看到系统里/usr/lib下的python2我就直接删了,结果... 可能还有人是因为python升级的原因,即系统自带的pyt ...
- BFS与DFS常考算法整理
BFS与DFS常考算法整理 Preface BFS(Breath-First Search,广度优先搜索)与DFS(Depth-First Search,深度优先搜索)是两种针对树与图数据结构的遍历或 ...
- ReentrantLock源码解析——虽众但写
在看这篇文章时,笔者默认你已经看过AQS或者已经初步的了解AQS的内部过程. 先简单介绍一下ReentantLock,跟synchronized相同,是可重入的重量级锁.但是其用法则相当不同,首先 ...
- 使用FME将CAD中块参照数据转换为shp数据
暴露出需要导出的字段值,首先在数据查看器中看看CAD中各个图层分别有哪些隐含的字段. CAD快参照中含有多个部分,需要将点按照原始编码聚合成一个点. 属性字段创建,并按照属性字段一一对应CAD中的字段 ...
- 不可思议的hexo,五分钟教你免费搭一个高逼格技术博客
引言 作为程序员拥有一个属于自己的个人技术博客,绝对是百利无一害的事,不仅方便出门装b,面试时亮出博客地址也会让面试官对你的好感度倍增.经常能在很多大佬的技术文章的文末,看到这样一句话: " ...
- [vijos1162]波浪数
题目链接:https://www.vijos.org/p/1162 这题的解法我觉得可能是模拟吧,但是题的分类又是构造QAQ..... 不是很懂,所以我们把这个方法叫做奇技淫巧吧 这题的暴力思路就是针 ...