网络概述
容器网络指的是容器能够连接并相互通信,或者与非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
驱动程序
默认情况下,以下网络驱动程序可用,并提供核心网络功能:
| Driver | Description |
|---|---|
bridge | The default network driver. |
host | Remove network isolation between the container and the Docker host. |
none | Completely isolate a container from the host and other containers. |
overlay | Overlay networks connect multiple Docker daemons together. |
ipvlan | IPvlan networks provide full control over both IPv4 and IPv6 addressing. |
macvlan | Assign a MAC address to a container. |
有关不同驱动程序的更多信息,请参阅 网络驱动程序 概述。
容器网络
除了用户定义的网络外,您还可以使用--network container:标志格式,直接将容器附加到另一个容器的网络堆栈上。
以下标志不支持使用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主机上的端口,以便与外界通信。以下是一些示例:
| Flag value | Description |
|---|---|
-p 8080:80 | Map port 8080 on the Docker host to TCP port 80 in the container. |
-p 192.168.1.100:8080:80 | Map port 8080 on the Docker host IP 192.168.1.100 to TCP port 80 in the container. |
-p 8080:80/udp | Map port 8080 on the Docker host to UDP port 80 in the container. |
-p 8080:80/tcp -p 8080:80/udp | Map TCP port 8080 on the Docker host to TCP port 80 in the container, and map UDP port 8080 on the Docker host to UDP port 80 in the container. |
重要
默认情况下,发布容器端口是不安全的。这意味着,当你发布容器的端口时,它不仅对Docker主机可用,也对外部世界可用。
如果你在发布标志中包含本地主机IP地址(
127.0.0.1或::1),只有Docker主机及其容器可以访问发布的容器端口。$ docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' nginx警告
在同一L2段内的主机(例如,连接到同一网络交换机的主机)可以访问发布到本地主机的端口。 更多信息,请参见 moby/moby#45610
如果您想让其他容器访问某个容器, 不需要发布容器的端口。 您可以通过将容器连接到同一网络来启用容器间通信,通常是 桥接网络。
如果端口映射中没有给出主机IP,主机IPv6地址上的端口将映射到容器的IPv4地址,桥接网络仅支持IPv4,并且--userland-proxy=true(默认)。
有关端口映射的更多信息,包括如何禁用它并使用直接路由到容器,请参阅 数据包过滤和防火墙。
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 run或docker create命令的标志。下表描述了与DNS配置相关的可用docker run标志。
| Flag | Description |
|---|---|
--dns | The IP address of a DNS server. To specify multiple DNS servers, use multiple --dns flags. DNS requests will be forwarded from the container's network namespace so, for example, --dns=127.0.0.1 refers to the container's own loopback address. |
--dns-search | A DNS search domain to search non-fully qualified hostnames. To specify multiple DNS search prefixes, use multiple --dns-search flags. |
--dns-opt | A key-value pair representing a DNS option and its value. See your operating system's documentation for resolv.conf for valid options. |
--hostname | The hostname a container uses for itself. Defaults to the container's ID if not specified. |
自定义主机
您的容器将在/etc/hosts中有几行定义容器本身的主机名,以及localhost和其他一些常见内容。在主机上定义的/etc/hosts中的自定义主机不会被容器继承。要将其他主机传递到容器中,请参阅docker run参考文档中的向容器主机文件添加条目。
代理服务器
如果你的容器需要使用代理服务器,请参阅 使用代理服务器。