Docker网络模式详解与应用

Docker网络模式详解与应用
Eucalyptus前言
Docker作为一个革命性的技术平台,极大地简化了应用程序的部署、管理和扩展过程,其中容器网络是其核心组件之一,对于充分挖掘Docker潜力至关重要。虽然不少开发者和IT专业人员可能已经接触或应用过Docker,但深入理解其网络机制仍然是提升容器化技能的关键步骤。本文旨在提供一个全面而深入的指南,帮助您不仅了解Docker网络的基础,还能掌握其高级特性和最佳实践。
Docker内置网络
当我们完成docker engine的安装以后,docker会在每一个engine上面生成一个3种网络,他们是:bridge, none还有host。
bridge
基本概念
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
如下图所示,当Docker1需要访问外网时,请求先到达Docker0虚拟网卡,然后在到达物理网卡,请求就发送出去了。
案例
(1)客户端执行”docker run”命令创建并启动容器。
查看容器信息
1 | docker inspect nginx |
(2)Docker引擎创建一对虚拟接口veth pair;并把它们分别放到宿主机和新容器的网络命名空间中。
(3)Docker引擎将宿主机上的veth接口连接到宿主机的docker0网桥上,并且给它分配一个以”veth”开头的名字,如veth8ead84e@if117。
(4)Docker引擎将容器上的veth接口改名为”eth0”,并且该接口只有在容器内网络命名空间中是可见的。
(5)Docker引擎从宿主机的docker0网桥上分配一个空闲的ip地址给容器内的eth0,例如:172.17.0.2。并将容器内eth0的路由网关设置为docker0的内部IP地址,例如:172.17.0.1。完成以上的这些步骤后,容器就可以使用其内部的虚拟接口”eth0”来连接到其他的容器和访问外部的网络了。
由于上面启动nginx容器的时候使用的是默认的bridge网络,并且也没有添加端口映射,所以iptables不会做DNAT规则
如果启动容器的时候做了端口映射,则iptables会做DNAT规则,实现端口转发功能,可以使用iptables -t nat -nL查看
工作原理
在 Docker 中启动容器时,如果没有指定网络模式,它默认连接到 Docker 主机上的一个桥接网络。这个桥接网络起初是空的,当容器连接到它时,Docker 会为每个容器分配一个 IP 地址和一个网络接口,并将这个接口连接到虚拟桥接上。
Docker 的桥接网络通常使用 NAT(网络地址转换)来连接到物理网络,使得容器能够通过宿主机的 IP 地址访问外部网络。
使用场景
- 隔离容器网络环境:当你希望运行的每个容器都有独立的网络堆栈时,Bridge网络非常有用。每个使用Bridge网络的容器都会获得自己的IP地址,并且容器之间的网络通信需要通过端口映射来进行,这提供了基本的网络隔离。
- 快速部署和测试:在开发和测试环境中,Bridge网络可以让开发者快速搭建一个与外部网络隔离的环境来部署和测试应用,而不会影响到主机或其他网络环境。
- 服务发现:虽然基础的Bridge网络不直接支持服务发现,但通过结合DNS解析(如使用docker-compose或Kubernetes中的服务发现机制)可以在一定程度上实现容器间的服务发现和通信。
- 端口映射:当需要从宿主机或其他网络访问容器内的服务时,可以使用Bridge网络并通过端口映射功能将容器的内部端口映射到宿主机的一个端口上,便于外部访问。
- 多主机通信需求不高场景:对于一些简单的多容器应用,如果不需要跨主机的容器网络通信,或者可以通过其他手段(如使用外部负载均衡器)来实现跨主机通信,使用Bridge网络就足够了。
- 轻量级解决方案:相比于更复杂的网络解决方案如overlay网络(用于跨多个Docker主机的容器通信)或macvlan网络,Bridge网络更简单、轻量,适合对网络需求不复杂的场景。
host
基本概念
host 模式:使用 –net=host 指定
相当于VMware 中的桥接模式,与宿主机在同一个网络中,但是没有独立IP地址
Docker 使用了Linux 的Namespace 技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace 隔离网络等。一个Network Namespace 提供了一份独立的网络环境,包括网卡,路由,iptable 规则等都与其他Network Namespace 隔离。一个Docker 容器一般会分配一个独立的Network Namespace
但是如果启动容器的时候使用host 模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口范围。此时容器不再拥有隔离的、独立的网络栈。不拥有所有端口资源
案例
我们拉起一个host网络的centos容器,查看容器信息,如下图所示,并没有发现IP信息
1 | docker run -itd --net=host --name centos7 eeb6ee3f44bd |
我们可以进入容器内部去查看下网络信息,通过下图发现,host网络模式下的容器的IP和宿主机IP一致
1 | # 进入容器 |
工作原理
主机网络模式下,容器将不会获得独立的 IP 地址。容器的网络堆栈将直接映射到宿主机上,容器内的网络服务可以直接绑定到宿主机的 IP 地址和端口上。这种模式通常用于需要进行大量网络操作或需要提供高性能网络服务的场景。
使用场景
- 性能敏感型应用:当容器化应用需要最大化网络性能时,使用主机网络是一个好选择。因为它消除了网络虚拟化带来的额外开销。
- 端口冲突:在主机网络模式下,容器可以直接使用宿主机的端口,避免了端口映射可能带来的端口冲突问题。
- 网络监控和管理:对于需要进行网络监控和管理的工具,主机网络模式能够提供更广泛的网络可视性和控制能力。
none
基本概念
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
案例
启动一个none网络的centos7的容器,查容器信息
1 | docker run -itd --name centos7 --net=none eeb6ee3f44bd |
进入容器查看网络信息
1 | # 进入容器 |
!!!大佬救命
这里可能处于none网络的原因,导致上面安装网络工具的时候失败
1 | # 安装网络工具 |
执行日志:
1 | Loaded plugins: fastestmirror, ovl |
container
基本概念
这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。因此,在这种模式下,容器之间可以通过 localhost 或者 127.0.0.1 进行相互间的访问,从而提高了传输的效率。
案例
(1)首先创建个基础容器
1 | docker run -itd --name centos7.A eeb6ee3f44bd |
(2)然后基于刚才的容器创建新的容器
1 | docker run -itd --net=container:04dcd560b6ce --name centos7.B eeb6ee3f44bd |
(3)对比上面创建的两个容器centos7.A和centos7.B发现使用了相同的网络命名空间,这是因为在创建容器B时使用了container模式,使得容器B不再创建自己的网络命名空间,而直接使用容器A的网络命名空间。
自定义网络
上面介绍的3种自带的网络模式有各自的局限性,因此,docker推荐大家自定义网络。通过自定义网络,我们可以实现”服务发现”与”DNS解析”。
docker 允许我们创建3种类型的自定义网络,bridge,overlay,MACVLAN
bridge:Bridge模式是Docker默认的网络模式,当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,用来连接宿主机和容器,此主机上的Docker容器都会连接到这个虚拟网桥上overlay:当有多个docker主机时,跨主机的container通信macvlan:每个container都有一个虚拟的MAC地址
bridge
基本概念
虽然Docker提供的默认bridge网络能满足很多基本需求,但在某些场景下,你可能需要创建自定义的bridge网络以实现更灵活的网络配置,比如指定子网、IP范围、网桥名称等。
自定义bridge网络为Docker容器提供了更灵活和可控的网络配置方式,它不仅能够帮助用户更好地组织和隔离容器网络,还支持更复杂的网络架构设计,满足不同应用场景的需求。通过精细的网络配置,可以有效地提升容器化应用的部署效率和管理便利性。
案例
首先创建一个网络(这里创建的时候没有指定子网网段)
1 | docker network create -d bridge test_bridge |
看下内置网络bridge和我们创建的test_bridge网络有什么区别
1 | docker inspect test_bridge |
自定义test_bridge网络
内置网络bridge
基于自定义网络test_bridge创建一个容器
1 | docker run -itd --name centos7.test --net=test_bridge eeb6ee3f44bd |
进入容器查看网络信息,会发现分配的ip在172.18.0.0/16网段中
Docker网络允许您将容器附加到任意数量的网络
将我们之前创建的centos7.A容器加入到test_bridge网络中,先看下centos7.A容器最初的网络信息
1 | docker network connect test_bridge centos7.A |
断开centos7.A容器和test_bridge网络的连接
1 | docker network disconnect test_bridge centos7.A |
使用方法
1 | docker network create --driver bridge --subnet=172.18.0.0/16 my-bridge-network |
overlay
基本概念
覆盖网络(Overlay Network)是 Docker 的一个高级网络类型,主要用于 Docker Swarm 集群环境中。它允许不同 Docker 主机上的容器相互通信,无论它们的物理位置如何。覆盖网络通过在宿主机之间创建一个虚拟网络层,来连接分布在不同节点上的容器。
工作原理
覆盖网络使用网络驱动(如 VXLAN)在宿主机之间建立一个虚拟网络。这个网络工作在现有的物理网络之上,容器之间的通信会被封装并通过这个虚拟网络传输。当数据包到达目的地后,它会被解封装并传递给目标容器。这种方式使得容器间能够透明地通信,就像它们在同一个网络中一样。
使用场景
- 多主机容器部署:当你需要在多个 Docker 主机上部署容器,并且这些容器需要相互通信时,覆盖网络是理想的选择。
- Docker Swarm 集群:在 Docker Swarm 环境中,覆盖网络允许不同节点上的服务实例之间进行通信,非常适合微服务架构。
- 跨主机负载均衡:覆盖网络支持跨多个宿主机的负载均衡,使得服务可以更加灵活地扩展和管理。
使用方法
要在 Docker Swarm 环境中创建一个覆盖网络,首先确保你的 Docker 环境已经初始化为 Swarm 模式,然后使用以下命令创建覆盖网络:
1 | docker network create -d overlay my_overlay_network |
创建了覆盖网络后,你可以在部署服务时指定使用这个网络:
1 | docker service create --name my_service --network my_overlay_network my_image |
注意事项
- 网络性能:由于覆盖网络中存在数据封装和解封装的过程,可能会对网络性能造成一定影响。
- 安全性:Docker 提供了网络加密选项来保护覆盖网络中的数据传输。
- 网络管理:管理覆盖网络可能需要对 Docker Swarm 集群的管理和网络原理有一定的了解。
macvlan
基本概念
Macvlan 网络是 Docker 提供的另一种网络类型,允许容器直接连接到物理网络。每个使用 Macvlan 网络的容器都会被分配一个独立的 MAC 地址,使其在网络上表现得就像是一个物理设备一样。这种网络类型适用于需要容器直接参与物理网络的场景,例如,当容器需要有自己的 IP 地址、或需要绕过 Docker 网络堆栈的复杂性时。
工作原理
Macvlan 网络通过创建一个或多个虚拟网络接口(Macvlan 接口)来工作,这些接口附加到宿主机的物理网络接口上。每个接口都有自己的 MAC 地址,容器通过这些虚拟接口与外部网络进行通信。这样,容器可以直接出现在物理网络上,而不是通过 Docker 主机的网络堆栈。
使用场景
- 需要直接网络访问:对于需要绕过 NAT、或需要与外部网络中的其他设备直接通信的容器,Macvlan 网络是一个理想的选择。
- 遗留系统集成:在一些遗留系统或需要直接网络访问的环境中,Macvlan 网络可以帮助容器更好地集成进这些环境中。
- 网络性能:由于容器直接连接到物理网络,Macvlan 可以提供更好的网络性能,减少虚拟化带来的开销。
使用方法
创建 Macvlan 网络的基本步骤如下:
- 创建 Macvlan 网络:
1 | docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my_macvlan_net |
这个命令会在宿主机的 eth0 网络接口上创建一个新的 Macvlan 网络,设置了子网和网关。
- 运行容器并连接到 Macvlan 网络:
1 | docker run --network my_macvlan_net --name my_container my_image |
这个命令启动一个容器,并将其连接到刚刚创建的 Macvlan 网络。
注意事项
- 网络隔离:使用 Macvlan 网络时,容器的网络隔离级别较低,容器直接暴露在物理网络上
- 路由和防火墙配置:可能需要在网络设备或宿主机上进行额外的路由和防火墙配置,以确保网络通信的正确性和安全性。
- 宿主机通信:默认情况下,使用 Macvlan 的容器可能无法与其宿主机进行直接通信。这可能需要额外的网络配置来解决。
总结
Docker 网络是容器化技术中不可或缺的一部分,它不仅提供了容器之间以及容器与外部世界之间通信的能力,还支持了高度的网络隔离和安全性。通过不同的网络类型和配置,Docker 能够满足各种应用场景的需求,从简单的单机部署到复杂的多主机、跨主机的集群环境。
bridge网络作为默认的网络类型,适用于大多数标准部署场景,提供了容器与外部网络的连接以及容器之间的隔离。host网络模式提供了最高的网络性能,适用于性能敏感型应用。overlay网络支持跨主机的容器通信,是在 Docker Swarm 集群中运行分布式应用的理想选择。Macvlan 网络则允许容器直接连接到物理网络,适用于需要直接网络访问或遗留系统集成的场景。
每种网络类型都有其适用场景和注意事项。选择合适的网络类型和配置,可以帮助开发者和运维人员构建高效、安全且易于管理的容器化应用。同时,Docker 的网络配置和管理工具也提供了灵活性和便利性,使得网络管理变得更加简单。
Docker 网络提供了强大而灵活的网络功能,支持各种应用部署和运行模式。通过合理选择和配置网络类型,可以最大化地发挥 Docker 容器的潜力,构建出高性能、安全且易于管理的容器化应用。































