Eli's Blog

1. 基于 Volume 的互联

  • Graph的架构图

docker-graph

  • graphdriver架构图

graphdriver

  • Aufs: Docker最早支持的driver,但它只是Linux内核的一个补丁集。
  • Device Mapper: Linux2.6 内核提供的一种从逻辑设备到物理设备的映射框架机制,时LVM2的核心,支持块级别的copy on write特性。支持block到block复制
  • VFS: 虚拟文件系统最大的缺陷是不支持copy on write特性,每层都是一个单独的目录,如果新增一个child层,则需要将父级层镜像文件一并复制到新目录)
  • Btrfs: 速度快,采用btrfs的文件系统的快照能力来实现layer分层功能。缺点是还不够成熟。
  • Overlay: 当前最新的文件驱动

1.1 不指定volume挂载目录,默认放在容器_data目录下

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
docker run --rm -it -v /data ubuntu /bin/bash

root@83139b884b25:/# df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 28289540 3451104 24838436 13% /
tmpfs 65536 0 65536 0% /dev
tmpfs 499104 0 499104 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/mapper/centos-root 28289540 3451104 24838436 13% /data
tmpfs 499104 0 499104 0% /proc/asound
tmpfs 499104 0 499104 0% /proc/acpi
tmpfs 499104 0 499104 0% /proc/scsi
tmpfs 499104 0 499104 0% /sys/firmware

docker inspect 83139b884b25
"Mounts": [
{
"Type": "volume",
"Name": "3fd2650cc22d735d6674c721cedd34ace7be5cfd3f35852abc98cf4ee8dbd50b",
"Source": "/var/lib/docker/volumes/3fd2650cc22d735d6674c721cedd34ace7be5cfd3f35852abc98cf4ee8dbd50b/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

# 共享 --volumes-from
docker run --rm -it --privileged=true --volumes-from=83139b884b25 busybox /bin/sh

/ # df
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 28289540 3451180 24838360 12% /
tmpfs 65536 0 65536 0% /dev
tmpfs 499104 0 499104 0% /sys/fs/cgroup
shm 65536 0 65536 0% /dev/shm
/dev/mapper/centos-root
28289540 3451204 24838336 12% /data
/dev/mapper/centos-root
28289540 3451204 24838336 12% /etc/resolv.conf
/dev/mapper/centos-root
28289540 3451204 24838336 12% /etc/hostname
/dev/mapper/centos-root
28289540 3451204 24838336 12% /etc/hosts

1.2 指定挂载目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mkdir -p /docker_data  # 宿主机上创建目录 (SRC:DEST)

docker run --rm -it -v /docker_data:/data ubuntu /bin/bash

docker inspect f15e04881ea5
"Mounts": [
{
"Type": "bind",
"Source": "/docker_data",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

1.3 基于数据容器的单主机互联

数据容器:只提供数据的容器,业务容器连接到该数据容器,实现数据共享

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run --rm --volumes-from=f15e04881ea5 -it ubuntu /bin/bash

docker inspect 19f9a3ffc9ea
"Mounts": [
{
"Type": "bind",
"Source": "/docker_data",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],

2. 基于 Link 的互联

2.1 默认允许 Container 互通

1
2
3
4
5
6
7
8
9
10
11
12
13
docker run --rm --name=mysql-srv -P -e MYSQL_ROOT_PASSWORD=123456 -it mysql:5.7 /bin/sh

root@64faae051d97:/# 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.5 64faae051d97

docker run --rm -it ubuntu curl 172.17.0.5:3306
curl: (1) Received HTTP/0.9 when not allowed

2.2 关闭 Container 互通

关闭互通: /usr/bin/dockerd -H unix:///var/run/docker.sock --icc=false

--link name:alias: 关闭互通的container,连接指定的 container。它会在/etc/hosts中生成对应的ip映射

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
docker run --rm --name=java1 -it java /bin/bash

root@090a30f3504e:/# ip addr
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
88: eth0@if89: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

# link 网络
docker run --rm --link=java1:java2 -it java /bin/bash
root@51a3a3e91351:/# ip addr
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
92: eth0@if93: <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@51a3a3e91351:/# 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 java2 090a30f3504e java1
172.17.0.3 51a3a3e91351

3. 基于网络的互联

3.1 端口映射

1
2
3
4
docker run --rm -p 8306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

ps -ef | grep docker-proxy
root 71225 55463 0 14:26 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8306 -container-ip 172.17.0.3 -container-port 3306

3.2 直接使用宿主机网络

1
docker run --rm --net=host -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

3.3 容器共用一个IP网络

1
2
3
4
docker run --rm --name=mysqlserver -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7

# 与 mysql 共用网络
docker run --rm --name javasrv --net=container:mysqlserver -it java /bin/bash

3.4 网络知识补充

  • docker0: nat 网桥
  • 网桥:把物理网卡当交换机,能接收mac不是自己的报文,然后转发到正确的mac上
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
$ yum install -y bridge-utils

$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242d81a56c3 no veth6445d40

$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:ff:1c:29 brd ff:ff:ff:ff:ff:ff
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:42:d8:1a:56:c3 brd ff:ff:ff:ff:ff:ff
99: veth6445d40@if98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
link/ether 1e:cd:1b:e4:1d:fc brd ff:ff:ff:ff:ff:ff link-netnsid 0

$ docker network ls
NETWORK ID NAME DRIVER SCOPE
5edf46553116 bridge bridge local
3f0e974cff7d host host local
016c2058322a none null local

$ docker network inspect bridge

# closed container,未分配IP地址
$ docker run --rm --network none -it busybox /bin/sh

# default
$ docker run --rm --network default -it busybox /bin/sh

# joined, 共享IP
$ docker run --rm --network container:c1 -it busybox /bin/sh

# host, 使用宿主机IP
$ docker run --rm --network host -it busybox /bin/sh

docker 网络模型:

docker-network-module