Docker网络通信

1. Docker网络模式

Docker在创建容器时有四种网络模式,bridge为默认不需要用--net=bridge去指定,其他三种模式需要在创建容器时使用--net去指定。

Docker安装后,会自动创建三个网络,分别为bridge、host、none。可以使用以下命令查看:

ycy@ubuntu18:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
349d6173c6e8        bridge              bridge              local
738ff1fb9923        host                host                local
1abb3c2c9846        none                null                local

1.1 bridge模式

默认情况下,创建一个新的容器都会自动连接到bridge网络,相当于Vmware中的Nat模式。

新建容器有独立的网络命名空间,并通过以下步骤将容器接入docker0中。

(1)创建veth pari虚拟网络对(类似于网线的两头);

(2)将veth pair的一端置于主机的root network namespace中,并将其关联docker0;

(3)将veth pair的另一端置于新建容器的网络命名空间中;

(4)从docker0所在的子网中选一个可用的IP地址赋予veth pair在容器的一端。

ycy@ubuntu18:~$ docker run -d --name s1 nginx
f5e8a999d00b06d9d95ecf732c81fbf1ff6b29b5707ed0868304d7c40567cd80

ycy@ubuntu18:~$ docker inspect -f "{{ .NetworkSettings.IPAddress }}" s1
172.17.0.2

ycy@ubuntu18:~$ brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.02422bc4b451	no		veth392e4b4

1.2 host模式

相当于Vmware中的桥接模式。新建容器与宿主机共享网络命名空间,该容器不会连接到docker0中,直接使用网络的网络资源进行通信。

ycy@ubuntu18:~$ docker run -it --name v1 --network host nginx /bin/bash
root@ubuntu18:/# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:2bff:fec4:b451  prefixlen 64  scopeid 0x20<link>
        ether 02:42:2b:c4:b4:51  txqueuelen 0  (Ethernet)
        RX packets 25018  bytes 1093724 (1.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 30033  bytes 185103642 (176.5 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.146.100  netmask 255.255.255.0  broadcast 192.168.146.255
        inet6 fe80::badd:42b1:f38b:bf0f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:9e:08:65  txqueuelen 1000  (Ethernet)
        RX packets 231221  bytes 282634477 (269.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 72539  bytes 6474630 (6.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 6118  bytes 534681 (522.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6118  bytes 534681 (522.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.3 none模式

新建容器有独立的网络namespace,但是不会配置任何网络参数,也不会接入docker0中,用户可对其进行任意的手动配置。

ycy@ubuntu18:~$ docker run -it --name net-none --network none mynginx /bin/bash
root@65fed235fdcb:/# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.4 container模式

新建容器与一个已有的容器共享network namespace,该容器不会连接到docker0中,直接使用已有容器的网络资源进行通信。

joined容器是一种较为特别的网络模式

在容器创建时使用--network=container:name(name是运行的容器名)

处在这个模式下的Docker容器会共享一个网络栈,这样两个容器可以使用localhost高效快速通信。

ycy@ubuntu18:~$ docker run -it --name s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig     
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 21  bytes 2682 (2.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

root@da6f3ecc0391:/# ycy@ubuntu18:~$ 
ycy@ubuntu18:~$ docker run -it --name s2 --network container:s1 mynginx /bin/bash
root@da6f3ecc0391:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 25  bytes 3036 (2.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

1.5 用户自定义网络模式

Docker提供了三种自定义网络驱动:bridge、overlay、macvlan。

bridge驱动类似于默认的bridge网络模式,但增加了一些新的功能(带DNS解析功能),overllay和macvlan适用于创建跨主机网络。

创建桥接网络

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
a765c3af4c5220534638e542d8dfa10e45e0e89c6d6f83820d0232339b35e3c7

创建bridge网络后,可以看到新增了一个网桥(172.20.0.1)。

ycy@ubuntu18:~$ ip a | grep br-
19: br-a765c3af4c52: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 172.20.0.1/24 brd 172.20.0.255 scope global br-a765c3af4c52

2. Docker网络通信

 

2.1 同一宿主机不同网桥间的容器间的通信

创建两个自定义网络

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 br0
f8eb445161aa2291a1f89ee7879c2825e7c9a556b1f400f78181b62f8f9ff570

ycy@ubuntu18:~$ docker network create -d bridge --subnet 172.21.0.0/24 --gateway 172.21.0.1 br1
65c9dd48d5b57d70c845fd4ce1a287cd7d4c864a6b641560efb71049ffbf4a05

创建两个测试容器,分别加入创建的网络

ycy@ubuntu18:~$ docker run -it -d --name s0 --network br0 --ip 172.20.0.100 nginx /bin/bash
e28178cb59210b488efdf00519d135609664957fd2ee32cbd28a9119ea4f566b

ycy@ubuntu18:~$ docker run -it -d --name s1 --network br1 --ip 172.21.0.100 nginx /bin/bash
1afbf57debaa8a7150243cabcebaf9628d10c328cec1c8992379f01713f80d91

将当前容器加入到需要与之通信的网络

ycy@ubuntu18:~$ docker network connect br1 s0
ycy@ubuntu18:~$ docker container attach s0

测试网络连接

root@e28178cb5921:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.20.0.100  netmask 255.255.255.0  broadcast 172.20.0.255
        ether 02:42:ac:14:00:64  txqueuelen 0  (Ethernet)
        RX packets 26  bytes 3106 (3.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.21.0.2  netmask 255.255.255.0  broadcast 172.21.0.255
        ether 02:42:ac:15:00:02  txqueuelen 0  (Ethernet)
        RX packets 19  bytes 2462 (2.4 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


 

2.2 跨主机容器间的通信

2.2.1 macvlan

  • macvlan网络容器接口直接与主机网卡连接,无需NAT或端口映射。
  • macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络。
  • macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。
  • 可以在三层上通过网关将macvlan网络联通起来。
  • docker本身不做任何限制,像传统vlan网络那样管理即可。

网卡开启混杂模式

[root@CentOS7 ~]# ip link set ens37 promisc on    

创建macvlan网络
使用-d macvlan创建macvlan网络,使用-o parent指定流量在docker主机上实际通过的物理接口  

[root@CentOS7 ~]# docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens37 macvlan1
8a36aca364caeff25642c843fc0d3064bd74a60985545954b59e0b8bc3218d3f

开启一个桥接macvlan的容器

[root@CentOS7 ~]# docker run -it --name s0 --network macvlan1 --ip 172.20.0.100 docker.io/centos
[root@e5519dccc6f2 /]#

另一个虚拟机也做类似配置

ycy@ubuntu18:~$ sudo ip link set ens38 promisc on

ycy@ubuntu18:~$ docker network create -d macvlan --subnet 172.20.0.0/24 --gateway 172.20.0.1 -o parent=ens38 macvlan1
9042e03b3242184498fc6ca2afae7953f776ec299ba8d05f21b1bbf240b32e71

ycy@ubuntu18:~$ docker run -it --name s1 --network macvlan1 --ip 172.20.0.200 nginx
root@8f8c30548017:/#

测试网络连通性

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值