docker的网络基础
一、前言
很多开发者用得最多的就是使用 -p -P 参数,将容器端口映射到主机端口,而且使用的是docker的默认创建的网络,这里简要介绍一下docker常用的网络模式
二、术语简介
docker网络中涉及的术语。
1、网桥(bridge)
docker中的虚拟网桥,类似于现实中的物理交换机、中转站,主机通过虚拟网桥与多个容器相互通信。
你可以使用brctl show命令查看主机中的网桥设备:
brctl 命令使用 yum install -y bridge-utils 进行安装
2、网络模式(driver)
driver定义了网络的行为模式,即表示该网络通过何种模型进行通信、流量的转发。网络基于driver创建。
docker的driver分别如下,常用的是前3种。
- host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
- None:该模式关闭了容器的网络功能。
- Bridge:此模式会为每一个容器分配、设置IP等,并将容器连接到一个虚拟网桥,通过虚拟网桥以及Iptables nat表配置与宿主机通信。
- Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
3、虚拟网卡(veth pair)
设备与设备之间的连接需要使用网卡,例如主机与网桥的连接,网桥与容器的连接。
网卡总是成对出现,数据从一头进入,就会从另一边出来。
4、网络(network)
顾名思义,若干设备通过联结构成了可以通信的网络,
因此,从docker的角度来看,主机、虚拟网桥、虚拟网卡、容器构成了docker的其中一个网络。
你可以使用docker network ls 查看docker中现有的网络。其中bridge、host、none是docker启动时以三种driver默认创建的。
三、bridge模式
本文重点讲解bridge网络。
上面有提及到,docker在启动时会默认以三种driver启动三个默认网络。
docker network ls查看存在的网络
默认的bridge网络依赖docker0网桥。
docker run启动的容器如果不指定网络,
默认使用的是bridge网络
下面以我主机中现存的三个container为例,分别是consul1,consul2和mysql5.7,均连接到默认的网络中。
执行 brctl show命令查看 存在的虚拟网桥,veth表示连接容器和网桥的网卡。一头为veth0连接到容器,一头以类似veth67的命名连接到网桥中。
执行 ip addr 命令可以看到主机中的虚拟网卡设备情况。
执行 docker network inspect bridge 查看网络详情
- 该网络的 Driver 是 bridge
- 分配的为网段为:** 172.17.0.0/16**
- 网关为: 172.17.0.1
- 连接到网络中的容器有三个,ip地址分别为** 172.17.0.2~4**。
- 以及其他的网络设置Options:
设置 | 创建时命令行配置 | 作用 |
---|---|---|
.default_bridge | – | 创建Linux bridge使用的bridge名称 |
.enable_ip_masquerade | –ip-masq | 启用IP伪装 |
.enable_icc | –icc | 启用或禁用容器间连接 |
.host_binding_ipv4 | –ip | 绑定容器端口时默认绑定的IP |
driver.mtu | –mtu | 设置容器网络MTU |
[
{
"Name": "bridge",
"Id": "c87c19aed810fbb175ed1f81b1a2b1293246a11fd6d1767969aa910751fce754",
"Created": "2019-09-29T10:06:01.861761113+08: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": {
"45897d4f86c5a167fb49411ebfe2adcf96b21aec971229c7d1e25ea43ffcd1ef": {
"Name": "consul2",
"EndpointID": "7e581828751c92817dab5603496522199432bd4c32a40e1beca7d3b433add705",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"89a48e95f34a1447ce16b56be10a1ea8298e84259fd792c7d13874b611c8a897": {
"Name": "consul1",
"EndpointID": "efe2b71351d0cd643814f61ca2020820f732f9567e8e070323ade4f08d7deabf",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"a30ac707d754437bb55b19bb309204c21ed63430906e62e5ff29ddefdd1837a1": {
"Name": "mysql5.7",
"EndpointID":
"f9821cfb205e3665f358cc1c4ba217ac1cfe79c3e01ec5361ebdb94bd5df18c2",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/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": {}
}
]
复制代码
四、自创建docker网络
docker创建网络的参数,具体参数代表的意思可以看英文注释,或者查阅官网
创建一个以bridge为driver的网络new_net
docker network create --driver bridge new_net
复制代码
启动测试容器并且连接到该网络
docker run -itd --name=busybox1 --network=new_net busybox
docker run -itd --name=busybox2 --network=new_net busybox
docker run -itd --name=busybox3 --network=new_net busybox
复制代码
进入到容器中
docker exec -it busybox1 bash
复制代码
在容器 ping busybox2或者busybox3,能通过容器名直接ping通,当然 ping ip也是一定可以的
这是因为docker的网络内嵌了dns服务器。
在容器中执行 cat /etc/resolv.conf,可以看到该dns的地址。
再看一下主机的虚拟网桥,红色框框部分即是自建的网络中的网桥和网卡设备,可以按照上面的思路进行验证。
docker网络构成图大概如下:
参考:
高级网络配置
Docker:网络模式详解
关于 docker 的网络,你需要知道的事情 - 程天小邮差的文章 - 知乎
Docker命令行参考(29) – docker network create创建一个网络