初探Docker的网络模式


刚接触Docker的时候,你是否好奇容器之间是怎么通信的呢?今天我们就一起来认识一下Docker的网络吧~

Docker的网络模块是可插拔式的,默认有五种网络模式可以选择。

通过docker network ls这个命令来查看本机中所有的网络模式。
[root@VM_0_14_centos ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
c79756cf9cde        bridge              bridge              local
204025a5abbc        host                host                local
9b9024f5ac40        macvlan             macvlan             local
6478888548d8        none                null                local
p2e02u1zhn8x        overlay             overlay             swarm

下面就让我们来动手实践一下这五种模式吧!

Bridge

Bridge模式是Docker的默认网络模式,此模式会为每一个容器设置Network Namespace、IP地址等,在Docker启动时候,就会在主机上创建一个名为docker0的虚拟网桥,在该主机上启动的Docker容器都会连接到这个虚拟网桥上,这样就可以和同一宿主机上桥接模式的其它容器进行通信啦。
#运行一个名为box1的busybox容器,网络模式是bridge
[root@VM_0_14_centos ~]# docker run -itd --name box1 busybox
24d88c0b3af9df06c367e9991c7628a2eaeb54e4f40a5326585fcf1274ea2f8f
[root@VM_0_14_centos ~]# docker exec -it box1 sh
/ # ip addr show eth0
68: eth0@if69: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
   valid_lft forever preferred_lft forever

#运行一个名为box2的busybox容器,网络模式是bridge       
[root@VM_0_14_centos ~]# docker run -itd --name box2 busybox
f3980be667731ae36aa567910f4a7e80fcc877c33dec59b70f7dc6e49f8fe3f2
[root@VM_0_14_centos ~]# docker exec -it box2 sh
/ # ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.146 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.120 ms
...

从上面的示例可以看出,同一节点下的容器默认都是可以彼此交流哒~
1.png

Host

Host模式下,容器不会设置自己的Network Namespace、IP等,而是和宿主机共用,通过--network host可以将容器直接绑定在Docker主机的网络,没有网络隔离,但是其它方面,比如文件系统、进程列表还是与宿主机隔离的。外界也可以直接访问容器。
#运行一个名为box3的busybox容器,网络模式是host
[root@VM_0_14_centos ~]# docker run -itd --network host --name box3 busybox

BusyBox

接下来我们来比较一下宿主机和容器box3的网络,不用怀疑,肯定是一样的啦。
[root@VM_0_14_centos ~]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:26:bb:53 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.14/20 brd 172.17.15.255 scope global eth0
   valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe26:bb53/64 scope link
   valid_lft forever preferred_lft forever

[root@VM_0_14_centos ~]# docker exec -it box3 sh
/ # ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 52:54:00:26:bb:53 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.14/20 brd 172.17.15.255 scope global eth0
   valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe26:bb53/64 scope link
   valid_lft forever preferred_lft forever

Macvlan

对于某一些应用程序,比如需要监视网络流量,期望直接连接到物理网络,这种情况下,可以使用Macvlan的网络模式,Docker会为容器的虚拟网络接口分配MAC地址。

创建一个Macvlan网络:
$ docker network create -d macvlan --subnet=172.16.86.0/24 --gateway=172.16.86.1 -o parent=eth0 macvlann

启动一个BusyBox容器,网络模式是Macvlan:
[root@VM_0_14_centos ~]# docker run -itd --network macvlan --name box busybox
77436b9c2c1638c498396ff765c27ffec885ff62d892c2064f41497460037156

[root@VM_0_14_centos ~]# docker exec box ip addr show eth0
67: eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:10:56:03 brd ff:ff:ff:ff:ff:ff
inet 172.16.86.3/24 brd 172.16.86.255 scope global eth0
   valid_lft forever preferred_lft forever

[root@VM_0_14_centos ~]# docker exec box ip route
default via 172.16.86.1 dev eth0
172.16.86.0/24 dev eth0 scope link  src 172.16.86.3

Overlay

Overlay网络是使用在Swarm集群中,用于连接不同主机上的Docker容器,允许不同宿主机上的容器相互通信。
#通过此命令我们可以创建集群中的manager,在输出信息中会包含一个token
[root@VM_0_14_centos ~]# docker swarm init

然后执行以下命令将工作节点加入集群。
$ docker swarm join --token <token> <manager_host>:2377

新建一个Overlay网络:
[root@VM_0_14_centos ~]# docker network create --driver=overlay --attachable overlay

#列出Docker Swarm中所有节点,其中VM_0_14_centos这个节点是leader,其它两个节点是工作节点
[root@VM_0_14_centos ~]# docker node ls
ID                            HOSTNAME                  STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
sa3m7r6m1lg4iz6dcfvyggr6s *   VM_0_14_centos             Ready               Active              Leader              19.03.11
azpq5fgozz5rd9y4lm11u69wq     VM_0_15_centos             Ready               Active                                  19.03.11
5mbf4l9k0y8zg69il7pk5ztxw     VM_0_16_centos             Ready               Active                                  19.03.7

分别在manager节点和work节点上启动一个BusyBox容器,并连接到Overlay网络。
$ docker run -it --network overlay --name box4 sh

然后我们在同一个Overlay网络下的容器中互相去ping对方,是可以连接哒~

我们也可以利用Overlay网络去创建一个集群服务,使用Docker Swarm去管理我们的集群服务。现在创建一个五副本的连接到Overlay网络的Nginx服务,暴露端口为80。
$ docker service create --name my-nginx --publish target=80,published=80 --replicas=5 --network overlay nginx

利用docker ps命令我们可以发现工作节点上也启动了Nginx应用,这个就是通过Overlay来实现不同主机中容器之间的通信。细心的小伙伴还会发现在任一节点结束一个副本,集群服务就会重启一个新的副本,会一直保持节点内的Nginx副本数量为五个,有木有觉得还蛮有意思的!
[root@VM_0_15_centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
1bf24ed438cf        nginx:latest        "/docker-entrypoint.…"   16 minutes ago      Up 16 minutes       80/tcp                 my-nginx.3.lcrhn4eelu1d5z4ln1ss9dczq

Overlay网络模型在Docker集群节点间的加入了一层虚拟网络,它有独立的虚拟网段,因此Docker容器发送的内容,会先发送到虚拟子网,再由虚拟子网包装为宿主机的真实网址进行发送。
2.png

None

使用的None模式后,这个容器就是封闭的,不会去参与网络通信,这样就能够保证容器的安全性。
#启动一个名为box3的BusyBox容器,网络模式是None
[root@VM_0_14_centos ~]# docker run -itd --network none --name box3 busybox
f431bffbd88712f940aee745d7a1e6795f3ef545f79bb2151628f9198c9b1c1e
[root@VM_0_14_centos ~]# docker exec -it box3 sh
/ # ifconfig
lo        Link encap:Local Loopback
      inet addr:127.0.0.1  Mask:255.0.0.0
      UP LOOPBACK RUNNING  MTU:65536  Metric:1
      RX packets:0 errors:0 dropped:0 overruns:0 frame:0
      TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
      collisions:0 txqueuelen:1000
      RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

总结

Docker网络就介绍到这啦,通过上面的实践我们不难发现:
  1. 在需要多个Docker容器在同一个宿主机上进行通信,最好就直接使用默认的Bridge模式;
  2. 当多个应用程序需要组成集群提供高可用服务时候,Overlay肯定是最佳的选择;
  3. Host模式对于优化性能以及在容器需要处理大量端口的情况下很有用,因为它不需要NAT,并且也不会为每个端口创建“ userland-proxy”。当想要容器对网络传输效率有较高要求,就可以选择Host模式,但是要注意端口占用的问题哦~


原文链接:https://mp.weixin.qq.com/s/nPCAprqbFzrvTbFRJaRP8A

0 个评论

要回复文章请先登录注册