Docker之网络详解(一)
刚刚安装完成Docker之后,会默认建立好三个网络,分别为bridge, host, none,顾名思义分别就是桥接网络、主机网络和没有网络,使用以下命令可以查看:
docker network ls
默认在运行容器时如果不使用--network来指定要运行的网络,所有容器都是运行于bridge网络之上,也就是说同一台主机的容器默认都是可以互相通过IP地址进行沟通的。
以下举例说明:
首先建立两个容器,
[[email protected] ~]# docker run -itd --name=container1 busybox
727b52e3d2f638d010c5810b53a4ac4b2229592a5deea37ab3c061fa52a3cc4c
[[email protected] ~]# docker run -itd --name=container2 busybox
646b09ce6961d687fbd41cb3aa4e83a5c16682d3b6294d6a5f9410c647b1f6a4
通过docker network inspect命令可以查看网络的情况,例如:
docker network inspect bridge
[
{
"Name": "bridge",
"Id": "119344dd5ab99e6bba301ff863618afab914165dc718bdc609d207e48f535183",
"Created": "2018-02-06T07:54:15.453845691-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,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"646b09ce6961d687fbd41cb3aa4e83a5c16682d3b6294d6a5f9410c647b1f6a4": {
"Name": "container2",
"EndpointID": "acc0e686c4f35740caab600abc9231179085ce81ccd47cff86a71083bca83aec",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"727b52e3d2f638d010c5810b53a4ac4b2229592a5deea37ab3c061fa52a3cc4c": {
"Name": "container1",
"EndpointID": "6fbbdb9dcf232761c62886de54de525afc49235e3913af738d58bc92051cb095",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"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": {}
}
]
可见两个容器的IP地址分别为172.17.0.2和172.17.0.3。
现在使用命令docker container attach进入容器一看究竟:
docker container attach container1
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.240 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.174 ms
可见完全是可以Ping通container2的IP地址。
实现同一主机的简单网络隔离
如果不想使用默认的桥接网络,则可以使用以下命令定义自己的桥接网络:
docker network create --driver bridge isolated_nw
接下来,为容器指定运行于我们创建的网络:
docker run --network=isolated_nw -itd --name=container3 busybox
此时用同样的方法进入container3
发现IP与默认的桥接网络是不同的,也无法ping通原先的container1和container2了,到此我们实现了在同一主机的容器之间的网络隔离。
[[email protected] ~]# docker container attach container3
/ # ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
^C
--- 172.17.0.3 ping statistics ---
113 packets transmitted, 0 packets received, 100% packet loss
操纵Docker网络的常用命令
docker network create 建立网络
docker network connect 连接网络
docker network ls 显示网络
docker network rm 删除网络
docker network disconnect 断开网络
docker network inspect 查看网络
以下续一说明:
建立网络,
docker network create simple-network
docker network inspect simple-network
[
{
"Name": "simple-network",
"Id": "7e599ed4e37ba3ea8f142076f0134aeadd04b44dcfb40b768f27289a3be1c39f",
"Created": "2018-02-06T08:41:12.295793815-05:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.20.0.0/16",
"Gateway": "172.20.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
建立一个自定义的桥接网络,在不指定其它参数的情况网段会自动选择本机的未分配网段。
改变容器的连接网络,
以下举例说明:
先建立两个默认的容器,
[[email protected] ~]# docker run -itd --name=container1 busybox
1c95e4c26ceac6bed6fd8497417f79e9bcd470da97339fb47e9d82cb82c29e4a
[[email protected] ~]# docker run -itd --name=container2 busybox
fd0b00c1a22fb37e898733e1578967fe28057f6ba60921444b5e029cae5cf2e6
然后建立一个新的网络,
docker network create -d bridge --subnet 172.25.0.0/16 isolated_nw
最后将container2连接到新的网络,
docker network connect isolated_nw container2
[[email protected] ~]# docker container attach container1
/ # ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
21: [email protected]: <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 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
/ # exit
[[email protected] ~]# docker container attach container2
/ # ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
23: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
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
26: [email protected]: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:19:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.25.0.2/16 brd 172.25.255.255 scope global eth1
valid_lft forever preferred_lft forever
可见container2多了一张网卡,现在它可以连接新网络的其它容器了!
启动容器时,还可以自定义IP地址,如下所示:
docker run --network=isolated_nw --ip=172.25.3.3 -itd --name=container3 busybox
此时的container2可以横跨两个网络,可以同时与container1和container3沟通。
还可以在命令行中直接连接两个容器的网络:
docker run --network=isolated_nw -itd --name=container5 --link container4 busybox