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 命令可以把主机的端⼝号映射到容器的内部端⼝号,解决了潜在的端⼝冲突问题。

更多推荐