理解Docker网络:探索User-defined Bridge

106 阅读5分钟

前言

现在绝大部分应用都有支持容器化部署,如 mysql,redis,nginx 等。我们在自己的单机开发测试环境可以非常方便的使用 docker 进行部署。但是有这样的问题,自己分开部署应用时,比如应用连接 mysql 和 redis,以前要么将 mysql, redis 端口映射到宿主机,应用网络配置成 host 模式进行连接或者应用配置它们的容器 ip,但这样重启容器 ip 可能会变,维护非常麻烦。解决这个问题的方案可以使用 docker 的 User-defined bridges 网络,下面开始介绍。

docker network driver

安装好 docker 服务后,默认会有3个 network ,bridge,host 和 none。 image.png

  • bridge: 默认 network driver,当应用程序在需要与同一主机上的其他容器通信的容器中运行时,通常使用桥接网络。
  • host: 移除容器与 Docker 主机之间的网络隔离,直接使用主机的网络。
  • none: 将容器与主机和其他容器完全隔离。使用该 network 创建的容器,仅创建环回设备网卡 lo

另外,用户也可使用 docker network create 命令创建自己的网络,默认 network driver 也是 bridge,你可指定子网,ip 地址范围等其他参数选项,详情可以加上 --help参数查看。

[root@z2024 ~]# docker network create --help

Usage:  docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which to copy the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment

User-defined bridge 与 default bridge 之间的差异

User-defined bridgedefault bridge 之间的差异,官方列出有以下几点

  1. User-defined bridges 在容器之间提供自动 DNS 解析。

default bridge 网络上的容器只能通过 IP 地址相互访问,除非使用 --link 选项,该选项被视为过时的。在 User-defined bridges网络上,容器可以通过名称或别名相互解析。

  1. User-defined bridges 提供更好的隔离

所有创建未使用 --network 指定的容器都将连接到默认网桥网络,而使用 User-defined bridges 提供了一个作用域内的网络,在该网络中,只有连接到该网络的容器才能进行通信。

  1. 容器可以动态地从用户定义的网络中 attached 和 detached

在容器的生命周期内,您可以动态地连接或断开它与用户定义的网络的连接 。要从默认网桥网络中删除容器,您需要停止该容器,然后使用不同的网络选项重新创建它。

  1. 每个用户定义的网络都会创建一个可配置的网桥。

如果容器使用默认网桥网络,则可以对其进行配置,但所有容器都使用相同的设置,例如 MTU 和 iptables 规则。此外,配置默认网桥网络发生在 Docker 本身之外,并且需要重新启动 Docker。 用户定义的网桥网络是使用 docker network create 创建和配置的。如果不同的应用程序组具有不同的网络要求,则可以在创建每个用户定义的网桥时单独配置网桥。

下面我们做个实验,分别在 User-defined bridgedefault bridge 网络下创建两个容器,首先创建一个 User-defined bridge 网络名叫 mytest

root@zvps1:~# docker network create mytest
60955eb581f962fac7a50fe3f45c29ef0f626ea7c451c35dc0cafb4547b80dd0
root@zvps1:~# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
606ce11f6e40   bridge    bridge    local
8a12b80eed2f   host      host      local
60955eb581f9   mytest    bridge    local
63d7be2720d7   none      null      local

创建4个容器,test1 和 test2 属于默认 bridge 网络,test3 和 test4 属于 mytest 网络

# test1 container
docker run --name test1 -d nginx
# test2 container
docker run --name test2 -d nginx
# test3 container
docker run --name test3 --network mytest -d nginx
# test4 container
docker run --name test4 --network mytest -d nginx

可以使用 docker network inspect 命令查看 docker 网络详情,还可以查看到哪些容器使用该网络以及容器 ip 和 mac 地址等信息 image.png
image.png

使用 busybox 容器测试 default bridge 网络,可以看到它无法解析 test1, test2 容器 image.png

使用 busybox 容器测试 mytest 网络,可以看到能解析 test3, test4 容器 image.png

Networking in Docker Compose

默认情况下,Compose 会为您的应用设置一个网络,服务的每个容器都加入它,这使得每个容器可以通过服务的名称发现。 例如,假设您的应用位于 myapp 的目录中,运行 docker compose up 时, 将创建一个名为的 myapp_default 网络。

总结

相比于默认的桥接网络,User-defined Bridges 不仅在容器之间提供自动 DNS 解析,还提供了更好的隔离和灵活性,使得容器间的通信更为便捷。Docker Compose 也是基于这一点,使得服务里面的容器可以互相解析。希望这篇文章对你有所帮助,如果你有任何疑问,欢迎留言讨论或者关注我的微信公众号运维小猪,谢谢!