网络概述

容器网络是指容器之间或非 Docker 工作负载之间连接和通信的能力。

容器默认启用网络,并且可以建立传出连接。容器不知道它所连接的网络类型,或者它们的对等体是否也是 Docker 工作负载。容器只能看到带有 IP 地址、网关、路由表、DNS 服务和其他网络详细信息的网络接口。也就是说,除非容器使用none网络驱动程序。

本页从容器的角度描述网络以及容器网络的概念。本页不描述有关 Docker 网络如何工作的特定于操作系统的详细信息。有关 Docker 如何iptables在 Linux 上操作规则的信息,请参阅 数据包过滤和防火墙

用户定义的网络

您可以创建自定义的、用户定义的网络,并将多个容器连接到同一网络。连接到用户定义的网络后,容器可以使用容器 IP 地址或容器名称相互通信。

以下示例使用bridge网络驱动程序创建网络并在创建的网络中运行容器:

$ docker network create -d bridge my-net
$ docker run --network=my-net -itd --name=container3 busybox

司机

默认情况下,以下网络驱动程序可用,并提供核心网络功能:

司机描述
bridge默认网络驱动程序。
host移除容器和 Docker 主机之间的网络隔离。
none将容器与主机和其他容器完全隔离。
overlayOverlay 网络将多个 Docker 守护进程连接在一起。
ipvlanIPvlan 网络提供对 IPv4 和 IPv6 寻址的完全控制。
macvlan为容器分配 MAC 地址。

有关不同驱动程序的详细信息,请参阅 网络驱动程序概述

容器网络

除了用户定义的网络之外,您还可以使用--network container:<name|id>标志格式将容器直接附加到另一个容器的网络堆栈。

使用网络模式的容器不支持以下标志container:

  • --add-host
  • --hostname
  • --dns
  • --dns-search
  • --dns-option
  • --mac-address
  • --publish
  • --publish-all
  • --expose

以下示例运行一个 Redis 容器,并将 Redis 绑定到 localhost,然后运行redis-cli命令并通过接口连接到 Redis 服务器localhost

$ docker run -d --name redis example/redis --bind 127.0.0.1
$ docker run --rm -it --network container:redis example/redis-cli -h 127.0.0.1

已发布的端口

docker create默认情况下,当您使用或创建或运行容器时docker run,容器不会向外界公开其任何端口。使用--publish-p标志使端口可用于 Docker 外部的服务。这会在主机中创建一条防火墙规则,将容器端口映射到 Docker 主机上通往外界的端口。这里有些例子:

标志值描述
-p 8080:808080将Docker 主机上的端口映射到80容器中的 TCP 端口。
-p 192.168.1.100:8080:808080将Docker 主机 IP 上的端口映射到容器中的192.168.1.100TCP 端口。80
-p 8080:80/udp8080将Docker 主机上的端口映射到80容器中的 UDP 端口。
-p 8080:80/tcp -p 8080:80/udp8080将Docker 主机上的TCP 端口映射到80容器中的 TCP 端口,将8080Docker 主机上的 UDP 端口映射到80容器中的 UDP 端口。

重要的

默认情况下,发布容器端口是不安全的。这意味着,当您发布容器的端口时,它不仅可供 Docker 主机使用,也可供外部世界使用。

127.0.0.1如果在发布标志中包含本地主机 IP 地址 ( ),则只有 Docker 主机可以访问已发布的容器端口。

$ docker run -p 127.0.0.1:8080:80 nginx

警告

同一 L2 网段内的主机(例如,连接到同一网络交换机的主机)可以访问发布到 localhost 的端口。有关更多信息,请参阅 moby/moby#45610

如果您想让一个容器可供其他容器访问,则无需发布该容器的端口。您可以通过将容器连接到同一网络(通常是 桥接网络)来启用容器间通信。

IP 地址和主机名

默认情况下,容器会为其连接的每个 Docker 网络获取一个 IP 地址。容器接收网络 IP 子网之外的 IP 地址。 Docker 守护进程为容器执行动态子网划分和 IP 地址分配。每个网络还有一个默认子网掩码和网关。

您可以将正在运行的容器连接到多个网络,方法是--network在创建容器时多次传递标志,或者docker network connect对已运行的容器使用命令。在这两种情况下,您都可以使用--ip--ip6标志来指定该特定网络上容器的 IP 地址。

同样,容器的主机名默认为 Docker 中容器的 ID。您可以使用 覆盖主机名--hostname。使用 连接到现有网络时docker network connect,您可以使用该--alias标志为该网络上的容器指定附加网络别名。

DNS服务

默认情况下,容器使用与主机相同的 DNS 服务器,但您可以使用--dns.

默认情况下,容器继承配置文件中定义的 DNS 设置 /etc/resolv.conf。连接到默认bridge网络的容器会收到此文件的副本。连接到 自定义网络的容器 使用 Docker 的嵌入式 DNS 服务器。嵌入式 DNS 服务器将外部 DNS 查找转发到主机上配置的 DNS 服务器。

您可以使用用于启动容器的docker run或命令的标志,在每个容器的基础上配置 DNS 解析 。docker create下表描述了docker run与 DNS 配置相关的可用标志。

旗帜描述
--dnsDNS 服务器的 IP 地址。要指定多个 DNS 服务器,请使用多个--dns标志。如果容器无法访问您指定的任何 IP 地址,它将使用位于 的 Google 公共 DNS 服务器8.8.8.8。这允许容器解析互联网域。
--dns-search用于搜索非完全限定主机名的 DNS 搜索域。要指定多个 DNS 搜索前缀,请使用多个--dns-search标志。
--dns-opt表示 DNS 选项及其值的键值对。有关resolv.conf有效选项,请参阅操作系统的文档。
--hostname容器自身使用的主机名。如果未指定,则默认为容器的 ID。

具有 IPv6 地址的名称服务器

如果/etc/resolv.conf主机系统上的文件包含一个或多个具有 IPv6 地址的名称服务器条目,这些名称服务器条目将被复制到/etc/resolv.conf您运行的容器中。

对于使用 musl libc 的容器(即 Alpine Linux),这会导致主机名查找出现竞争条件。因此,如果外部 IPv6 DNS 服务器赢得了与嵌入式 DNS 服务器的竞争条件,主机名解析可能会偶尔失败。

外部 DNS 服务器比嵌入式 DNS 服务器更快的情况很少见。但诸如垃圾收集或大量并发 DNS 请求之类的事情有时可能会导致到外部服务器的往返速度比本地解析速度更快。

自定义主机

您的容器将包含一些行,/etc/hosts其中定义容器本身的主机名以及localhost其他一些常见内容。在/etc/hosts主机上定义的自定义主机不会被容器继承。要将其他主机传递到容器中,请参阅 参考文档中的将条目添加到容器主机文件docker run

代理服务器

如果您的容器需要使用代理服务器,请参阅 使用代理服务器