Docker容器如何优雅地访问宿主机网络

# 前言

某些时候,我们会有在容器内容访问宿主机某个服务的需求,比如现在 openai 无法直接访问,需要给项目添加代理,我的 chatgpt-dingtalk (opens new window) 项目支持了通过环境变量指定代理地址。

添加方式如下:

# 运行项目

$ docker run -itd --name chatgpt -p 8090:8090 -e APIKEY=换成你的key -e MODEL="gpt-3.5-turbo" -e SESSION_TIMEOUT=600 -e HTTP_PROXY="" -e DEFAULT_MODE="单聊" --restart=always dockerproxy.com/eryajf/chatgpt-dingtalk:latest

复制

其中的 HTTP_PROXY 就是对应的代理服务。

# 方案

要解决这个问题,并且让如上命令能通用在 Linux,Mac,Windows 系统都通用,因此网上一些通过命令获取到宿主机 IP 的方案就不满足需求了,要实现这个需求,需要一点点骚操作才行。

# 方案一

使用 host 模式启动服务。

默认情况下,docker 使用的是桥接模式启动服务,即 Docker 容器将使用 Docker 自己创建的虚拟网络,Docker 容器之间可以相互通信,但是它们无法直接访问宿主机上的网络服务。Docker 容器需要通过端口映射来暴露自己的服务,以便宿主机或其他网络主机访问。

而使用 host 模式启动,Docker 容器与宿主机共享同一个网络命名空间,即 Docker 容器将直接使用宿主机的网络。这意味着 Docker 容器可以使用宿主机的 IP 地址和端口,可以直接访问宿主机上的网络服务。然而,host 模式也存在一些限制,例如 Docker 容器之间无法直接通信,Docker 容器的网络性能可能会受到影响。

所以此时启动命令可以改成下边这样:

# 运行项目

$ docker run -itd --name chatgpt  --network host -e APIKEY=换成你的key -e MODEL="gpt-3.5-turbo" -e SESSION_TIMEOUT=600 -e HTTP_PROXY="http://127.0.0.1:1080" -e DEFAULT_MODE="单聊" --restart=always dockerproxy.com/eryajf/chatgpt-dingtalk:latest

复制

这样容器就能直接访问到宿主机的 1080 了。

但是因为这种模式的局限性,因此实际生产当中几乎没有人会用这种方式,所以不推荐使用方案一,推荐方案二。

# 方案二

docker 官方提供了一种支持方案,可通过指向 host.docker.internal 来指向宿主机的 IP。参见文档:从容器连接到主机上的服务 (opens new window)

但注意,这个方案存在一个问题,那就是只支持 Mac 与 Windows 中 desktop 这种环境,并不支持在 Linux 中使用,所以不能直接使用。

于是,有人在官方提交了这个 issue:Support host.docker.internal DNS name to host (opens new window)

在其中的一个回答里,找到了一种可行方案:

按照如上说明,可以使用如下命令进行启动:

# 运行项目

$ docker run -itd --name chatgpt -p 8090:8090 --add-host="host.docker.internal:host-gateway" -e APIKEY=换成你的key -e MODEL="gpt-3.5-turbo" -e SESSION_TIMEOUT=600 -e HTTP_PROXY="http://host.docker.internal:15732" -e DEFAULT_MODE="单聊" --restart=always dockerproxy.com/eryajf/chatgpt-dingtalk:latest

复制

于是我在自己的 Mac 以及 Linux 都使用这种方案做了测试,发现是可以的。

需要注意的是,这个功能在 docker 版本过低的时候,可能支持的有问题,所以你的 docker 版本最好不低于 20。

如果使用的是docker-compose,则通过添加如下内容进行配置:

extra_hosts:
  - 'host.docker.internal:host-gateway'

复制

比如上边的项目改成docker-compose部署,就变成下边这样:

version: '3.9'
services:
  chatgpt:
    image: dockerproxy.com/eryajf/chatgpt-dingtalk:latest
    container_name: chatgpt
    environment:
      - APIKEY=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
      - MODEL="gpt-3.5-turbo-0301"
      - SESSION_TIMEOUT=600
      - HTTP_PROXY=http://host.docker.internal:15777
      - DEFAULT_MODE="单聊"
    ports:
      - "8090:8090"
    restart: always
    extra_hosts:
      - host.docker.internal:host-gateway

相关推荐

  1. Jenkins容器使用宿主Docker

    2023-12-15 22:12:03       26 阅读
  2. docker cuda 宿主访问docker 内部jupyter notebook

    2023-12-15 22:12:03       8 阅读
  3. Docker容器内部访问宿主的IP地址

    2023-12-15 22:12:03       23 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-15 22:12:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-15 22:12:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-15 22:12:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-15 22:12:03       20 阅读

热门阅读

  1. 矩阵理论及其应用邱启荣习题3.5题解

    2023-12-15 22:12:03       32 阅读
  2. Worker-Thread设计模式

    2023-12-15 22:12:03       44 阅读
  3. urllib.request --- 用于打开 URL 的可扩展库

    2023-12-15 22:12:03       36 阅读
  4. antd TreeSelect 组件如何获取父级ID

    2023-12-15 22:12:03       34 阅读
  5. jvm调优参数常用命令总结

    2023-12-15 22:12:03       42 阅读
  6. 安装dhg

    安装dhg

    2023-12-15 22:12:03      46 阅读
  7. 报表自定义导出文件名

    2023-12-15 22:12:03       45 阅读
  8. pgsql_postgresql表的继承关系查询

    2023-12-15 22:12:03       40 阅读
  9. C语言结构体小项目之通讯录代码实现+代码分析

    2023-12-15 22:12:03       35 阅读
  10. Vue3项目filter.js组件封装

    2023-12-15 22:12:03       37 阅读
  11. 矩阵求逆(C语言)

    2023-12-15 22:12:03       36 阅读