Loading

4-Docker网络模型

Docker网络模型

Docker默认是使用网桥进行交互的,Docker完成以上网络配置的过程大致是这样的:

  1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。

  2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看。

# 查看系统网桥信息
[root@localhost ~]# brctl show
bridge name     bridge id               STP enabled     interfaces
docker0         8000.0242b172ec42       no
  1. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。

1、Docker四种网络模型

​ Docker使用Linux的NameSpaces技术来进行资源隔离,如PID NameSpaces隔离进程,Mount NameSpaces隔离文件系统,同时Network NameSpaces提供了一份独立的网络环境,包括网卡、路由、iptables规则都与其他Network NameSpace隔离。同时提供了四种网络模式。

  • none模式,使用--net=none指定。

  • bridge模式,使用--net=bridge指定,默认即为bridge设置。

  • container模式,使用--net=container:NAME_or_ID指定

  • host模式,使用--net=host指定

1.1、none模式

​ Docker容器使用none模式启动时容器拥有自己的Network Space,不为Docker容器进行任何网络设置,容器没有网卡、IP、路由信息。

1.2、bridge模式

​ docker网络隔离基于Network Space,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。此模式是通过网桥进行交互,会去生成一个子网络,子网络的每个子网络中的ip都是一个单独的网络,一个自己的IP段。

​ 当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.101.105/24。

clip_image002

1.3、container模式

​ 这个模式在创建容器时指定和一个已经存在的容器共享一个Network NameSpaces,但是两个容器还有自己独立的文件系统、主机名等。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

1.4、host模式

​ 和container模式不同,host模式共享的是宿主机的Network NameSpaces,此模式创建的容器没有自己独立的网络命名空间,并且共享物理机的所有端口与IP。

2、通过ip netns创建虚拟网卡对

前面了解过Docker的网络实现是在主机上创建一对虚拟网卡veth pair设备,可以通过ip netns 命令用来管理 network namespace中的虚拟网卡对。

# 查看网络名称空间列表
[root@localhost ~]# ip netns help
Usage: ip netns list
       ip netns add NAME
       ip netns set NAME NETNSID
       ip [-all] netns delete [NAME]
       ip netns identify [PID]
       ip netns pids NAME
       ip [-all] netns exec [NAME] cmd ...
       ip netns monitor
       ip netns list-id
       
# 添加两个网络名称空间
[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns add ns2
[root@localhost ~]# 
[root@localhost ~]# ip netns list
ns2
ns1

# 创建网卡对
[root@localhost ~]# ip link add name veth1.1 type veth peer name veth1.2
# name:指定网卡名称
# type:指定网卡类型
# peer name:指定另外一半网卡名称

[root@localhost ~]# ip link show  
# 查看网卡对,下面可以看到veth1.1和veth1.2这对网卡
......
4: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e6:bb:5f:08:40:73 brd ff:ff:ff:ff:ff:ff
5: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 62:63:07:98:2c:cf brd ff:ff:ff:ff:ff:ff
    
# 将veth1.1留在宿主机上,将veth1.2移到前面创建的名称空间ns1上,模拟在不同设备上成对出现
[root@localhost ~]# ip link set dev veth1.2 netns ns1  # 将veth1.2绑定到ns1名称空间中
[root@localhost ~]# ip link show
......
# 可以看到宿主机上只有veth1.1网卡了,另外一半就在ns名称空间了
5: veth1.1@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 62:63:07:98:2c:cf brd ff:ff:ff:ff:ff:ff link-netnsid 0

# 查看ns1名称空间的网卡
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
4: veth1.2@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e6:bb:5f:08:40:73 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    
# 给宿主机上的这一半网卡veth1.1配置IP并启动
[root@localhost ~]# ip addr add 10.1.0.1/24 dev veth1.1
[root@localhost ~]# ip link set veth1.1 up
# 给名称空间上的另一半网卡veth1.2配置IP并启动
[root@localhost ~]# ip netns exec ns1 ip addr add 10.1.0.2/24 dev veth1.2
[root@localhost ~]# ip netns exec ns1 ip link set veth1.2 up

# 在名称空间间ping在宿主机上这一半的网卡验证
[root@localhost ~]# ip netns exec ns1 ping 10.1.0.1
PING 10.1.0.1 (10.1.0.1) 56(84) bytes of data.
64 bytes from 10.1.0.1: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 10.1.0.1: icmp_seq=2 ttl=64 time=0.028 ms
64 bytes from 10.1.0.1: icmp_seq=3 ttl=64 time=0.026 ms

3、创建四种网络类型容器

3.1、创建none类型网络的容器

[root@localhost ~]# docker run --name t1 -it --network none --rm busybox:latest
/ # 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)

3.2、创建bridge类型网络的容器

[root@localhost ~]# docker run --name t1 -it --network bridge --rm busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

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)
# 创建时配置主机名
[root@localhost ~]# docker run --name t1 -it --network bridge -h larry.test.com --rm busybox:latest
/ # hostname
larry.test.com

# 创建时配置dns服务器地址
[root@localhost ~]# docker run --name t1 -it --network bridge --dns 114.114.114.114 --rm busybox:latest
/ # cat /etc/resolv.conf 
search localdomain
nameserver 114.114.114.114

创建container类型网络的容器

# 1、创建第一个bridge类型容器
[root@localhost ~]# docker run --name busybox1 -it --rm busybox:latest                  / # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)
# 2、创建第二个container类型的容器
[root@localhost ~]# docker run --name busybox2 --network container:busybox1 -it --rm busybox:latest
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

上面的例子可以看到两个容器的ip地址是一样的,说明使用了相同的网路名称空间,单其他名称空间还是独立的,比如主机名、硬盘等。

3.4、创建host类型网络的容器

[root@localhost ~]# docker run --name t1 --network host -it --rm busybox 
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:7B:F3:10:88  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:7bff:fef3:1088/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:656 (656.0 B)

enp0s3    Link encap:Ethernet  HWaddr 08:00:27:46:31:55  
          inet addr:10.0.16.90  Bcast:10.0.17.255  Mask:255.255.254.0
          inet6 addr: fe80::a00:27ff:fe46:3155/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8651 errors:0 dropped:2 overruns:0 frame:0
          TX packets:1621 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:890929 (870.0 KiB)  TX bytes:302211 (295.1 KiB)

上面可以看到生成的ip和宿主机的ip相同。

4、自定义Docker默认网络属性信息

docker默认使用172.17.x.x作为容器的虚拟ip地址,这个地址可以修改。

自定义docker0桥的网络属性信息:/etc/docker/daemon.json文件

 {             
 	"bip": "192.168.1.5/24",             
 	"fixed-cidr": "10.20.0.0/16",             
 	"fixed-cidr-v6": "2001:db8::/64",             
 	"mtu": 1500,             
 	"default-gateway": "10.20.1.1",             
 	"default-gateway-v6": "2001:db8:abcd::89",             
 	"dns": ["10.20.1.2","10.20.1.3"]         
 } 

核心选项为bip,即bridge ip之意,用于指定docker0桥自身的IP地址;其它选项可通过此地址计算得出。

自定义Docker监听端口

dockerd守护进程的C/S,其默认仅监听Unix SOcket格式的地址,/var/run/docker.sock;如果使用TCP套接字。

修改/etc/docker/daemon.json,添加:

"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]           

也可向dockerd直接传递“-H|--host”选项;

可以通过-H远程连接其他docker服务

# docker -H 10.0.16.91:2375 image ls

6、自定义网桥

docker可以自定义网桥

[root@localhost ~]# docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr07e5ee2128e3f20789db14245928bfc76decfec01cdcb2634868217cef6e71331[root@localhost ~]# docker network lsNETWORK ID          NAME                DRIVER              SCOPEb38755c57d8c        bridge              bridge              local136e91e4c434        host                host                local7e5ee2128e3f        mybr0               bridge              localb9e4dcb6ea19        none                null                local[root@localhost ~]# ip a......3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default     link/ether 02:42:7b:f3:10:88 brd ff:ff:ff:ff:ff:ff    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0       valid_lft forever preferred_lft forever    inet6 fe80::42:7bff:fef3:1088/64 scope link        valid_lft forever preferred_lft forever14: br-7e5ee2128e3f: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default     link/ether 02:42:23:d1:64:89 brd ff:ff:ff:ff:ff:ff    inet 172.26.0.1/16 brd 172.26.255.255 scope global br-7e5ee2128e3f       valid_lft forever preferred_lft forever
posted @ 2021-07-13 17:19  勤俭持家亮公子  阅读(81)  评论(0)    收藏  举报