基于Volume的互联
理解Docker Volume 
/var/lib/docker/graph 存放本地Image里的分层信息
/var/lib/docker/devicemapper/devicemapper/data 存储了Image与Container的二进制数据文件
/var/lib/docker/devicemapper/devicemapper/metadata 存储了相关元数据



Aufs driver是Docker最早支持的driver,但是aufs只是Linux内核的一个补丁集
Device mapper是Linux 2.6内核中提供的一种从逻辑设备到物理设备的映射框架机制,是LVM2的核心,支持块级别的copy on write特性目前,除少数版本如Ubuntu, Docker基本运行在Devicemapper基础上FS虚拟文件系统的最大缺陷是不支持copy on write特性,每层都是一个单独的目录,如果新增一个child层,则需要将父级层镜像文件一并复制到新目录
btrfs 非常快,采用btrfs的文件系统级的快照能力来实现layer分层功能,缺点是仍然在进化中,还不够成熟,特别是大量写操作的压力下
目前,除少数版本如Ubuntu, Docker基本运行在Devicemapper基础上 
为什么需要Volume
[root@node1 ~]# docker run --rm=true -it -v /leader java /bin/bash #容器删除目录不存在
root@476a8dc8ae5d:/# ls
bin boot dev etc home leader lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@476a8dc8ae5d:/# ls /leader/
[root@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
476a8dc8ae5d java "/bin/bash" 4 minutes ago Up 4 minutes mystifying_heisenberg
3d48efbceb60 java "/bin/bash" 7 days ago Up 6 hours myjava3
11f068716ba1 mysql "docker-entrypoint.s…" 8 days ago Up 6 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysqlsrv1
[root@node1 ~]# docker inspect 476a8dc8ae5d
"Mounts": [
{
"Type": "volume",
"Name": "06d3f6ca6b5148fd7e33ed2ce0e32f924c722e9bfdd54488a869ff502246983a",
"Source": "/var/lib/docker/volumes/06d3f6ca6b5148fd7e33ed2ce0e32f924c722e9bfdd54488a869ff502246983a/_data",
"Destination": "/leader",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
[root@node1 ~]# mkdir /var/lib/docker/volumes/06d3f6ca6b5148fd7e33ed2ce0e32f924c722e9bfdd54488a869ff502246983a/_data/mybook
root@476a8dc8ae5d:/# ls leader/
mybook
docker run --rm=true -it -v /storage(本地目录) /leader(容器目录)java /bin/bash
[root@node1 ~]# mkdir /storage [root@node1 ~]# docker run --rm=true -it -v /storage:/leader:ro java /bin/bash #容器删除目录还在 root@9bb567abc803:/# mkdir /leader/mybook3 mkdir: cannot create directory ‘/leader/mybook3’: Read-only file system [root@node1 ~]# docker run --rm=true -it -v /storage:/leader:rw java /bin/bash root@502db16fb115:/# mkdir leader/mybook3
可以多个容器中的Volume指向同一个本机目录,实现基于文件的的共享访问
基于Volume的互联,也可以解决跨主机的共享问题

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

[root@node1 ~]# docker run -it -v /leader java /bin/bash [root@node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2e1132cdd525 java "/bin/bash" 17 seconds ago Up 16 seconds determined_lederberg 3d48efbceb60 java "/bin/bash" 8 days ago Up 7 hours myjava3 11f068716ba1 mysql "docker-entrypoint.s…" 8 days ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysqlsrv1 [root@node1 ~]# docker run --rm=true --privileged=true --volumes-from=2e1132cdd525 -it java /bin/bash root@2302ce2ac287:/# ls /leader/ root@2302ce2ac287:/# ls /leader/ root@2302ce2ac287:/# mkdir /leader/mybook root@2e1132cdd525:/# ls /leader/ mybook
基于link的互联
默认情况下是容器直接是互联的
[root@node1 ~]# docker run --rm=true --name=mysqlserver -e MYSQL_ROOT_PASSWORD=smoke520 mysql
[root@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a35457528ed2 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mysqlserver
3d48efbceb60 java "/bin/bash" 8 days ago Up 7 hours myjava3
11f068716ba1 mysql "docker-entrypoint.s…" 8 days ago Up 7 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysqlsrv1
[root@node1 ~]# docker exec -it a35457528ed2 bash
root@a35457528ed2:/# 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.4 a35457528ed2
[root@node1 ~]# docker inspect a35457528ed2
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "8c60f6322422f9f0b16ebf0bb956fce4c4c567dc489f7079e834b2e7ff02d56c",
"EndpointID": "eecb29d0af7e30f8c2daed9fac1fc00442dd53ee9e00d572a77cc1be8bb7847f",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:04",
"DriverOpts": null
}
}
[root@node1 ~]# docker run --rm=true -it java curl 172.17.0.4:3306 #默认情况下时容器直接是互联的
%N▒▒▒▒▒<u}S)|w1=caching_sha2_password▒Got packets out of order[root@node1 ~]#
link方式
docker默认是允许container互通,通过-icc=false关闭互通。一旦关闭了互通,只能通过-link name:alias命令连接指定container.
-- link redis:db的别名,会在/etc/hosts中生成对应的ip映射
--link=myjaveserver[目标容器(需要连接容器)]:serverM1[给一个主机名(DNS名称)用来代替IP地址进行访问]
[root@node1 ~]# docker run --rm=true --name=myjavaserver -it java /bin/bash
root@50b8886a5de8:/# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
165: eth0@if166: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@node1 ~]# docker run --rm=true --link=myjavaserver:serverM1 -it java /bin/bash
root@08e669748006:/# 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 serverM1 50b8886a5de8 myjavaserver
172.17.0.6 08e669748006
root@08e669748006:/# ping serverM1
PING serverM1 (172.17.0.5): 56 data bytes
64 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.210 ms
^C--- serverM1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.210/0.210/0.210/0.000 ms
root@08e669748006:/# ping myjavaserver
PING serverM1 (172.17.0.5): 56 data bytes
64 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.139 ms
^C--- serverM1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.139/0.139/0.139/0.000 ms
/usr/bin/docker daemon --icc=false --iptables=true #关闭容器互通
[root@node1 ~]# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --icc=false --iptables=true
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl restart docker
[root@node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2512029290fb mysql "docker-entrypoint.s…" 24 hours ago Up 24 hours 3306/tcp, 33060/tcp mysqlserver
[root@node1 ~]# docker inspect 2512029290fb
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "2bd1ee6d1375a84d109f5b8945ebf15d5ddd0c0aad69ef8005a32b5ef74d4b06",
"EndpointID": "c00fe9deded0c2ba4ce3c80841aaadd0381bfdf4e4c7fd55a9b481a3082c4251",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
[root@node1 ~]# docker run --rm=true -it java ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
^C--- 172.17.0.2 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
[root@node1 ~]# docker run --rm=true --link=mysqlserver:myserver -it java /bin/bash
root@fd90f24a4a59:/# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
189: eth0@if190: <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@node1 ~]# iptables-save > /etc/sysconfig/iptables
[root@node1 ~]# vim /etc/sysconfig/iptables
-A DOCKER -s 172.17.0.3/32 -d 172.17.0.2/32 -i docker0 -o docker0 -p tcp -m tcp --dport 3306 -j ACCEPT
-A DOCKER -s 172.17.0.2/32 -d 172.17.0.3/32 -i docker0 -o docker0 -p tcp -m tcp --sport 3306 -j ACCEPT
root@fd90f24a4a59:/# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
^C^C92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
--- 172.17.0.2 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
root@fd90f24a4a59:/# curl 172.17.0.2:3306
8.0.19 Te1▒▒▒▒▒'QMB:vI`ycPcaching_sha2_password▒Got packets out of orderroot@fd90f24a4a59:/# xterm-256color
[root@node1 ~]# docker run --rm=true java curl 172.17.0.2:3306
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (7) Failed to connect to 172.17.0.2 port 3306: No route
to host
[root@node1 ~]# docker run --rm=true --link=mysqlserver:myserver -it java ping myserver
PING myserver (172.17.0.2): 56 data bytes
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
92 bytes from 172.17.0.1: Dest Unreachable, Unknown Code: 10
^C--- myserver ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
Docker远程代理(Ambassador) 模式
https://github.com/gliderlabs/connectable

socat是一个多功能的网络工具,名字来由是” SOcket CAT”
基于网络的互联
Docker的网络模型

Bridge(桥)是 Linux 上用来做 TCP/IP 二层协议交换的设备,与现实世界中的交换机功能相似。
常用的互联方式:端口映射

docker run -p "8080:80" 宿主的0.0.0.0:8080 -> 容器80
[root@node1 ~]# docker run --rm=true --name=mysqlserver -p 8066:3306 -e MYSQL_ROOT_PASSWORD=smoke520 mysql [root@node1 ~]# ps -elf | grep docker-proxy 4 S root 41390 94465 0 80 0 - 91097 futex_ 21:53 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8066 -container-ip 172.17.0.2 -container-port 3306 0 S root 41726 88007 0 80 0 - 28180 pipe_w 21:54 pts/0 00:00:00 grep --color=auto docker-proxy [root@node1 ~]# netstat -tnlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1024/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1444/master tcp6 0 0 :::8066 :::* LISTEN 41390/docker-proxy tcp6 0 0 :::22 :::* LISTEN 1024/sshd tcp6 0 0 ::1:25 :::* LISTEN 1444/master
Apparently there are some edge cases without a better workaround (for now):
•localhost<->localhost routing
•docker instance calling into itself via its published port
•and possibly more
[root@node1 ~]# iptables -t nat -L -n MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:3306 DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8066 to:172.17.0.2:3306 [root@node1 ~]# iptables -L -n ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:3306
Do we really need the proxy to be using 11MB of ram... per port!
Even one of the docker-proxy processes is using more than my znc server,and there are 3 ports forwarded from it!
Docker default bridge network makes networking very slow #11911
The user land proxy is going to be removed.Since removing the user land proxy will fix this problem,I'm going to close this in flavor of #11185 because the solution to #11185 is the complete removal of the user land proxy.
直接使用宿主机网络
[root@node1 ~]# docker run --rm=true --net=host --name=mysqlserver -e MYSQL_ROOT_PASSWORD=smoke520 mysql
[root@node1 ~]# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1024/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1444/master
tcp6 0 0 :::33060 :::* LISTEN 49883/mysqld
tcp6 0 0 :::3306 :::* LISTEN 49883/mysqld
tcp6 0 0 :::22 :::* LISTEN 1024/sshd
tcp6 0 0 ::1:25 :::* LISTEN 1444/master
[root@node1 ~]# docker inspect mysqlserver
"Networks": {
"host": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "12977d1d7d74463b9d8a91ae746d30d051fbcfe77faf10b90711e40d67516bbe",
"EndpointID": "6d037354d2fc875619a7d660815b3ce365c3c641b69046a464c2214a50422d1f",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
容器公用一个IP网络
[root@node1 ~]# docker run --rm=true --name=mysqlserver -e MYSQL_ROOT_PASSWORD=smoke520 mysql
[root@node1 ~]# docker run --rm=true --net=container:mysqlserver java ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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
209: eth0@if210: <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
[root@node1 ~]# docker inspect mysqlserver
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "2bd1ee6d1375a84d109f5b8945ebf15d5ddd0c0aad69ef8005a32b5ef74d4b06",
"EndpointID": "207dcd5d4018cf68e36754ca6dfafdbce3678b0d423fbedef9ab6f0c6054cf69",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
同一个IP怎么访问
[root@node1 ~]# docker run --rm=true --net=container:mysqlserver java curl localhost:3306
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 104 0 104 0 0 815 0 --:--:-- --:--:-- --:--:-- 825
7▒▒▒▒▒%t=m_&imGcaching_sha2_password▒Got packets out of order[root@node1 ~]#

目前更为复杂的主流方向
docker容器的IP地址能够被另外主机所访问

浙公网安备 33010602011771号