【容器与外部系统之间如何通信】
1、如何实现容器与外界网络互通
Docker提供了三种网络模式,分别是是null、host和bridge。
(1)null是最简单的模式,也就是没有网络,但允许其他的网络插件来自定义网络连接。
(2)host是直接使用宿主机网络,相当于去掉了容器的网络隔离(其他隔离依然保留),所有的容器会共享宿主机的IP地址和网卡。这种模式没有中间层,通信效率高,但缺少了隔离,运行太多的容器容易导致端口冲突。
host模式需要在docker run时使用–net=host参数,下面用这个参数启动Nginx:

在本机和容器里分别执行ip addr命令,查看网卡信息和ip地址信息:
ip addr # 本机查看⽹卡
docker exec xxx ip addr # 容器查看⽹卡


可以看到,这两个 ip addr命令的输出信息完全一致,网卡都是ens33,ip地址都是192.168.254.128。
(3)bridge桥接模式,有点类似于现实世界里的交换机、路由器,只不过是由软件虚拟出来的,容器和宿主机再通过虚拟网卡(下图中的docker0)接入这个网桥,这样容器和宿主机就可以正常的收发网络数据包。

和host模式⼀样,也可以⽤ --net=bridge 来启⽤桥接模式,但因为Docker默认的⽹络模式就是bridge,所以⼀般不需要显式指定:
docker run -d --rm nginx:alpine # 默认使⽤桥接模式
docker exec 93d ip addr #查看容器ip,93d是nginx的前3位

对比刚才host模式的输出,可以发现容器里的网卡设置 与宿主机完全不同,eth0是一个虚拟网卡,ip地址是B类私有172.17.0.2,而宿主机的ip地址则是172.17.0.1(安装 Docker 时,它会自动创建一个名为 docker0 的虚拟网桥,这个虚拟网桥 docker0 的ip地址默认是172.17.0.1),所以它们都在172.17.0.0/16这个Docker的默认网段,彼此之间便可以使用IP地址来实现网络通信。
2、如何给容器里的网络服务分配网络端口号
使⽤host模式或者bridge模式,我们的容器就有了IP地址,建⽴了与外部世界的⽹络连接,接下来
要解决的就是⽹络服务的端⼝号问题。服务器应⽤都必须要有端⼝号才能对外提供服务,⽐如HTTP协议⽤80、HTTPS⽤443等。
⼀台主机上的端⼝号数量是有限的,⽽且多个服务之间还不能够冲突,但我们打包镜像应⽤的时候通常都使⽤的是默认端⼝,容器实际运⾏起来就很容易因为端⼝号被占⽤⽽⽆法启动。
解决这个问题的⽅法就是加⼊⼀个“中间层”,由容器环境例如Docker来统⼀管理分配端⼝号,在本
机端⼝和容器端⼝之间做⼀个“映射”操作,容器内部还是⽤⾃⼰的端⼝号,但外界看到的却是另外⼀个端⼝号,这样就很好地避免了冲突。
端⼝号映射需要使⽤bridge模式,并且在 docker run 启动容器时使⽤ -p 参数,比如要启动一个Nginx容器,跑在8080端口上:
docker run -d -p 8080:80 --rm nginx:alpine

这样就把本机的8080端口映射到容器里的80端口,可以用curl再验证一下:
curl 127.1:8080 -I

使用 docker ps能在“PORTS"栏里更直观地看到端口的映射情况:

ok,以上就是容器与外部系统之间沟通交流的两种方法,除此之外,还有几种简单的方法,一并总结如下:
1、 docker cp 命令可以在容器和主机之间互相拷⻉⽂件,适合简单的数据交换。
2、docker run -v 命令可以让容器和主机共享本地⽬录,免去了拷⻉操作,提升⼯作效率。
3、host ⽹络模式让容器与主机共享⽹络栈,效率⾼但容易导致端⼝冲突。
4、 bridge ⽹络模式实现了⼀个虚拟⽹桥,容器和主机都在⼀个私有⽹段内互联互通。
5、docker run -p 命令可以把主机的端⼝号映射到容器的内部端⼝号,解决了潜在的端⼝冲突问题。
更多推荐
所有评论(0)