当你安装完docker之后,默认已经有了5种网络模式,可以通过docker info查看
分别是bridge host macvlan null overlay.

bridge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[
{
"Name": "bridge",
"Id": "1c006820eb42b4f57f95c91dcb694df703afebd4fcb666cc58ead63877b57deb",
"Created": "2018-01-10T06:05:53.925311686-05:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
当你未指定网络的时候,默认用的就是bridge网络。例如
docker run --rm radial/busyboxplus:curl
ip a
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:2/64 scope link
valid_lft forever preferred_lft forever
ip r
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 src 172.17.0.2
ping d.cn
PING d.cn (183.131.214.42): 56 data bytes
64 bytes from 183.131.214.42: seq=0 ttl=52 time=13.337 ms

host

主机网络,应该是性能最好的,可以理解为直接使用主机的网络,你只需要进行端口映射,映射到主机上的对应端口即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
[
{
"Name": "host",
"Id": "94902992950ea665822834f82c173e19af65c2b628e447fda3fc88a39b219e1b",
"Created": "2017-11-19T13:35:24.770968568-05:00",
"Scope": "local",
"Driver": "host",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
docker run -it --net host radial/busyboxplus:curl
ip a
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
link/ether 08:00:27:ee:3a:ff brd ff:ff:ff:ff:ff:ff
inet 10.8.1.55/16 brd 10.8.255.255 scope global dynamic enp0s3
valid_lft 85500sec preferred_lft 85500sec
inet6 fe80::2f29:b319:faba:9924/64 scope link
valid_lft forever preferred_lft forever
inet6 fe80::1c21:1175:2cfc:5cad/64 scope link tentative flags 08
valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue
link/ether 02:42:d1:70:39:09 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:d1ff:fe70:3909/64 scope link
valid_lft forever preferred_lft forever
ip r
default via 10.8.0.1 dev enp0s3 metric 100
10.8.0.0/16 dev enp0s3 src 10.8.1.55 metric 100
172.17.0.0/16 dev docker0 src 172.17.0.1
ping d.cn
PING d.cn (183.131.214.42): 56 data bytes
64 bytes from 183.131.214.42: seq=0 ttl=53 time=11.149 ms

none

就是没有网络

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
{
"Name": "none",
"Id": "0e61fd6480d7a3c68d01d57577a1b282464148fc748850d1493b782111f616c2",
"Created": "2017-11-19T13:35:24.755228508-05:00",
"Scope": "local",
"Driver": "null",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]

overlay

为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。
VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 VLAN 相同的以太网二层服务,但是拥有更强的扩展性和灵活性。
Docerk overlay 网络需要一个 key-value 数据库用于保存网络状态信息,包括 Network、Endpoint、IP 等。
Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。

--cluster-store=consul://192.168.56.1:8500 --cluster-advertise=enp0s3:2376

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
systemctl daemon-reload
systemctl restart docker
docker network create -d overlay ov_net1
docker network inspect ov_net1
docker run -itd --name bbox1 --network ov_net1 busybox
docker run -itd --name bbox2 --network ov_net1 busybox
docker exec bbox1 ip r
docker exec bbox2 ip r
docker exec bbox1 ping bbox2
docker rm -f $(docker ps -qa)

macvlan

macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。
macvlan 本质上是一种网卡虚拟化技术,Docker 用 macvlan 实现容器网络就不奇怪了。
macvlan 的最大优点是性能极好,相比其他实现,macvlan 不需要创建 Linux bridge,而是直接通过以太 interface 连接到物理网络。

为保证多个 MAC 地址的网络包都可以从 enp0s9 通过,我们需要打开网卡的混杂模式

1
2
3
4
5
6
7
8
9
10
11
12
ip link set enp0s8 promisc on
docker network create -d macvlan \
--subnet=172.16.86.0/24 \
--gateway=172.16.86.1 \
-o parent=enp0s8 mac_net1
docker network rm mac_net1
docker run --name bbox1 --net=mac_net1 --ip=172.16.86.10 -itd busybox
docker run --name bbox2 --net=mac_net1 --ip=172.16.86.11 -itd busybox

flannel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
IP=10.8.1.50
etcd -listen-client-urls http://${IP}:2379 -advertise-client-urls http://${IP}:2379 2>&1 &
cat > flannel-config.json <<EOF
{
"Network": "10.2.0.0/16",
"SubnetLen": 24,
"Backend": {
"Type": "vxlan"
}
}
EOF
etcdctl --endpoints=http://${IP}:2379 set /docker-test/network/config < flannel-config.json
flanneld -etcd-endpoints=http://${IP}:2379 -iface=enp0s3 -etcd-prefix=/docker-test/network 2>&1 &
mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker
vim /usr/lib/systemd/system/docker.service
EnvironmentFile=-/run/flannel/docker
$DOCKER_NETWORK_OPTIONS
systemctl daemon-reload
systemctl restart docker
docker run -itd --name bbox1 busybox
docker run -itd --name bbox2 busybox

calico

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
IP=
etcd -listen-client-urls http://${IP}:2379 -advertise-client-urls http://${IP}:2379 2>&1 &
etcdctl --endpoints=http://${IP}:2379 cluster-health
mkdir /etc/calico/
cat > /etc/calico/calicoctl.cfg <<EOF
apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
etcdEndpoints: http://${IP}:2379
EOF
calicoctl node run
docker network create --driver calico --ipam-driver calico-ipam cal_net1
docker container run --net cal_net1 --name bbox1 -tid busybox
docker exec bbox1 ip a
docker container run --net cal_net1 --name bbox2 -tid busybox