Docker单机桥接网络

最简单的 Docker 网络就是单机桥接网络。

从名称中可以看到两点,单机意味着该网络只能在单个 Docker 主机上运行,并且只能与所在 Docker 主机上的容器进行连接,桥接意味着这是 802.1.d 桥接的一种实现(二层交换机)。

Linux Docker 创建单机桥接网络采用内置的桥接驱动。

下图展示了两个均包含相同本地桥接网络 mynet 的 Docker 主机。虽然网络是相同的,但却是两个独立的网络。这意味着图中容器无法直接进行通信,因为并不在一个网络当中。

每个 Docker 主机都有一个默认的单机桥接网络。

在 Linux 上网络名称为 bridge,在 Windows 上叫作 nat。除非通过命令行创建容器时指定参数--network,否则默认情况下,新创建的容器都会连接到该网络。

下面列出了 docker network ls 命令在刚完成安装的 Docker 主机上的输出内容。输出内容做了截取处理,只展示了每个主机上的默认网络。注意,网络的名称和创建时使用的驱动名称是一致的——这只是个巧合。

/Linux
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
333e184cd343 bridge bridge local

docker network inspect bridge

可以看到桥接网络的内容

在 Linux 主机上,Docker 网络由 Bridge 驱动创建,而 Bridge 底层是基于 Linux 内核的 Linux Bridge 技术。Bridge 是高性能并且非常稳定的!同时可以通过标准的 Linux 工具来查看这些网络,代码如下。

$ ip link show docker0

在 Linux Docker 主机之上,默认的“bridge”网络被映射到内核中为“docker0”的 Linux 网桥。可以通过 docker network inspect 命令观察到上面的输出内容。

docker network inspect bridge | grep bridge.name

Docker 默认“bridge”网络和 Linux 内核中的“docker0”网桥之间的关系如下图所示。

下图对上图的内容进行了扩展,在顶部补充了接入“bridge”网络的容器。

“bridge”网络在主机内核中映射到名为“docker0”的 Linux 网桥,该网桥可以通过主机以太网接口的端口映射进行反向关联。

接下来使用 docker network create 命令创建新的单机桥接网络,名为“localnet”。

//Linux
$ docker network create -d bridge localnet

新的网络创建成功,并且会出现在 docker network ls 命名的输出内容当中。如果使用 Linux,那么在主机内核中还会创建一个新的 Linux 网桥。

接下来通过使用 Linux brctl 工具来查看系统中的 Linux 网桥。可能需要通过命令 apt-get install bridge-utils 来安装 brctl 二进制包。

两个网桥目前都没有开启 STP,并且也都没有任何设备接入(对应的 interfaces 列为空)。

目前,主机上的网桥配置如下图所示。

接下来创建一个新的容器,并接入到新建桥接网络 localnet 当中。

 docker container run -d --name c1 \
--network localnet \
alpine sleep 1d

容器现在接入了 localnet 网络当中。可以通过 docker network inspect 命令来确认。

$ docker network inspect localnet --format

加上格式化参数后

输出内容表明“c1”容器已经位于桥接(Bridge/NAT)网络 localnet 之上。

如果再次运行 brctl show 命令,就能看到 c1 的网络接口连接到了 br-3576dcb29082 网桥。

如果在相同网络中继续接入新的容器,那么在新接入容器中是可以通过“c1”的容器名称来 ping 通的。这是因为新容器都注册到了指定的 Docker DNS 服务,所以相同网络中的容器可以解析其他容器的名称。

    提示:Linux 上默认的 Bridge 网络是不支持通过 Docker DNS 服务进行域名解析的。自定义桥接网络可以!

下面一起来测试一下。
1) 创建名为“c2”的容器,并接入“c1”所在的 localnet 网络。

$ docker container run -it --name c2 \
--network localnet \
alpine sh

当前终端会切换到“c2”容器中。

2) 在“c2”容器中,通过“c1”容器名称执行 ping 命令。

命令生效了!c2 容器运行了一个本地 DNS 解析器,该解析器将请求转发到了 Docker 内部 DNS 服务器当中。DNS 服务器中记录了容器启动时通过 --name 或者 --net-alias 参数指定的名称与容器之间的映射关系。

如果仍处于容器中,可以尝试运行一些网络相关的命令。这是一种很好的了解 Docker 容器网络工作原理的方式。

到目前为止,前面提到的桥接网络中的容器只能与位于相同网络中的容器进行通信。可以使用端口映射(Port Mapping)来绕开这个限制。端口映射允许将某个容器端口映射到 Docker 主机端口上。对于配置中指定的 Docker 主机端口,任何发送到该端口的流量,都会被转发到容器。下图中展示了具体流量动向。

如上图所示,容器内部应用开放端口为 80。该端口被映射到了 Docker 主机的 10.0.0.15 接口的 5000 端口之上。最终结果就是访问 10.0.0.15:5000 的所有流量都被转发到了容器的 80 端口。

接下来通过示例了解将容器上运行着 Web 服务的端口 80,映射到 Docker 主机端口 5000 的过程。示例使用 Linux 的 Nginx。

1) 运行一个新的 Web 服务容器,并将容器 80 端口映射到 Docker 主机的 5000 端口。

$ docker container run -d --name web \
--network localnet \
--publish 5000:80 \
nginx

2) 确认端口映射。

$ docker port web

这表示容器 80 端口已经映射到 Docker 主机所有接口上的 5000 端口。

3) 通过 Web 浏览器访问 Docker 主机 5000 端口,验证配置是否生效,如下图所示。为了完成测试,需要知道 Docker 主机的 IP 地址或者 DNS 名称。

外部系统现在可以通过 Docker 主机的 TCP 端口 5000,来访问运行在桥接网络上的 Nginx 容器了。

端口映射工作原理大致如此,这种方式比较笨重并且不能扩展。在只有单一容器的情况下,它可以绑定到主机的任意端口。其他容器就不能再使用已经被 Nginx 容器占用的 5000 端口了。这也是单机桥接网络只适用于本地开发环境以及非常小的应用的原因。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值