在docker中,每个container 都是一个独立的个体。Container是一种轻量级的虚拟化技术,不用模拟硬件创建虚拟机。Docker是基于Linux Kernel的Namespace、CGroups、UnionFileSystem等技术封装成的一种自定义容器格式,从而提供一套虚拟运行环境。
Namespace : 用来做隔离的,比如pid[进程]、net[网络]、mnt[挂载点]等
CGroups : Controller Groups用来做资源限制,比如内存和CPU等
Unionfilesystems : 用来做image和container分层
所以每个container,都会有自己的network namespace,并且是独立的。在网络设计上也是通过namespace来互相隔离。在学习docker网络之前,可以先了解下Linux网卡相关信息,有助于更加深刻理解docker网络。网卡原理浅析
Container 的Namespace
-
启动两个Tomcat container
docker run --name tomcat01 -p 8081:8080 -d tomcat
-
并进入查看两个容器IP信息
docker exec -it tomcat01 ip a
-
查看主机centos IP信息
ip a
-
互相ping一下
docker exec -it tomcat01 ping 172.17.0.2
在上面分析说,每个container 是独立,是通过namespace被分割开的,那既然是在不同的namespace下,那他们是怎么通信的?
Container bridge 网络
在上一步,可以发现,container网络虽然在不同的namespace下,却也能互相通信。难道也是veth-pair技术?其实不是的,docker默认使用的是Bridge网络模式。
在上面启动了两个container 容器,tomcat01和tomcat02。我们可以看到他们的网卡信息
tomcat01 : eth0@if10
tomcat02 : eth0@if12
主机 : vethf4d5613@if9 和 vethb649f29@if11
因为docker 默认是Bridge网络模式。所以Container 与docker之间也是通过Bridge模式链接。可以通过命令查看本机的bridge网络信息
yum install bridge-utils
brctl show
类似veth,tomca01与tomcat02与主机有成对的veth(序号是连续的)。用图表示
可以通过docker network ls
查看docker的网络模型。
通过docker network inspect bridge
查看bridge 详细信息
[
{
"Name": "bridge",
"Id": "f0c48ab3ea649908098694f0d2e7c8924ed0c11b173d6cea2c87462f43487a6a",
"Created": "2021-06-28T20:36:32.496777771Z",
"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": {
"088c88596b0413d85c49ec4d1d21464f7e219089a0dcfbdedd3cef89b99ebdcb": {
"Name": "tomcat01",
"EndpointID": "91ebd527dcb511be87641a61b22dca7cc7b35cec63b6f8482f2d92bdf05bf43c",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"a0b79743ae420bb8a07d0a73dd5a06eeff089283ae84758846403e8f47f06c69": {
"Name": "tomcat02",
"EndpointID": "053dc08fc81d27ccccbd0822e1cb5a6236aecdd9b071c01724c60e64ad8b783b",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/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": {}
}
]
同理,container能访问Internet也是通过这种技术实现
如何在Docker创建Network并使用
- 创建自己的network
docker network create [name]
- 创建一个容器,并使用tomcat-net。
docker run --name custom-net-tomcat --network tomcat-net -d tomcat
- 查看容器custom-net-tomcat的网卡信息
docker exec -it custom-net-tomcat ip a
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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
valid_lft forever preferred_lft forever
-
查看主机网卡信息
-
查看网卡接口
brctl show
-
查看下tomcat01 的 IP信息。
docker exec -it tomcat01 ip addr
-
custom-net-tomcat 容器是ping不同tomcat01()的,因为他们在不同的network
-
将tomcat01也是用tomcat-net 网络
docker network connect tomcat-net tomcat01
-
查看tomcat-net 网络信息,发现tomcat01在其中
docker network inspect tomcat-net
-
再次ping就可以通了。而且还可以通过容器名称ping