赞
踩
本博客的内容会为大家讲解Docker的网络管理。
docker网络模式
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分。
Docker 在启动时会开启一个虚拟网桥设备 docker0,默认地址为 172.17.1.1/16, 容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址。(我的虚拟机的docker0)
[root@server1 ~]# ip addr show docker0 #要确保自己的docker服务已经开启
同时每一个容器都会有一个独有的Pid:
[root@server1 ~]# docker inspect vm1 |grep Pid
"Pid": 1675,
"PidMode": "",
"PidsLimit": 0,
每一个独有的Pid都会在/proc目录下有一个相应的以Pid为名的目录,这个目录里面的ns目录有着关于这个Pid容器网络的文件:
解释:veth设备是成双成对出现的,一端是容器内部命名为eth0,一端是加入到网桥并命名的veth*(通常命名为veth*),它们组成了一个数据传输通道,一端进一端出,veth设备连接了两个网络设备并实现了数据通信。
1、selinux和firewalld状态均为disabled
2、实验所用到的信息
主机 | ip地址 |
---|---|
server1(已安装docker) | 172.25.1.1 |
server2(已安装docker) | 172.25.1.2 |
Docker在创建容器时有三种网络模式,bridge为默认不需要用–net去指定,其他三种模式需要在创建容器时使用–net去指定。
bridge 模式,使用–net=bridge指定,默认设置。
none 模式,使用–net=none指定。
host 模式,使用–net=host指定。
container 模式,使用–net=container:容器名称或ID指定
Bridge 桥接模式的实现步骤主要如下:
Bridge桥接模式的缺陷:
host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。
Host 网络模式的缺陷:
当然,有这样的方便,肯定会损失部分其他的特性。
[root@server1 ~]# docker run -it --name vm2 --net host ubuntu
root@server1:/# ip a
它将使用宿主机的IP地址,ip addr和宿主机查看到同样的结果:
Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。
Container网络模式的缺陷:
它并没有改善容器与宿主机以外世界通信的情况(和桥接模式一样,不能连接宿主机以外的其他设备)。
示例: 创建一个使用vm1容器网络的容器vm3
[root@server1 1675]# docker run -it --name vm3 --net container:vm1 ubuntu
由于vm3使用vm1的网络,,所以vm3使用 ip addr查看网络结果和vm1相同
网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docker Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制【开发。这也恰巧体现了 Docker 设计理念的开放。
示例:新建一个none网络模式的容器vm4
[root@server1 1675]# docker run -it --name vm4 --net none ubuntu
root@4aec50ccf52f:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever root@4aec50ccf52f:/# ping vm1 PING db1 (172.17.0.2) 56(84) bytes of data. 64 bytes from db1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.070 ms 64 bytes from db1 (172.17.0.2): icmp_seq=2 ttl=64 time=0.040 ms ^C --- db1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.040/0.055/0.070/0.015 ms root@4aec50ccf52f:/# cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 db1 329c4fb8eefe vm1 172.17.0.3 4aec50ccf52f
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。
[root@server1 1675]# docker network create my_net1
docker network inspect my_net1
[root@server1 ~]# docker run -it --name vm1 --network=my_net1 ubuntu #创建vm1 root@059d90f560b7:/# ping vm1 #可以发现有关于vm1的解析 PING vm1 (172.18.0.2) 56(84) bytes of data. 64 bytes from 059d90f560b7 (172.18.0.2): icmp_seq=1 ttl=64 time=0.016 ms 64 bytes from 059d90f560b7 (172.18.0.2): icmp_seq=2 ttl=64 time=0.028 ms 64 bytes from 059d90f560b7 (172.18.0.2): icmp_seq=3 ttl=64 time=0.026 ms ^C --- vm1 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.016/0.023/0.028/0.006 ms root@059d90f560b7:/# [root@server1 ~]# [root@server1 ~]# docker run -it --name vm2 --network=my_net1 ubuntu #创建vm2 root@0776ee82696a:/# ping vm1 #可以发现可以和vm1通讯 PING vm1 (172.18.0.2) 56(84) bytes of data. 64 bytes from vm1.my_net1 (172.18.0.2): icmp_seq=1 ttl=64 time=0.051 ms 64 bytes from vm1.my_net1 (172.18.0.2): icmp_seq=2 ttl=64 time=0.045 ms 64 bytes from vm1.my_net1 (172.18.0.2): icmp_seq=3 ttl=64 time=0.044 ms 64 bytes from vm1.my_net1 (172.18.0.2): icmp_seq=4 ttl=64 time=0.042 ms ^C --- vm1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.042/0.045/0.051/0.007 ms
在自定义网桥上(自定义的ip地址和网关地址),同一网桥上的容器是可以通信的。
值的注意的是:
[root@server1 ~]# docker network create --subnet=172.21.0.0/24 --gateway=172.21.0.1 my_net2
[root@server1 ~]# docker run -it --name vm3 --network=my_net2 --ip=172.21.0.6 ubuntu
root@0d6f663916c0:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:15:00:06 brd ff:ff:ff:ff:ff:ff
inet 172.21.0.6/24 brd 172.21.0.255 scope global eth0
valid_lft forever preferred_lft forever
默认使用不同网桥的容器是不可以通讯的。
我们现在的vm1使用的是my_net1网桥,vm3使用的是my_net2网桥,默认是不能通讯的。
使用 docker network connect命令为vm1添加一块my_net2 的网卡
[root@server1 ~]# docker network connect my_net2 vm1
[root@server1 ~]# docker attach vm1
可以成功通讯!!!
值的注意的是:
docker 1.10开始,内嵌了一个DNS server。dns解析功能必须在自定义网络中使用。
[root@server1 ~]# iptables -t nat -nL
[root@server1 ~]# docker run -d --name nginx -p 80:80 nginx 109cffe95ab39aa3b34b9b74ed92b5aa81499bcf9d311586356f6d54eeedc3c8 [root@server1 ~]# docker port nginx 80/tcp -> 0.0.0.0:80 [root@server1 ~]# netstat -antlp | grep 80 tcp6 0 0 :::80 :::* LISTEN 4269/docker-proxy [root@server1 ~]# iptables -t nat -nL Chain PREROUTING (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- 172.21.0.0/24 0.0.0.0/0 MASQUERADE all -- 172.18.0.0/16 0.0.0.0/0 MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0 MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80 Chain DOCKER (2 references) target prot opt source destination RETURN all -- 0.0.0.0/0 0.0.0.0/0 RETURN all -- 0.0.0.0/0 0.0.0.0/0 RETURN all -- 0.0.0.0/0 0.0.0.0/0 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
1、docker原生的macvlan和overlay;
2、第三方的flannel,weave和calico。
libnetwork docker容器网络库
CNM(Container Network Model)这个模型对容器网络进行了抽象
Sandbox:容器网络栈。包括容器接口,dns,路由表。(namespace)
Endpoint:作用是将sanbox接入network(veth pair)
Network:包含一组endpoint,同一network的endpoint可以通信。
Linux kernel提供的一种网卡虚拟化技术。
无需Linux bridge,直接使用 物理接口,性能机号。
server1:
添加网卡配置文件:
[root@server1 network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@server1 network-scripts]# vim ifcfg-eth1
[root@server1 network-scripts]# cat ifcfg-eth1
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yes
[root@server1 network-scripts]# ifup eth1 #启动网卡
server2:
添加网卡配置文件:
[root@server2 ~]# cd /etc/sysconfig/network-scripts/
[root@server2 network-scripts]# vim ifcfg-eth1
[root@server2 network-scripts]# cat ifcfg-eth1
BOOTPROTO=none
DEVICE=eth1
ONBOOT=yes
[root@server2 network-scripts]# ifup eth1
macvlan本身是linxu kernel的模块,本质上是一种网卡虚拟化技术。其功能是允许在同一个物理网卡上虚拟出多个网卡,通过不同的MAC地址在数据链路层进行网络数据的转发,一块网卡上配置多个 MAC 地址(即多个 interface),每个interface可以配置自己的IP,Docker的macvlan网络实际上就是使用了Linux提供的macvlan驱 动。
因为多个MAC地址的网络数据包都是从同一块网卡上传输,所以需要打开网卡的混杂模式ip link set eth0 promisc on。
[root@server1 network-scripts]# ip link set eth1 promisc on #在server1上打开网卡eth0的混杂模式
[root@server2 network-scripts]# ip link set eth1 promisc on
看到PROMISC,表示成功
注意 : 如果不开启混杂模式,会导致macvlan网络无法访问外界,具体在不使用vlan时,表现为无法ping通路由,无法ping通同一网络内其他主机。
创建macvlan网络不同于桥接模式,需要指定网段和网关(因为要保证跨主机上网段和网关是相同的),并且都得是真实存在的,例如docker network create -d macvlan --subnet=172.183.1.0/24 --gateway=172.183.1.1 -o parent=eth0 mac_net1。
server1:
[root@server1 ~]# docker network create -d macvlan --subnet=172.22.0.0/24 --gateway=172.22.0.1 -o parent=eth1 macvlan1
server2:
server1: [root@server1 ~]# docker run -it --name vm1 --network=macvlan1 --ip=172.22.0.6 ubuntu root@9ae2652ce7c9:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 25: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:16:00:06 brd ff:ff:ff:ff:ff:ff inet 172.22.0.6/24 brd 172.22.0.255 scope global eth0 valid_lft forever preferred_lft forever server2: [root@server2 ~]# docker run -it --name vm2 --network=macvlan1 --ip=172.22.0.10 ubuntu root@e9a5c1094cf1:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 5: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:16:00:0a brd ff:ff:ff:ff:ff:ff inet 172.22.0.10/24 brd 172.22.0.255 scope global eth0 valid_lft forever preferred_lft forever
访问测试:
[root@server1 ~]# docker run -it --name vm1 --network=macvlan1 --ip=172.22.0.6 ubuntu root@9ae2652ce7c9:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 25: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:16:00:06 brd ff:ff:ff:ff:ff:ff inet 172.22.0.6/24 brd 172.22.0.255 scope global eth0 valid_lft forever preferred_lft forever root@9ae2652ce7c9:/# ping 172.22.0.10 PING 172.22.0.10 (172.22.0.10) 56(84) bytes of data. 64 bytes from 172.22.0.10: icmp_seq=1 ttl=64 time=0.570 ms 64 bytes from 172.22.0.10: icmp_seq=2 ttl=64 time=0.332 ms 64 bytes from 172.22.0.10: icmp_seq=3 ttl=64 time=0.261 ms 64 bytes from 172.22.0.10: icmp_seq=4 ttl=64 time=0.316 ms 64 bytes from 172.22.0.10: icmp_seq=5 ttl=64 time=0.310 ms ^C --- 172.22.0.10 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4000ms rtt min/avg/max/mdev = 0.261/0.357/0.570/0.111 ms
macvlan会独占主机的网卡,也就是说一个网卡只能创建一个macvlan 网络,否则会报错,如果要创建多个macvlan网络,则需要添加多块网卡。
macvlan会独占主机网卡,但可以使用vlan子接口实现多
macvlan网络
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,
vlan id取值为1~4094
我们只需要在创建容器时使用vlan子接口就可以i解决:
[root@server1 ~]# docker network create -d macvlan --subnet=172.23.0.0/24 --gateway=172.23.0.1 -o parent=eth1.1 macvlan2 #创建vlan子接口 1ea70c44b95688c4d8660035d22fb8ab6fd9c2a483cf73f554c4302972da5edd [root@server1 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 68dd8769d20f bridge bridge local b904eb30beb0 host host local 53c5b15b2e60 macvlan1 macvlan local 1ea70c44b956 macvlan2 macvlan local 078936c1a2fd none null local [root@server1 ~]# docker run -it --name vm3 --network=macvlan2 --ip=172.23.0.8 ubuntu root@66d5e0b1b706:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 27: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:17:00:08 brd ff:ff:ff:ff:ff:ff inet 172.23.0.8/24 brd 172.23.0.255 scope global eth0 valid_lft forever preferred_lft forever
[root@server1 ~]# docker network connect macvlan1 vm3
测试
[root@server1 ~]# docker network connect macvlan1 vm3 [root@server1 ~]# docker attach vm3 root@66d5e0b1b706:/# root@66d5e0b1b706:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 27: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:17:00:08 brd ff:ff:ff:ff:ff:ff inet 172.23.0.8/24 brd 172.23.0.255 scope global eth0 valid_lft forever preferred_lft forever 28: eth1@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default link/ether 02:42:ac:16:00:02 brd ff:ff:ff:ff:ff:ff inet 172.22.0.2/24 brd 172.22.0.255 scope global eth1 valid_lft forever preferred_lft forever root@66d5e0b1b706:/# ping 172.22.0.6 PING 172.22.0.6 (172.22.0.6) 56(84) bytes of data. 64 bytes from 172.22.0.6: icmp_seq=1 ttl=64 time=0.060 ms 64 bytes from 172.22.0.6: icmp_seq=2 ttl=64 time=0.034 ms 64 bytes from 172.22.0.6: icmp_seq=3 ttl=64 time=0.033 ms ^C --- 172.22.0.6 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.033/0.042/0.060/0.013 ms
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。