网络概述

容器网络指的是容器连接并彼此通信或与非 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 主机可用,而且对外部世界也可用。

如果您在发布标志中包含 localhost 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 服务器。

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

标志描述
--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 参考文档中的 将条目添加到容器主机文件

代理服务器

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