探索 Docker Desktop 上的网络功能
Docker Desktop 包含内置网络功能,可帮助您将容器与主机上的服务、跨容器或通过代理和 VPN 连接。
所有平台的网络功能
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 代理支持
SOCKS(Socket Secure)是一种协议,它通过代理服务器促进客户端和服务器之间的网络数据包路由。它提供了一种增强用户和应用程序的隐私、安全和网络性能的方法。
您可以启用 SOCKS 代理支持,以允许传出请求(例如拉取镜像),并从主机访问 Linux 容器后端 IP。
要启用和设置 SOCKS 代理支持:
- 导航到设置中的资源选项卡。
- 从下拉菜单中选择代理。
- 打开手动代理配置开关。
- 在安全 Web 服务器 HTTPS 框中,粘贴您的
socks5://host:portURL。
Mac 和 Windows 的网络模式和 DNS 行为
在 Docker Desktop 4.42 版及更高版本中,您可以自定义 Docker 处理容器网络和 DNS 解析的方式,以更好地支持各种环境——从仅 IPv4 到双栈和仅 IPv6 系统。这些设置有助于防止因不兼容或配置错误的主机网络而导致的超时和连接问题。
注意这些设置可以使用 CLI 标志或 Compose 文件选项在每个网络上覆盖。
默认网络模式
选择 Docker 创建新网络时使用的默认 IP 协议。这允许您将 Docker 与主机的网络功能或组织要求对齐,例如强制执行仅 IPv6 访问。
可用选项有:
- 双栈 IPv4/IPv6(默认):支持 IPv4 和 IPv6。最灵活,适用于具有双栈网络的环境。
- 仅 IPv4:仅使用 IPv4 地址。如果您的主机或网络不支持 IPv6,请使用此选项。
- 仅 IPv6:仅使用 IPv6 地址。最适合过渡到或强制执行仅 IPv6 连接的环境。
注意此设置可以使用 CLI 标志或 Compose 文件选项在每个网络上覆盖。
DNS 解析行为
控制 Docker 如何过滤返回给容器的 DNS 记录,从而提高仅支持 IPv4 或 IPv6 环境的可靠性。此设置对于防止应用程序尝试使用实际不可用的 IP 系列进行连接特别有用,这可能会导致可避免的延迟或故障。
根据您选择的网络模式,可用选项有:
- 自动(推荐):Docker 会检测您主机的网络堆栈,并自动过滤掉不受支持的 DNS 记录类型(IPv4 的 A 记录,IPv6 的 AAAA 记录)。
- 过滤 IPv4(A 记录):阻止容器解析 IPv4 地址。仅在双栈模式下可用。
- 过滤 IPv6(AAAA 记录):阻止容器解析 IPv6 地址。仅在双栈模式下可用。
- 不过滤:Docker 返回所有 DNS 记录(A 和 AAAA),无论主机是否支持。
重要切换默认网络模式会将 DNS 过滤器重置为自动。
使用设置管理
如果您是管理员,可以使用设置管理来在开发人员的机器上强制执行此 Docker Desktop 设置。从以下代码片段中选择并将其添加到您的 admin-settings.json 文件中,或者使用管理员控制台配置此设置
双栈 IPv4/IPv6
{
"defaultNetworkingMode": {
"locked": true
"value": "dual-stack"
}
}仅 IPv4
{
"defaultNetworkingMode": {
"locked": true
"value": "ipv4only"
}
}仅 IPv6
{
"defaultNetworkingMode": {
"locked": true
"value": "ipv6only"
}
}自动过滤
{
"dnsInhibition": {
"locked": true
"value": "auto"
}
}过滤 IPv4
{
"dnsInhibition": {
"locked": true
"value": "ipv4"
}
}过滤 IPv6
{
"dnsInhibition": {
"locked": true
"value": "ipv6"
}
}不过滤
{
"dnsInhibition": {
"locked": true
"value": "none"
}
}Mac 和 Linux 的网络功能
SSH 代理转发
Docker Desktop for Mac 和 Linux 允许您在容器内使用主机的 SSH 代理。为此:
通过将以下参数添加到您的
docker run命令中来绑定挂载 SSH 代理套接字:$--mount type=bind,src=/run/host-services/ssh-auth.sock,target=/run/host-services/ssh-auth.sock在容器中添加
SSH_AUTH_SOCK环境变量:$ -e SSH_AUTH_SOCK="/run/host-services/ssh-auth.sock"
要在 Docker Compose 中启用 SSH 代理,请将以下标志添加到您的服务中:
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 地址。Docker 建议您连接到特殊的 DNS 名称 host.docker.internal,它解析为主机使用的内部 IP 地址。
您也可以使用 gateway.docker.internal 访问网关。
如果您在机器上安装了 Python,请使用以下说明作为示例,从容器连接到主机上的服务:
运行以下命令以在端口 8000 上启动一个简单的 HTTP 服务器。
python -m http.server 8000如果您安装了 Python 2.x,请运行
python -m SimpleHTTPServer 8000。现在,运行一个容器,安装
curl,然后尝试使用以下命令连接到主机:$ docker run --rm -it alpine sh # apk add curl # curl http://host.docker.internal:8000 # exit
我想从主机连接到容器
端口转发适用于 localhost。--publish、-p 或 -P 都有效。从 Linux 公开的端口将转发到主机。
Docker 建议您发布端口,或者从另一个容器连接。即使容器位于覆盖网络而非桥接网络(因为这些网络不进行路由),在 Linux 上也需要这样做。
例如,要运行 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 一起使用的发布选项的更多详细信息,请参阅运行命令。