docker Network(网络)
docker Network
- docker为什么需要网络管理?
- docker网络架构简介
- 常见的网络类型
- docker网络管理命令
- docker network create
- docker network inspect
- docker network connect
- docker network disconnect
- docker network prune
- docker network rm
- docker network ls
- 网络详解
- docker bridge网络
- docker Host网络
- docker Container 网络
- docker none 网络
docker为什么需要网络管理?
容器的网络默认与宿主机及其他容器都是相互隔离, 但同时我们也要考虑下面的一些问题, 比如:
- 多个容器之间是如何通信的
- 容器和宿主机是如何通信的
- 容器和外界主机是如何通信的
- 容器中要运行一些网络应用(如 nginx、web 应用、数据库等),如果要让外部也可以访问这些容器内运行的网络应用应该如何实现
- 容器不想让它的网络与宿主机、与其他容器隔离应该如何实现
- 容器根本不需要网络的时候应该如何实现
- 容器需要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网)应
该如何实现
docker网络架构简介
Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。
Docker 为实现容器网络,主要采用的架构由三部分组成:CNM、Libnetwork 和驱动。
CNM:
Docker 网络架构采用的设计规范是 CNM(Container Network Model)。CNM 中规定了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。
- Sandbox:提供了容器的虚拟网络栈,也即端口、套接字、IP 路由表、防火墙、DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络环境。
- Network:Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯。
- Endpoint:就是虚拟网络的接口,就像普通网络接口一样,Endpoint 的主要职责是负责创建连接。Endpoint 类似于常见的网络适配器,那也就意味着一个 Endpoint 只能接入某一个网络, 当容器需要接入到多个网络,就需要多个 Endpoint。
如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。那么容器 A 和容器 B 之间是可以实现通信的,因为都接入了 NetworkA。但是容器 A 和容器 C 不可以通过容器 B 的两个 Endpoint 通信。
Libnetwork:
Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。Libnetwork 实现了 CNM 中定义的全部三个组件,此外它还实现了本地服务发现、基于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能。
驱动:
驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。例如 Bridge Driver、Host Driver、Overlay Driver、MacVLan Driver、IPVLan Driver、None Driver 等等。每个驱动负责创建其上所有网络资源的创建和管理。
常见的网络类型
1. bridge网络:
bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上的容器可以相互通信。也可以通过 bridge 驱动程序配置,实现对外部容器的访问。Docker 容器的默认网络驱动.当我们需要多个容器在同一个 Docker 主机上通信时,桥接网络是最佳选择。
2. host网络:
对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。当网络堆栈不应该与 Docker 主机隔离,但是希望容器的其他资源被隔离时,主机网络是最佳选择。
3. container 网络:
这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 ip,而是和一个指定的容器共享 ip,端口等,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
4. none 网络:
Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。容器完全网络隔离。
5. overlay 网络:
借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个Docker 守护进程连接在一起,使集群服务能够相互通信。当我们需要运行在不同Docker 主机上的容器进行通信时,或者当多个应用程序使用集群服务协同工作时,覆盖网络是最佳选择。
在 Docker 安装时,会自动安装一块 Docker 网卡称为 docker0,它是一个网桥设备,主要用于 Docker 各容器及宿主机的网络通信:
docker网络管理命令
docker network create
语法: docker network create [OPTIONS] NETWORK
功能: 创建一个网络,不指定-d选项,默认是桥接网络
参数:
-d: 网络驱动,该选项接受overlay网络和birdge网络,如果有其它第三方网络,在这里指定即可;
–gateway:网关地址
–subnet:设置网络的ip地址范围,eg:192.168.32.0/24
–ipv6:启用ipv6
实战:
docker network inspect
语法: docker network inspect [OPTIONS] NETWORK [NETWORK…]
功能: 查看一个或多个网络的详细信息
参数:
-f: 指定格式显示;
实战:
docker network connect
语法: docker network connect [OPTIONS] NETWORK CONTAINER
功能: 将一个容器连接进一个网络
参数:
–ip: 给容器指定ipv4地址;
–ipv6: 给容器指定ipv6地址;
实战:
docker network disconnect
语法: docker network disconnect [OPTIONS] NETWORK CONTAINER
功能: 断开容器与网络的连接,并且在执行该命令的时候,容器必须正在运行;
参数:
-f:强制断开;
实战:
docker network prune
语法: docker network prune [OPTIONS]
功能: 删除所有未被容器引用的网络;
参数:
-f: 不要输出提示信息
实战:
docker network rm
语法: docker network rm NETWORK [NETWORK…]
别名: docker network remove
功能: 删除一个或多个网络
参数:
-f:强制删除;
实战:
docker network ls
语法: docker network ls [OPTIONS]
别名: docker network list
功能: 列出所有的网络
参数:
-q: 输出网络号
实战:
网络详解
docker bridge网络
Docker Bridge 网络采用内置的 bridge 驱动,bridge 驱动底层采用的是 Linux 内核中Linux bridge 技术。就网络而言,bridge 网络是在网络段之间转发流量的链路层设备,而网桥可以是在主机内核中运行的硬件设备或软件设备;就 Docker 而言,桥接网络使用软件网桥 docker0,它允许连接到同一网桥网络的容器进行通信,同时提供与未连接到该网桥网络容器的隔离。
默认情况下,创建的容器在没有使用–network 参数指定要加入的 docker 网络时,
默认都是加入 Docker 默认的单机桥接网络,即下面的 name 为 bridge 的网络。其中,容器、bridge和Host::eth0之间的之间的关系可以参考:手机、路由器、光猫之间的关系;
在日常的生活中,我们手机发出的数据包想要发送到外网的话,那么需要先将数据包发送给路由器,路由器的WAN口连接着光猫,因此路由器在拿到数据包过后,又会将其转发给光猫,再由光猫将数据转发到外网;默认的 bridge 网络会被映射到内核中为 docker0 的网桥上。
Docker 默认的 bridge 网络和 Linux 内核中的 docker0 网桥是一一对应的关系。
bridge 是 Docker 对网络的命名,而 docker0 是内核中网桥的名字。
注意:
- docker run --network选项会使容器加入指定的网络,而不会加入默认的docker0网络;如果没有指定该选项,那么容器加入的是默认docker0网络;
- 对于两个加入docker0网络的容器来说,互相ping对方的容器名是ping不通的,但是对于两个加入自定义bridge网络的容器来说互相ping容器名可以ping通;
docker Host网络
Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统, 但是如果基于 host 网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机共用同一个 Network Namespace,容器将不会虚拟出自己的网卡,IP 等,而是直接使用宿主机的 IP 和端口。
连接到 host 网络的容器共享宿主机的网络栈,容器的网络配置与宿主机完全一样。我
们可以通过 --network=host 指定使用 host 网络。
- 在host网络下,容器和宿主机处于同一个Network Namespace下,共享宿主机的端口和网络接口等资源;
- 在host模式下,不需要使用-p选项来指定端口映射;
- 相比于bridge类型网络的优点就是,转发效率高,因为在host网络中,避免了中间层的转发;
- 相比于bridge类型网络的缺点就是与宿主机共享同一套Network Namespace,网络资源都耦合在了一起,容器发生资源冲突;
docker Container 网络
Docker Container 的 other container 网络模式是 Docker 中一种较为特别的网络的模式。之所以称为“other container 模式”,是因为这个模式下的 Docker Container,会使用其他容器的网络环境。之所以称为“特别”,是因为这个模式下容器的网络隔离性会处于 bridge 桥接模式与 host 模式之间。Docker Container 共享其他容器的网络环境,则至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
Docker Container 的 other container 网络模式实现逻辑如下:
- 查找 other container(即需要被共享网络环境的容器)的网络 namespace;
- 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace, 使用 other container 的 namespace
总结:
- 可以使用
docker run --network container:要加入的容器网络的容器名
来加入container网络;- 容器2在加入容器1的网络过后和容器1共用同一套Network Namespace;
- 容器2的网络依赖于容器1的网络,一旦容器1重启过后,容器2的网络服务将不可用,只可使用本地环回网络;
docker none 网络
none 网络就是指没有网络。挂在这个网络下的容器除了 lo(本地回环),没有其他任何网卡。
总结:
- 针对一些对安全性要求比较高并且不需要联网的应用, 可以使用 none 网络, 比如生成随机密码, 避免生成密码被第三方获取;
- 一些第三方的应用可能需要 docker 帮忙创建一个没有网络的容器, 网络由第三方自己来配置。