文章目录
- Docker 网络管理需求
- Docker 网络架构认识
- Docker 常见网络类型
- 1. bridge 网络
- 2. host 网络
- 3. container 网络
- 4. none 网络
- 5. overlay 网络
- Docker 网路基础指令
- Docker 网络管理实操
其他相关链接
Docker 基础使用(0)基础认识
Docker 基础使用(1)使用流程概览
Docker 基础使用(2)镜像与容器
Docker 基础使用(3)存储卷
Docker 网络管理需求
在操作系统的学习过程中,可以了解网络通信,本质上通常是两个进程的通信。Docker运行容器的本质通常是隔离了更多资源或属性的进程,隔离的资源就包括网络资源,容器的网络默认与宿主机及其他容器都是相互隔离。
但容器在实际应用场景下,也是需要进行网络(进程)间通信的。 通常需要考虑的通信场景有:
- 多个容器之间是如何通信的
- 容器和宿主机是如何通信的
- 容器和外界主机是如何通信的
- 容器中要运行一些网络应用(如 nginx、web 应用、数据库等),如果要让外部也可以访问这些容器内运行的网络应用应该如何实现
- 容器需要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网)应该如何实现
为了满足上述需求,便有了学习容器网络管理的需求。
Docker 网络架构认识
Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块。 Docker为了实现容器网络,主要采用Libnetwork与驱动作为架构。
CNM
Docker 网络架构采用的设计规范是 CNM(Container Network Model)。CNM 中规定了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。
Sandbox:提供了容器的虚拟网络栈,即端口、套接字、IP 路由表、防火墙、DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络环境。
Network:Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯。
Endpoint:就是虚拟网络的接口,就像普通网络接口一样,Endpoint 的主要职责是负责创建连接。Endpoint 类似于常见的网络适配器,那也就意味着一个 Endpoint 只能接入某一个网络, 当容器需要接入到多个网络,就需要多个 Endpoint。 如下图当两Endpoint同时接入同一个Network中即可实现容器间的通信。
Libnetwork
CNM是一种架构, Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。Libnetwork 实现了 CNM 中定义的全部三个组件以及其他额外的功能。
驱动
驱动指的是一种用于与底层系统或基础设施交互的插件,说的直白一点就是驱动是操作对应硬件的软件。 例如显卡驱动、显示器键盘鼠标的驱动(基础驱动装机自带,所以对电脑没有过多需求的用户不知道驱动是什么)。
Docker网络相关的驱动也是驱动的一种,驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。例如 Bridge Driver、Host Driver、Overlay Driver、MacVLan Driver、IPVLan Driver、None Driver 等等。每个驱动负责创建其上所有网络资源的创建和管理。
(补充:网络栈是一种计算机网络的概念,用于描述网络协议栈的层次结构。它包括多个层次,每个层次都负责不同的功能,具体来说就是网络通信模型中的某一层,例如物理层、数据链路层、网络层、传输层和应用层。)
Docker 常见网络类型
1. bridge 网络
bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上的容器可以相互通信。也可以通过 bridge 驱动程序配置,实现对外部容器的访问。Docker 容器的默认网络驱动.当我们需要多个容器在同一个 Docker 主机上通信时,桥接网络是最佳选择。
bridge 网络默认网桥
在创建容器时,默认情况下(即创建的容器在没有使用–network参数指定要加入的 docker 网络时)都是加入 Docker 默认的单机桥接网络。默认的 bridge 网络会被映射到内核中为 docker0 的网桥上,一个docker bridge 对应一个 Linux bridge (内核网桥)。bridge 是 Docker 对网络的命名,而 docker0 是内核中网桥的名字。通过 docker network ls
指令查询出的名为bridge网络即为默认网络。 当两个相同的容器连接同一个网桥,即可进行通信。此外用户可定义自定义,例如使用docker network create -d bridge new-bridge
指令,创建一个名为new-bridge自定义网桥。
值得注意是的,docker提供的默认bridge网络无法使用DNS域名解析服务。而自定义的bridge网络可以。
bridge 网络端口问题
docker 容器有和主机网络交互的需求,为此,需要对端口号进行专门的处理。通常容器要想和外部
主机或其他主机进行通信有两种策略。
① 暴露所有端口号, 在启动容器时,可以使用指令参数 -P暴露主机所有端口号
② 端口转发, 身端口转发(Port Forwarding)本身是一种网络配置,允许将来自外部网络的流量路由到局域网中的特定设备或服务。通常用于使外部用户能够访问局域网中的服务器或服务,如Web服务器或游戏服务器。 使用-p参数将主机端口号与容器端口号建立映射关系,主机指定端口号接收到的网络数据会发给容器的指定端口号。
2. host 网络
对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。当网络堆栈不应该与 Docker 主机隔离,但是希望容器的其他资源被隔离时,主机网络是最佳选择。
Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统, 但是如果基于 host 网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机共用同一个 Network Namespace,容器将不会虚拟出自己的网卡,IP 等,而是直接使用宿主机的 IP 和端口。
连接到 host 网络的容器共享宿主机的网络栈,容器的网络配置与宿主机完全一样。用户可以在启动容器时通过 --network=host 指定使用 host 网络。
bridge 网络在通信的时候需要进行端口转发以及 NAT 地址转换,这势必会消耗掉一些资源以及性能。而直接使用 host 网络最大的好处就是性能好,如果容器对网络传输效率有较高的要求,建议选择 host 网络。当然也会牺牲一些东西,比如要考虑端口冲突问题,其他服务已经被占用的端口就不能再使用了。
3. container 网络
这个模式指定新创建的容器和已存在的一个容器共享一个网络 ,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 ip,而是和一个已存在的、指定的容器共享 ip,端口等。两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 LO网卡(127.0.0.1,通常被称为本地回环地址(Loop back address))设备通信。
Docker Container 的 other container 网络模式是 Docker 中一种较为特别的网络的模式。之所以称为“other container 模式”,是因为这个模式下的 Docker Container,会使用其他容器的网络环境。之所以称为“特别”,是因为这个模式下容器的网络隔离性会处于 bridge 桥接模式与 host 模式之间。Docker Container 共享其他容器的网络环境,则至少两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
other container 网络模式的创建方式如下:
1. 创建一个 busybox 容器 (任意带网络通信的容器均可)
docker run -itd --name netcontainer1 busybox
2. 使用 netcontainer1 的网络创建另外一个容器
docker run -itd --name netcontainer2 --network container:netcontainer1 busybox
这样创建的两个容器的ip、mac地址完全一样。
4. none 网络
Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。容器完全网络隔离。
在运行容器的时候,可以通过–network=none 参数来指定容器使用 none 网络。
5. overlay 网络
借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个Docker 守护进程连接在一起,使集群服务能够相互通信。当我们需要运行在不同Docker 主机上的容器进行通信时,或者当多个应用程序使用集群服务协同工作时,覆盖网络是最佳选择。
Docker 网路基础指令
创建自定义网络
docker network create [OPTIONS] NETWORK
○ -d, --driver:网络驱动
○ --gateway:网关地址
○ --subnet:表示网段的 CIDR 格式的子网
○ --ipv6:启用 ipv6
查看网络详情
docker network inspect [OPTIONS] NETWORK [NETWORK...]
用于将容器连接到网络。可以按名称或 ID 连接容器。
一旦连接,容器可以与同一网络中的其他容器通信。
docker network connect [OPTIONS] NETWORK CONTAINER
断开网络
docker network disconnect [OPTIONS] NETWORK CONTAINER
删除不使用的网络
docker network prune [OPTIONS]
删除 1 个或者多个网络
docker network rm
列出网络
docker network ls
Docker 网络管理实操
创建网络
docker network create --subnet=172.18.0.0/16 mynetwork
列出已创建的网络
docker network ls
启动容器mynginx1并以名为mynetwork的网络启动
docker run -itd --name mynginx1 --network mynetwork nginx:1.24.0
docker inspect mynginx1:
启动容器2
docker run -itd --name mynginx2 nginx:1.24.0
查看容器2发现除了本地网络之外,没有其他的网络连接
docker inspect mynginx2
将创建的网络与容器2连接
docker network connect mynetwork mynginx2
再次查看容器2的网络,发现有新的网络
docker inspect mynginx2
完整执行流程
# 创建网络
docker network create --subnet=172.18.0.0/16 mynetwork
# 列出已创建的网络
docker network ls
# 启动容器mynginx1并以名为mynetwork的网络启动
docker run -itd --name mynginx1 --network mynetwork nginx:1.24.0
#查看容器1的信息
docker inspect mynginx1
#启动容器2
docker run -itd --name mynginx2 nginx:1.24.0
# 查看容器2发现除了本地网络之外,没有其他的网络连接
docker inspect mynginx2
# 将创建的网络与容器2连接
docker network connect mynetwork mynginx2
# 再次查看容器2的网络,发现有新的网络
docker inspect mynginx2
# 断开容器2的网络连接
docker network disconnect mynetwork mynginx2
docker inspect mynginx2
# 尝试删除网络,但删除失败,因为任然有容器1在使用该网络。
docker network rm mynetwork