147 lines
9.1 KiB
Markdown
147 lines
9.1 KiB
Markdown
---
|
||
outline: [2,5]
|
||
---
|
||
# 网络概述
|
||
|
||
容器网络是指容器相互连接和通信的能力,或连接到非Docker工作负载的能力。
|
||
|
||
容器默认启用了网络,并且可以建立出站连接。容器没有关于它连接到哪种网络的信息,或者他们的同行是否也是Docker工作负载的信息。容器只看到具有IP地址、网关、路由表、DNS服务和其他网络详细信息的网络接口。也就是说,除非容器使用`none`网络驱动程序。
|
||
|
||
本页从容器的角度描述网络,以及围绕容器网络的概念。本页不介绍有关Docker网络如何工作的操作系统特定细节。有关Docker如何在Linux上操作`iptables`规则的信息,请参阅[数据包过滤和防火墙][0]。
|
||
|
||
## 用户定义的网络
|
||
您可以创建自定义的用户定义网络,并将多个容器连接到同一网络。一旦连接到用户定义的网络,容器可以使用容器IP地址或容器名称相互通信。
|
||
|
||
以下示例使用网桥网络驱动程序创建网络,并在创建的网络中运行容器:
|
||
``` console
|
||
$ docker network create -d bridge my-net
|
||
$ docker run --network=my-net -itd --name=container3 busybox
|
||
```
|
||
### 驱动器
|
||
默认情况下,以下网络驱动程序可用,并提供核心网络功能:
|
||
|
||
驱动 | 描述
|
||
| - | - |
|
||
bridge | 默认网络驱动程序。
|
||
host | 删除容器和Docker主机之间的网络隔离。
|
||
none | 将容器与主机和其他容器完全隔离。
|
||
overlay | 叠加网络将多个Docker守护程序连接在一起。
|
||
ipvlan | IPvlan网络提供对IPv4和IPv6寻址的完全控制。
|
||
macvlan | 为容器分配一个MAC地址。
|
||
有关不同驱动程序的更多信息,请参[阅网络驱动程序概述][1]。
|
||
|
||
### 连接到多个网络
|
||
一个容器可以连接到多个网络。
|
||
|
||
例如,前端容器可以连接到具有外部访问的桥接网络,以及一个`--internal`网络,用于与运行不需要外部网络访问的后端服务的容器进行通信。
|
||
容器也可以连接到不同类型的网络。例如,提供互联网接入的`ipvlan`网络,以及接入本地服务的`bridge`网络。
|
||
|
||
发送数据包时,如果目的地是直接连接网络中的地址,则数据包将发送到该网络。否则,数据包会发送到默认网关,以便路由到其目的地。在上述示例中,`ipvlan` 网络的网关必须是默认网关。
|
||
|
||
默认网关由Docker选择,每当容器的网络连接发生变化时,可能会发生变化。要让Docker在创建容器或连接新网络时选择特定的默认网关,请设置网关优先级。请参阅 [`docker run`][2] 和 [`docker network connect`][3] 命令的 `gw-priority` 选项。
|
||
|
||
默认的 `gw-priority` 为 `0`,网络中具有最高优先级的网关是默认网关。因此,当网络应该始终是默认网关时,将其 `gw-priority` 设置为1就足够了。
|
||
|
||
``` console
|
||
$ docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
|
||
$ docker network connect anet2 myctr
|
||
```
|
||
|
||
## 容器网络
|
||
除了用户定义的网络外,您还可以使用 `--network container:<name|id>` 标志格式将容器直接附加到另一个容器的网络堆栈上。
|
||
|
||
使用容器不支持以下标志 `container`: 网络模式
|
||
|
||
| 网络模式 | 描述 |
|
||
| - | - |
|
||
`--add-host` | `--添加主机`
|
||
`--hostname` |
|
||
`--dns` |
|
||
`--dns-search` | `--dns-搜索`
|
||
`--dns-option` | `--dns-选项`
|
||
`--mac-address` | `--mac-地址`
|
||
`--publish` | `--发布`
|
||
`--publish-all` | `--全部发布`
|
||
`--expose` | `--暴露`
|
||
|
||
以下示例运行一个 Redis 容器,并将 Redis 绑定到 `localhost`,然后运行 `redis-cli` 命令并通过 `localhost` 接口连接到 Redis 服务器。
|
||
```console
|
||
$ 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` <br> `-p 8080:80/udp` | 将 Docker 主机上的 TCP 端口 8080 映射到容器中的 TCP 端口 80,并将 Docker 主机上的 UDP 端口 8080 映射到容器中的 UDP 端口 80。
|
||
|
||
|
||
:::tip 重要
|
||
默认情况下,发布容器端口是不安全的。这意味着,当您发布容器的端口时,它不仅可供 Docker 主机使用,而且可供外部世界使用。
|
||
|
||
如果在 publish 标志中包含 localhost IP 地址(`127.0.0.1` 或 `::1`),则只有 Docker 主机及其容器可以访问已发布的容器端口。
|
||
```console
|
||
$ docker run -p 127.0.0.1:8080:80 -p '[::1]:8080:80' nginx
|
||
```
|
||
:::warning 警告
|
||
同一 L2 Segment 中的主机(例如,连接到同一 网络交换机)可以访问发布到 localhost 的端口。 有关更多信息,请参阅 [moby/moby#45610][4]
|
||
|
||
:::
|
||
|
||
如果要使容器可供其他容器访问, 无需发布容器的端口。 您可以通过将容器连接到 同一网络,通常为 [桥接网络][5]。
|
||
|
||
如果端口映射中没有给出主机 IP,桥接网络仅限 IPv4,并且 `--userland-proxy=true`(默认),则主机的 IPv6 地址上的端口将映射到容器的 IPv4 地址。
|
||
|
||
有关端口映射的更多信息,包括如何禁用它并使用 直接路由到容器,请参阅 [数据包过滤和防火墙][6]。
|
||
|
||
## IP 地址和主机名
|
||
|
||
创建网络时,IPv4 地址分配默认启用,可以使用 `--ipv4=false` 禁用它。可以使用 `--ipv6` 启用 IPv6 地址分配。
|
||
|
||
```console
|
||
$ docker network create --ipv6 --ipv4=false v6net
|
||
```
|
||
|
||
默认情况下,容器会为其附加到的每个 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` 配置文件。连接到默认桥接网络的容器会收到此文件的副本。 附加到 [自定义网络][7] 使用 Docker 的嵌入式 DNS 服务器。 嵌入式 DNS 服务器将外部 DNS 查找转发到主机上配置的 DNS 服务器。
|
||
|
||
您可以基于每个容器配置 DNS 解析,使用 `docker run` 或 `docker create` 命令来启动容器。下表描述了与 DNS 配置相关的可用 `docker run` 标志。
|
||
|
||
| Flag | 描述 |
|
||
| - | - |
|
||
|`--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` 中定义的自定义主机不会由 器皿。要将其他主机传递到容器中,请参阅 [将条目添加到容器主机文件中][8]的 `docker run` 参考文档。
|
||
|
||
## 代理服务器
|
||
如果您的容器需要使用代理服务器,请参阅 [使用代理服务器][9]。
|
||
|
||
<!-- 链接 -->
|
||
[0]:https://docs.docker.com/engine/network/packet-filtering-firewalls/
|
||
[1]:https://docs.docker.com/engine/network/drivers/
|
||
[2]:https://docs.docker.com/reference/cli/docker/container/run/
|
||
[3]:https://docs.docker.com/reference/cli/docker/network/connect/
|
||
[4]:https://github.com/moby/moby/issues/45610
|
||
[5]:https://docs.docker.com/engine/network/drivers/bridge/
|
||
[6]:https://docs.docker.com/engine/network/packet-filtering-firewalls/
|
||
[7]:https://docs.docker.com/engine/network/tutorials/standalone/#use-user-defined-bridge-networks
|
||
[8]:https://docs.docker.com/reference/cli/docker/container/run/#add-host
|
||
[9]:https://docs.docker.com/engine/daemon/proxy/ |