docs.dockoro.cn/docs/network/index.md

147 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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/