要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。
Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。 Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。
Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 veth pair
)。
Docker 中使用 Network 来管理容器之间的通信,只要两个 Conteiner 处于同一个 Network 之中,就可以通过容器名去互相通信。
Docker 创建一个容器的时候,会执行如下操作:
docker0
或指定网桥上,并具有一个唯一的名字,如 veth65f9
eth0
,这个接口 只在 容器的名字空间可见eth0
,并配置默认路由到桥接网卡 veth65f9
完成这些之后,容器就可以使用 eth0
虚拟网卡来连接其他容器和其他网络。
可以在 docker run
的时候通过 --net
参数来指定容器的网络配置,有四个可选值,下面逐个进行解释。
Bridge 模式(--net=bridge
)为 Docker 容器默认创建后的网络模式,这中模式创建后即加入 docker0
网桥。其特点如下:
docker0
docker0
上Host 模式(--net=host
)并没有为容器创建一个隔离的网络环境(network namespace),这就意味着容器不会有自己的网卡信息,而是与宿主机共用网络环境,亦即拥有完全的本地主机接口的访问权限。
容器进程可以跟宿主机其他 root 进程一样打开低范围的端口,可以访问本地网络服务比如 D-Bus,还可以让容器做一些影响整个主机系统的事情。这种情况下,容器除了网络,其他都是隔离的。
此时容器内获取 IP 为宿主机 IP,端口绑定直接绑定在宿主机网卡上,有点是网络传输不用经过 NAT 转换,效率更高速度更快。
其特点包括:
Container 模式(--net=container:<NAME_OR_ID>
)是 Docker 中一种较为特别的网络的模式。处于这个模式下的 Docker 容器会共享其他容器的网络环境(共享 network namespace),因此,至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
两个容器有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 I/O 环回接口通信。
None 模式(--net=none
),即容器获取独立的 network namespace,但不为容器进行任何网络配置,需要手动配置。一旦 Docker 容器采用了 none 网络模式,那么容器内部就只能使用 loopback
网络设备,不会再有其他的网络资源。Docker Container 的 none 网络模式意味着不给该容器创建任何网络环境,容器只能使用 127.0.0.1
的本机网络。
# 通过link指令建立连接$ docker run --name <Name> -d -p <path1>:<path2> --link <containerName>:<alias> <containerName:tag/imageID>- --link 容器连接指令- < containerName > : < alias >- < 被连接容器名称 > : < 容器访问别名 >- 注:别名在主动建立连接的容器中访问被连接容器使用- 以下指令在容器检测连接状态$ curl <alias>
Docker 中常用的 network 指令:
$ docker network create# 将容器 container-name 连接到新建网络 network-name$ docker network connect <network-name> <contaienr-name>$ docker network ls# 将 container-name 从 network-name 网络中移除连接$ docker network disconnect <network-name> <container-name># 与 disconnect 相似,但是要求容器关闭或断开与此网络的连接$ docker network rm <network-name> <container-name># 查看容器的网络情况$ docker network inspect <container-name>
参考资料: