网络是虚拟化技术中最复杂的部分,也是Docker应用中的一个重要环节。
Docker中的网络主要解决容器与容器、容器与外部网络、外部网络与容器之间的互相通信的问题。
这些复杂情况的存在要求Docker有一个强大的网络功能去保障其网络的稳健性。因此,Docker的网络功能是它的关键技术之一。
Docker基于Network Namespace提供隔离的网络环境,容器拥有独立的网络栈。
Docker官方提供了五种网络模式:
-
Bridge(默认模式):每个容器分配IP,并连接到docker0虚拟网桥,通过Iptables nat表与宿主机通信。
-
Host:容器不配置虚拟网卡,使用宿主机的IP和端口。
-
Container:新容器不创建自己的网络配置,与指定容器共享IP、端口。
-
None:关闭容器网络功能,不与其他容器或宿主机连通。
-
Overlay:这种模式用于在多个Docker主机之间创建一个虚拟网络,允许容器跨主机进行通信。
本文主要介绍前面四种,Overlay 参考:docker overlay网络原理详解-CSDN博客
网络模式 | 配置 | 说明 |
---|---|---|
bridge | --network | bridge 默认模式 |
host | --network host | 容器和宿主机共享 Network namespace |
container | --network container:NAME_OR_ID | 容器和另外一个容器共享 Network namespace |
none | --network none | 容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,配置 IP 等 |
默认网络
Docker安装后自动创建bridge、host、none三个网络。使用docker network ls
命令可以列出这些网络。
docker network ls
使用docker run命令创建Docker容器时,可以用--net命令指定容器的网络模式。
Docker的4种网络模式分别由如下命令指定:
- Bridge模式:使用--net=bridge指定,默认设置。
- Host模式:使用--net=host指定。
- Container模式:使用--net=container:NAME_or_ID指定。
- None模式:使用--net=none指定。
Bridge模式(默认方式)
Docker的Bridge模式是Docker容器的默认网络模式,它为每个容器提供了一个隔离的网络环境,同时允许容器与宿主机以及其他容器进行通信。以下是Bridge模式的详细特点和工作原理:
主要特点
-
独立的网络栈:每个容器都在自己的Network Namespace中运行,拥有独立的网络栈。
-
虚拟网桥:Docker使用一个虚拟网桥(默认为
docker0
),类似于物理交换机,连接所有容器。 -
自动IP分配:Docker为连接到Bridge网桥的每个容器自动分配一个唯一的IP地址。
-
容器间通信:容器可以通过它们各自的虚拟接口和网桥相互通信,就像它们处于同一局域网中一样。
-
与宿主机通信:容器可以通过NAT(网络地址转换)规则与宿主机通信,宿主机也可以访问容器。
-
端口映射:可以通过
-p
参数将容器内部端口映射到宿主机的端口,从而使外部网络能够访问容器中的服务。
工作原理
-
网桥创建:当Docker守护进程启动时,它会自动创建一个虚拟网桥(如
docker0
)。 -
veth pair接口:为每个容器创建一对虚拟网络接口(veth pair),一端连接容器内部的
eth0
,另一端连接到网桥。 -
IP地址分配:Docker使用内置的IP地址管理(IPAM)为每个容器分配一个IP地址,通常处于
172.17.0.0/16
网段。 -
NAT规则:Iptables规则被配置以允许容器通过宿主机的IP地址与外部网络通信。
-
容器连接:当容器被创建时,它的网络接口会被连接到
docker0
网桥上,使其能够与网络中的其他容器通信。
示例命令
使用Bridge模式启动一个Docker容器通常不需要显式指定网络模式,因为Bridge是默认设置。但可以通过以下命令明确指定:
docker run -it --net=bridge ubuntu bash
这条命令会启动一个基于Ubuntu镜像的容器,并提供一个bash shell。容器将连接到默认的Bridge网络。
注意事项
-
默认网桥:
docker0
是Docker自动创建的默认网桥,通常不需要手动配置。 -
网络隔离:尽管容器在网络层面上是隔离的,但它们仍然可以通过网桥进行通信。
-
端口映射:使用端口映射时,需要确保宿主机上映射的端口没有被其他服务使用。
-
网络安全:由于容器共享宿主机的网络,因此需要考虑网络安全策略,如使用防火墙规则来限制访问。
查看某网络的详细信息
[root@yeweijie-cvm-71 ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
2a6943137141 bridge bridge local
78e82590f37e harbor_harbor bridge local
6106e5ad9c03 host host local
2b10648fd424 none null local
[root@yeweijie-cvm-71 ~]#
[root@yeweijie-cvm-71 ~]# docker network inspect 2a6943137141
如上图,可以看到默认的bridge模式,网关为:172.17.0.1; 网段为:172.17.0.3/16,目前已分配四个容器,分配的IP地址为172.17.0.2到172.17.0.5
查看docker 的IP
# docker inspect --format '{{json .NetworkSettings.IPAddress}}' ${docker_id}
docker inspect --format '{{json .NetworkSettings.IPAddress}}' aee012a7b0e1
查看对应容器的 iptables 规则
iptables -t nat -vnL
iptables -t nat -vnL |grep 172.17.0.5
Host模式
容器与宿主机共用Network Namespace,不分配独立IP。容器使用宿主机的IP和端口。
Docker的Host模式提供了一种网络配置选项,允许容器直接使用宿主机的网络堆栈。这意味着容器不会获得自己的网络命名空间,而是与宿主机共享网络接口和配置。以下是Host模式的一些关键特点和使用场景:
主要特点
-
共享网络命名空间:容器与宿主机共享同一个网络命名空间,因此它们之间不会有网络隔离。
-
直接使用宿主机的IP:容器会直接使用宿主机的IP地址,不会分配独立的IP地址给容器。
-
端口映射:由于容器使用宿主机的端口,因此不需要进行端口映射(即不需要使用
-p
参数来映射端口)。容器内部服务的端口直接映射到宿主机的相应端口。 -
网络性能:由于避免了虚拟网络接口的开销,Host模式下容器的网络性能通常比使用桥接网络(Bridge模式)时更优。
-
安全性:由于容器与宿主机共享网络,任何对容器的网络攻击都可能影响到宿主机。因此,Host模式在安全性方面需要谨慎使用。
使用场景
-
性能敏感型应用:当运行对网络性能要求极高的应用时,Host模式可以减少网络通信的延迟和开销。
-
宿主机网络调试:在需要调试宿主机网络配置或直接与宿主机网络服务交互的场景下,Host模式非常有用。
-
特定网络服务:当容器需要作为宿主机上的特定网络服务运行时,例如,作为网络代理或负载均衡器,Host模式可以简化配置。
示例命令
要使用Host模式启动一个Docker容器,可以使用--net=host
标志:
docker run -it --net=host ubuntu bash
这条命令会启动一个基于Ubuntu镜像的容器,并提供一个bash shell。由于使用了Host模式,这个容器将直接使用宿主机的网络。
注意事项
-
使用Host模式时,容器内的网络配置(如
/etc/hosts
、/etc/resolv.conf
等)将与宿主机保持一致。 -
在Host模式下,容器内的网络服务可能会与宿主机上的服务冲突,因此需要仔细规划端口和服务的使用。
-
Host模式可能会增加安全风险,因为它减少了容器与宿主机之间的隔离。因此,除非必要,通常不建议在生产环境中使用Host模式。
Container模式
新容器与已存在容器共享Network Namespace,共享网卡、主机名、IP地址,通过本地回环接口通讯。
Docker的Container模式(也称为Container网络模式)允许一个新创建的容器与一个已经存在的容器共享同一个网络命名空间。这意味着两个容器将共享相同的网络接口、IP地址和端口号,它们之间可以直接通过回环接口(lo)进行通信,而不需要通过网络。以下是Container模式的一些关键特点和使用场景:
主要特点
-
共享网络命名空间:新容器与指定的容器共享网络命名空间,它们具有相同的网络配置。
-
共享IP地址:两个容器共享同一个IP地址,因此从外部网络来看,它们是不可区分的。
-
直接通信:由于共享网络命名空间,两个容器可以直接通过回环接口进行通信,无需通过网络。
-
端口共享:共享网络命名空间的容器可以访问和使用相同的端口。
-
资源隔离:尽管网络命名空间被共享,但容器的文件系统、进程列表等其他资源仍然是隔离的。
使用场景
-
服务发现:在微服务架构中,服务实例可能需要共享网络以便更容易地发现和通信。
-
容器间紧密耦合:当两个容器需要紧密协作,共享网络可以简化它们的通信机制。
-
网络配置简化:在某些情况下,共享网络可以减少网络配置的复杂性。
示例命令
要使用Container模式启动一个Docker容器,并与已存在的容器existing_container
共享网络命名空间,可以使用以下命令:
docker run -it --net=container:existing_container new_container_image bash
这条命令会启动一个新的容器,并使其与名为existing_container
的已存在容器共享网络命名空间。new_container_image
是你想要运行的新容器的镜像名称。
注意事项
-
使用Container模式时,新容器将无法拥有独立的网络接口或IP地址。
-
由于共享了网络命名空间,新容器的网络配置将受到现有容器网络状态的影响。
-
如果现有容器的网络配置发生变化,如IP地址变更,新容器的网络配置也会相应变化。
-
在Container模式下,两个容器之间的网络通信不会经过任何网络地址转换(NAT),因此它们可以直接通过回环接口通信。
None模式
一句话:就是不配置任何网络,与宿主机和其他容器都不连通。
Docker的None网络模式是一种特殊的网络配置,它创建了一个具有网络命名空间但没有任何网络配置的容器。这意味着容器将不会有任何网络接口,无法进行任何网络通信。以下是None模式的一些关键特点和使用场景:
主要特点
-
独立的网络命名空间:容器拥有自己的网络命名空间,但是不分配任何网络接口。
-
无网络接口:在None模式下,容器内不会有任何网络接口,如
eth0
。 -
无IP地址:由于没有网络接口,容器也不会有分配的IP地址。
-
无法进行网络通信:容器无法访问外部网络,也无法被外部网络访问。
-
完全隔离:容器的网络环境与宿主机和其他容器完全隔离。
使用场景
-
测试和隔离:在需要完全隔离网络环境进行测试的场景下,None模式非常有用。
-
依赖网络服务的容器:当容器需要依赖于宿主机或其他容器提供的网络服务,但本身不需要直接访问网络时,可以使用None模式。
-
简化网络配置:在某些情况下,为了简化网络配置和管理,可能会选择None模式。
示例命令
要使用None模式启动一个Docker容器,可以使用以下命令:
docker run -it --net=none ubuntu bash
这条命令会启动一个基于Ubuntu镜像的容器,并提供一个bash shell。由于使用了None模式,这个容器将不会有任何网络接口。
注意事项
-
使用None模式时,容器将完全与网络隔离,因此不适合需要网络通信的应用。
-
如果容器需要在后期配置网络,None模式提供了一个干净的起点,但需要手动添加网络接口和配置。
-
None模式下的容器仍然可以通过Docker的高级网络功能(如端口映射)来访问外部服务,但这需要额外的配置。
-
在None模式下,容器的网络环境可以被完全控制,适合于需要精细网络管理的场景。
总结
-
默认网络: Docker安装后自动创建bridge、host、none三个网络,可通过
docker network ls
命令列出。 -
网络模式指定: 在使用
docker run
创建容器时,可通过--net
选项指定网络模式。 -
网络隔离: Host模式和Container模式减少了容器与宿主机之间的网络隔离,因此在安全性方面需要特别注意。
-
网络性能: Host模式由于避免了虚拟网络接口的开销,通常提供比Bridge模式更优的网络性能。
-
使用场景: 根据不同的应用场景和需求,选择合适的网络模式,例如性能敏感型应用可能更适合Host模式,而需要网络隔离的场景则可能需要Bridge或None模式。
没展开讲的Overlay网络是一种用于在多个Docker主机之间创建虚拟网络的模式,允许容器跨主机进行通信,此部分将单独讲解。