1.单主机网络
1.1 网络类型
- none网络
none 网络:是指挂在这个网络下的容器除了lo(内部环回网络)之外, 没有其他任何网卡;容器创建时,可以通过 --network=none 指定使用 none 网络;
一般应用于对安全性要求高并且不需要联网的封闭环境下的场景,比如某个容器的唯 用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
[root@master ~]# docker run -it --network=none busybox
...
Pull complete
/ # ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
...
/ #
- host网络
连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样,最大的优势在于网络性能好,但是缺乏灵活性;在可以通过 --network=host 指定使用 host 网络。
- bridge网络
Docker 安装时会创建一个命名为 docker0的 Linux bridge ,默认的subnet网段是172.17.0.0/16,docker0就是网关所在;如果不指定–network, 新创建的容器默认都会挂到 docker0上;
每运行一个容器,就会在docker0网桥上自动创建一个veth接口,和新建容器的虚拟网卡共同构成一个veth-pair(成对出现的特殊网卡设备),这样就将容器桥接到了docker0上。
注:在桥接模式下, Docker 容器 Internet 的通信,以及不同容器之间的通信,都是通过 iptables 规则控制的;可以通过使用 iptables -vnL -t nat 命令来查看 iptables nat 表内容。
注:docker0只为运行中的容器分配veth接口,如果容器停止运行接口就会被回收;如果容器重新运行,docker0会分配新的接口给该容器
#在没有运行容器的情况下,docker0没有生成新的接口
[root@master ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242b6d3f44e no
virbr0 8000.52540036ad48 yes virbr0-nic
#当运行两个容器之后,docker0会产生两个接口
[root@master ~]# docker run -d httpd:2.4
[root@master ~]# docker run -d httpd
[root@master ~]# brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242b6d3f44e no veth256e773
veth3263584
virbr0 8000.52540036ad48 yes virbr0-nic
- user-defined网络
Docker 提供三种 user-defined 网络驱动: bridge、overlay和macvlan;其中overlay和macvlan类型是跨主机网络(在跨主机网络中详解)。
可以使用docker network命令来创建自定义网络,同时可以指定驱动类型、子网和网关,默认使用的子网网段是172.18.0.0/16;如果容器要使用这个网络,就需要在启动时通过 --network 指定,默认情况下是由网桥自动从subnet中分配一个地址,也可以指定一个静态IP(但是地址必须在子网的网段内)
注:①、只有使用 --subnet 创建的网络才能指定静态 IP;
②、同一网络中的容器、网关之间都是可以通信的;默认情况下docker0和net1网络是不通的,可以通过docker connect命令连接到net1下,相当于给docker0下的容器添加一块网卡,网卡连接到net1的子网上。
[root@master ~]# docker network create --driver bridge \
--subnet 10.1.1.0/24 --gateway 10.1.1.1 net1
...
[root@master ~]# docker network inspect net1
...
"Driver": "bridge", #网络驱动类型是bridge
...
"Subnet": "10.1.1.0/24", "Gateway": "10.1.1.1"
[root@master ~]# docker run -it --network=net1 busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:01:01:02
inet addr:10.1.1.2 Bcast:10.1.1.255 Mask:255.255.255.0
...
[root@master ~]# docker run -it --network=net1 --ip=10.1.1.10 busybox
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:0A:01:01:0A
inet addr:10.1.1.10 Bcast:10.1.1.255 Mask:255.255.255.0 ...
1.2 容器间通信
容器之间可通过 IP、Docker DNS Server和 Joined 容器三种方式实现通信;这里所说的容器间通信有个前提:需要通信的容器必须处于同一个network,不同network之间的容器是不互通的。
- IP
两个容器要能通信,必须要有属于同一个网络的网卡(情况同docker0和net1中容器互通)。
- Docker DNS Server
docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名进行通信,解决了IP地址不够灵活的的不足;注意这里只是修改了容器名,容器里的hostname并没有修改,还是容器ID;由于容器名是唯一的,所以DNS server不能用于容器的负载均衡。
注:只能在自定义bridge网络中使用DNS server,在docker0网桥中不能使用。
- joined容器
joined 容器可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,使 joined 容器之间可以通过 127.0.0.1 (本地环回地址)直接通信;也就是指定某个容器为 joined容器,其他容器共享这个容器的网卡;joined 容器非常适合以下场景:
①、不同容器中的程序需要通过 loopback进行高效快速地通信,比如Web Server和AppServer;
②、需要监控某个容器的网络流量,比如运行在独立容器中的网络监控程序要监控Web Server容器的流量,就可以将Web Server容器设置为joined容器,然后将监控容器连接到 joined容器上。
[root@master ~]# docker run -d --name webserver httpd:2.4
fe56671d8b12855b747726fccd068c6e246f1be854babddc0b7a3129401f70da
#指定webserver这个容器的网络作为busybox的网络
[root@master ~]# docker run -d -it --network=container:webserver busybox
5