linux docker 端口无法访问_Docker容器是如何进行网络通信的

b3cde1b11a35f044a614ff9369a948f4.png
Docker是基于go语言开发,Linux下的底层技术主要基于cgroups、namespace以及联合文件技术实现的一种进程级别的轻量级虚拟化解决方案。由于Docker进程隔离独立于宿主机上其他进程,因此也称为容器,Docker在容器的基础上,进行了更进一步的封装,从文件系统、网络到进程隔离等,极大简化了容器的创建管理维护工作,降低了开发者使用门槛,因此才在近几年流行开来(毕竟Docker的底层技术在Docker出现之前就已经存在了)。

Docker作为一种容器技术,在目前的分布式和微服务系统中被广泛使用,因为要在多个容器或机器间进行通信,因此Docker网络通信是一个重要的技术点。从网络架构的角度来看,所有的容器实际上是通过本地主机的网桥接口(docker0)进行相互通信,就像物理机器通过物理交换机通信一样

Docker服务启动时会首先在主机上自动创建一个docker0虚拟网桥,实际上是一个Linux网桥。网桥可以理解为一个软件交换机,负责挂载其上的接口之间进行包转发。同时,Docker随机分配一个本地未占用的私有网段(在RFC1918中定义)中的一个地址给docker0接口。比如典型的172.17.0.0/16网段,掩码为255.255.0.0,此后启动的容器内的网口也会自动分配一个该网段的地址。

当创建一个Docker容器的时候,同时会创建了一对veth pair互联接口。当向任一个接口发送包时,另外一个接口自动收到相同的包。互联接口的一端位于容器内,即eth0;另一端在本地并被挂载到docker0网桥,名称以veth开头。通过这种方式,主机可以与容器通信,容器之间也可以相互通信。如此一来,Docker就创建了在主机和所有容器之间一个虚拟共享网络:

411e57dd1533dbc92ac00e129ada9d34.png

默认情况下,Docker容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器,可通过命令 docker port container查看对应容器的端口映射信息。Docker容器使用的是私有网络IP,那么容器访问外部流程是什么样的呢?

假设容器内部的网络地址为172.17.0.2,本地网络地址为10.0.2.2,容器要能访问外部网络,源地址不能为172.17.0.2,需要进行源地址映射(Source NAT, SNAT),修改为本地系统的IP地址10.0.2.2。映射是通过iptables的源地址伪装操作实现的。查看主机nat表上POSTROUTING链的规则。该链负责网包要离开主机前,改写其源地址。其中,上述规则将所有源地址在172.17.0.0/16网段,且不是从docker0接口发出的流量(即从容器中出来的流量),动态伪装为从系统网卡发出。MASQUERADE行动与传统SNAT行动相比,好处是能动态地从网卡获取地址。

知道了容器内部访问外部流程,如果外部想要访问内部该如何实现呢?容器允许外部访问,可以在docker [container] run时候通过-p或-P参数来启用容器内外端口的映射配置。不管用哪种办法,其实也是在本地的iptable的nat表中添加相应的规则,将访问外部IP地址的包进行目标地址DNAT,将目标地址修改为容器的IP地址。每次创建一个新容器的时候,Docker从可用的地址段中选择一个空闲的IP地址分配给容器的eth0端口,并且使用本地主机上docker0接口的IP作为容器的默认网关。目前docker不支持启动时配置ip地址。

上面所说的是docker容器的默认网络通信模式—bridge模式,容器拥有独立的网络命名空间和网络协议栈,如果容器启动过程中不添加--net参数配置,则默认采用这种网络通信默认。除了bridge模式之外,还可以配置host网络模式,直接使用容器宿主机的网络命名空间,该模式下容器不再拥有自己独立的网络环境,直接使用宿主机的IP和端口。当然用户也可自定义网络模式或者none模式等。

推荐阅读

开发者不可不知的 Docker 命令​mp.weixin.qq.com
b7a9089115743573a957b0779a92c0c0.png
Linux Namespace浅析​mp.weixin.qq.com
90898c402b2a0c2ebf054ac9b455e4a2.png
Linux Cgroup浅析​mp.weixin.qq.com
a1324e9d8430e52f05cd317ecdb11b75.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值