网络概述
容器网络是指容器连接到彼此或非 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 | 将容器与主机和其他容器完全隔离。 |
overlay | Overlay 网络将多个 Docker 守护程序连接在一起。 |
ipvlan | IPvlan 网络提供对 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 run
或docker create
命令的标志,基于每个容器配置DNS解析。
标志 | 描述 |
---|---|
--dns | DNS服务器的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文件。
代理服务器
如果您的容器需要使用代理服务器,请参见 使用代理服务器。