网络概述

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

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

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

用户定义网络

您可以创建自定义的用户定义网络,并将多个容器连接到同一个网络。一旦连接到用户定义的网络,容器可以使用容器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 命令并通过 localhost 接口连接到 Redis 服务器。

$ 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 createdocker run 创建或运行容器时, 桥接网络上的容器不会向外部世界暴露任何端口。 使用 --publish-p 标志使端口对桥接网络之外的服务可用。 这会在主机上创建一个防火墙规则, 将容器端口映射到 Docker 主机上的端口,从而向外部世界开放。 以下是一些示例:

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

重要

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

如果您在使用发布标志时包含本地 IP 地址(127.0.0.1::1),则只有 Docker 主机及其容器可以访问已发布的容器端口。

$ docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' nginx

警告

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

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

如果在端口映射中未指定主机 IP,且桥接网络仅支持 IPv4,以及 --userland-proxy=true(默认值),则主机的 IPv6 地址上的端口将映射到容器的 IPv4 地址。

有关端口映射的更多信息,包括如何禁用它并使用直接路由到容器,请参阅 数据包过滤和防火墙

IP 地址和主机名

默认情况下,容器在连接到每个 Docker 网络时会获得一个 IP 地址。 容器从网络的 IP 子网中获取一个 IP 地址。 Docker 守护进程为容器执行动态子网划分和 IP 地址分配。 每个网络也有一个默认的子网掩码和网关。

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

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

DNS 服务

容器默认使用与主机相同的 DNS 服务器,但您可以使用 --dns 覆盖此设置。

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

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

Flag描述
--dnsDNS 服务器的 IP 地址。要指定多个 DNS 服务器,请使用多个 --dns 标志。DNS 请求将从容器的网络命名空间转发,因此,例如,--dns=127.0.0.1 指的是容器自己的环回地址。
--dns-search一个用于搜索非完全限定主机名的 DNS 搜索域。要指定多个 DNS 搜索前缀,请使用多个 --dns-search 标志。
--dns-opt表示 DNS 选项及其值的键值对。有关有效选项,请参阅操作系统的 resolv.conf 文档。
--hostname容器用于自身的主机名。如果未指定,则默认为容器的 ID。

自定义主机

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

代理服务器

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