网络概述

容器网络是指容器连接到彼此或非 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 create` 或 `docker 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解析。

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

代理服务器

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