在 Docker Desktop 中探索网络功能

Docker Desktop 提供了多种网络功能,以方便使用。

所有平台的网络功能

VPN旁路

Docker Desktop 的网络功能可在连接 VPN 时正常工作。为此, Docker Desktop 会拦截容器的流量,并将其注入主机, 仿佛该流量源自 Docker 应用程序本身。

端口映射

当您使用 -p 参数运行容器时,例如:

$ docker run -p 80:80 -d nginx

Docker Desktop 会将容器内运行在 80 端口上的服务(本例中为 nginx)映射到 localhost 的 80 端口。在此示例中,主机端口与容器端口相同。例如,如果您已在主机机器的 80 端口上运行了其他服务,则可将容器连接到其他端口:

$ docker run -p 8000:80 -d nginx

现在,对 localhost:8000 的连接将被转发到容器中的端口 80。-p 的语法为 HOST_PORT:CLIENT_PORT

HTTP/HTTPS 代理支持

请参阅 代理

SOCKS5 代理支持

自 Docker Desktop 版本 4.28.0 起引入

注意

需要商业订阅。

SOCKS(Sockets 安全协议)是一种协议,可在客户端与服务器之间通过代理服务器实现网络数据包的路由转发。该协议能够为用户和应用程序提供增强的隐私性、安全性以及网络性能。

您可以启用 SOCKS 代理支持,以允许发出出站请求(例如拉取镜像),并从主机访问 Linux 容器后端 IP。

启用并设置 SOCKS 代理支持:

  1. 设置 中导航至 资源 选项卡。
  2. 从下拉菜单中选择 代理
  3. 打开手动代理配置开关。
  4. 安全 Web 服务器 HTTPS框中,粘贴您的socks5://host:port URL。

适用于 Mac 和 Linux 的网络功能

SSH 代理转发

Mac 和 Linux 上的 Docker Desktop 允许您在容器内使用主机的 SSH 代理。操作步骤如下:

  1. 通过在您的 docker run 命令中添加以下参数,将 SSH agent 套接字进行绑定挂载:

    $--mount type=bind,src=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-auth.sock
    
  2. 在您的容器中添加 SSH_AUTH_SOCK 环境变量:

    $ -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock"
    

要在 Docker Compose 中启用 SSH agent,请在您的服务中添加以下标志:

services:
 web:
   image: nginx:alpine
   volumes:
     - type: bind
       source: /run/host-services/ssh-auth.sock
       target: /run/host-services/ssh-auth.sock
   environment:
     - SSH_AUTH_SOCK=/run/host-services/ssh-auth.sock

已知限制

更改内部 IP 地址

Docker 使用的内部 IP 地址可通过 设置 进行修改。更改 IP 后,需要重置 Kubernetes 集群,并退出任何已激活的 Swarm 集群。

主机上不存在 docker0 网桥

由于 Docker Desktop 中网络的实现方式,您无法在主机上看到 docker0 接口。该接口实际上位于虚拟机内部。

我无法ping通我的容器

Docker Desktop 无法将流量路由到 Linux 容器。不过,如果您是 Windows 用户,您可以 ping Windows 容器。

不支持每个容器单独分配IP地址

这是因为 Docker bridge 网络无法从主机访问。 不过,如果您使用的是 Windows,Windows 容器支持为每个容器分配独立的 IP 地址。

使用场景与变通方案

我想从容器连接到主机上的服务

主机的 IP 地址可能会发生变化,或者如果没有网络连接则没有 IP 地址。 我们建议您连接到特殊的 DNS 名称 host.docker.internal, 该名称会解析为主机使用的内部 IP 地址。

您还可以通过 gateway.docker.internal 访问网关。

如果您已在本机安装了 Python,请使用以下说明作为示例,从容器连接到主机上的服务:

  1. 运行以下命令以在端口 8000 上启动一个简单的 HTTP 服务器。

    python -m http.server 8000

    如果您已安装 Python 2.x,请运行 python -m SimpleHTTPServer 8000

  2. 现在,运行一个容器,安装 curl,并尝试使用以下命令连接到主机:

    $ docker run --rm -it alpine sh
    # apk add curl
    # curl http://host.docker.internal:8000
    # exit
    

我想从主机连接到容器

端口转发适用于 localhost--publish-p-P,这些值均有效。 从 Linux 发出的端口将被转发到宿主机。

我们建议您发布一个端口,或从另一个容器进行连接。即使在 Linux 上,如果容器位于覆盖网络(overlay network)而非网桥网络(bridge network),也必须执行此操作,因为覆盖网络不可路由。

例如,运行一个 nginx Web 服务器:

$ docker run -d -p 80:80 --name webserver nginx

为澄清语法,以下两条命令均将容器的端口 80 映射到主机的端口 8000

$ docker run --publish 8000:80 --name webserver nginx

$ docker run -p 8000:80 --name webserver nginx

要发布所有端口,请使用 -P 标志。例如,以下命令 以分离模式启动一个容器,并使用 -P 标志将容器的所有暴露端口映射到主机上的随机端口。

$ docker run -d -P --name webserver nginx

或者,您也可以使用 主机网络 让容器直接访问主机的网络堆栈。

有关与 docker run 一起使用的发布选项的更多详细信息,请参见 run 命令