Docker网络-bridge/host/container/none模式

本文详细介绍了Docker的四种网络模式:Bridge(桥接)模式,通过docker0网桥和vethpair技术实现容器间及与宿主机的通信;Host模式下,容器与宿主机共享网络栈,直接使用宿主机IP;Container模式让新容器共享已有容器的网络环境;None模式则提供无网络配置的封闭环境,强调安全隔离。每种模式的特点和应用场景都有所不同,为Docker容器的网络管理提供了灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

bridge模式

bridge 模式下,Docker Daemon 会创建出一个名为 docker0 的虚拟网桥 ,用来连接宿主机容器,或者连接不同的容器Docker 利用 veth pair技术,在宿主机上创建了两个虚拟网络接口 veth0 和 veth1(veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会无条件地传输给另一方)。

 Bridge桥接模式的实现步骤主要如下:

1. Docker Daemon利用veth pair技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0和veth1。而veth pair技术的特性可以保证无论哪一个veth接收到网络报文,都会将报文传输给另一方。

2. Docker Daemon将veth0附加到Docker Daemon创建的docker0网桥上。保证宿主机的网络报文可以发往veth0;

3. Docker Daemon将veth1添加到Docker Container所属的namespace下,并被改名为eth0。如此一来,保证宿主机的网络报文若发往veth0,则立即会被eth0接收,实现宿主机到Docker Container网络的联通性;同时,也保证Docker Container单独使用eth0,实现容器网络环境的隔离性。

容器与宿主机通信 : 在桥接模式下,Docker Daemon 将 veth0 附加到 docker0 网桥上,保证宿主机的报文有能力发往 veth0。再将 veth1 添加到 Docker 容器所属的网络命名空间,保证宿主机的网络报文若发往 veth0 可以立即被 veth1 收到。

容器与外界通信 : 容器如果需要联网,则需要采用 NAT 方式。准确的说,是 NATP (网络地址端口转换) 方式。NATP 包含两种转换方式:SNAT 和 DNAT 。

  • 目的 NAT (Destination NAT,DNAT): 修改数据包的目的地址。
  • 源 NAT (Source NAT,SNAT): 修改数据包的源地址。

外界访问Docker Container内部服务的流程为:

  1. 外界访问宿主机的IP以及宿主机的端口port_1;
  2. 当宿主机接收到这样的请求之后,由于DNAT规则的存在,会将该请求的目的IP(宿主机eth0的IP)和目的端口port1进行转换,转换为容器IP和容器的端口port0;
  3. 由于宿主机认识容器IP,故可以将请求发送给veth pair;
  4. veth pair的veth0将请求发送至容器内部的eth0,最终交给内部服务进行处理。

当宿主机以外的世界需要访问容器时,数据包的流向如下图所示:

 

解释上图:由于容器的 IP 与端口对外都是不可见的,所以数据包的目的地址为宿主机的 ip 和端口,为 192.168.1.10:24 。

数据包经过路由器发给宿主机 eth0,再经 eth0 转发给 docker0 网桥。由于存在 DNAT 规则,会将数据包的目的地址转换为容器的 ip 端口,为 172.17.0.n:24 。

宿主机上的 docker0 网桥识别到容器 ip 和端口,于是将数据包发送附加到 docker0 网桥上的 veth0 接口,veth0 接口再将数据包发送给容器内部的 veth1 接口,容器接收数据包并作出响应。

Docker Container访问宿主机以外世界的流程:

  1. Docker Container内部进程获悉宿主机以外服务的IP地址和端口port2,于是Docker Container发起请求。容器的独立网络环境保证了请求中报文的源IP地址为容器IP(即容器内部eth0),另外Linux内核会自动为进程分配一个可用源端口(假设为port3);
  2. 请求通过容器内部eth0发送至veth pair的另一端,到达veth0,也就是到达了网桥(docker0)处;
  3. docker0网桥开启了数据报转发功能(/proc/sys/net/ipv4/ip_forward),故将请求发送至宿主机的eth0处;
  4. 宿主机处理请求时,使用SNAT对请求进行源地址IP转换,即将请求中源地址IP(容器IP地址)转换为宿主机eth0的IP地址;
  5. 宿主机将经过SNAT转换后的报文通过请求的目的IP地址(宿主机以外世界的IP地址)发送至外界。

当容器需要访问宿主机以外的世界时,数据包的流向为下图所示:

解释上图:此时数据包的源地址为容器 ip 和端口,为 172.17.0.n:24,容器内部的 veth1 接口将数据包发往 veth0 接口,到达 docker0 网桥。

宿主机上的 docker0 网桥发现数据包的目的地址为外界的 IP 和端口,便会将数据包转发给 eth0 ,并从 eth0 发出去。由于存在 SNAT 规则,会将数据包的源地址转换为宿主机的 ip 端口,为 192.168.1.10:24 。

由于路由器可以识别到宿主机的 ip 地址,所以再将数据包转发给外界,外界接受数据包并作出响应。这时候,在外界看来,这个数据包就是从 192.168.1.10:24 上发出来的,Docker 容器对外是不可见的。

host模式

host模式介绍

Docker Container中的host模式并没有为容器创建一个隔离的网络环境。而之所以称之为host模式,是因为该模式下的Docker Container会和host宿主机共享同一个网络namespace,故Docker Container可以和宿主机一样,使用宿主机的eth0,实现和外界的通信。换言之,Docker Container的IP地址即为宿主机eth0的IP地址。

Docker Containerhost网络模式可以参考下图:

上图最左侧的Docker Container,即采用了host网络模式,而其他两个Docker Container依然沿用brdige桥接模式,两种模式同时存在于宿主机上并不矛盾。Docker Container的host网络模式在实现过程中,由于不需要额外的网桥以及虚拟网卡,故不会涉及docker0以及veth pair。

host模式是bridge桥接模式的补充

Docker Container的网络模式中,host模式是bridge桥接模式很好的补充。采用host模式的Docker Container,可以直接使用宿主机的IP地址与外界进行通信,若宿主机的eth0是一个公有IP,那么容器也拥有这个公有IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行NAT转换。

host模式缺点

Docker Container网络环境隔离性的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用host模式的Docker Container虽然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以bridge网络模式容器的端口映射。

container模式

container模式介绍

Docker Container的container网络模式,会使用其他容器的网络环境。

创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

Docker Container的other container网络模式可以参考下图:

上图右侧的Docker Container即采用了container网络模式,它能使用的网络环境即为左侧Docker Container brdige桥接模式下的网络。Docker Container的container网络模式在实现过程中,不涉及网桥,同样也不需要创建虚拟网卡veth pair

 Docker Container的container网络模式,可以用来更好的服务于容器间的通信。在这种模式下的Docker Container可以通过localhost来访问namespace下的其他容器,传输效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他容器形成网络隔离。

none模式

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息。这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

指定方法: --net="none" 可以看到,这样创建出来的容器完全没有网络:

[root@localhost ~]$ docker run -i -t --net="none"  centos:centos7 /bin/bash
root@061364719a22:$ ip addr
1: lo:  mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
root@061364719a22:$ ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2): 48 data bytes
ping: sending packet: Network is unreachable
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值