一个在 OSX 环境下下通过 IP 访问 Docker 容器的解决方案
不建议使用这种方式,它实现起来不算方便,且实现后还需要配置终端的代理设置,在这里推荐我写(抄)的项目,虽然需要在本机安装额外的依赖,但是配置完后就基本无感知了!
如果是 VSCode 或 JetBrain 家的 IDE,也可以将项目部署到 container 内。
MacOS(以及 Windows)上的 Docker 由于实现方式的原因,在网络配置上有许多限制,最麻烦的地方是无法通过容器的 IP 直接访问 IP,这在搭建分布式系统环境时会造成很多麻烦。我经过一些研究,发现可以使用 Docker 提供的(实验性的)socksProxyPort
配置和系统的 proxy 配置来使对特定网段的请求路由到 container。
原理
配置 Docker 的socksProxyPort
后,对该端口的请求将会被路由到 Container 中,因此我们可以通过配置代理让对特定网段如172.172.0.0/16
的请求代理到127.0.0.1:socketProxyPort
,让 Docker 引擎帮我们路由到具体的容器中。
这里的代理配置我们使用 Mac 的 PAC 配置进行实现,考虑到 Mac 暂时不支持从文件系统读取 PAC 文件,我们需要某种渠道将该文件托管到特定服务器中,这里使用 Mac 自带的 apache 的服务器(使用 nginx,nodejs 的 http-server 等也行)。
材料
- Docker 环境
- apache HttpServer(Mac 自带)
- 爱
配置 Docker
我们首先需要配置 Docker 中的socksProxyPort
配置项,该配置文件位于~/Library/Group\ Containers/group.com.docker/settings.json
,可通过搜索找到socksProxyPort
项,其默认值为 0,修改其为想要使用的端口,这里使用8888
。
编写 PAC 文件
然后我们编写一个 PAC 文件 来配置代理信息,PAC 文件使用 js 编写,下面的代码是一个可直接使用的例子,它假设要使用的 Docker 容器占据的网段为172.172.0.0/16
。
1 |
|
isInNet(host, '172.172.0.0', '255.255.0.0')
检查请求的地址是否满足172.172.*.*
,如果满足(说明是对 Docker 容器的访问),则将其通过 SOCKS5 代理路由到127.0.0.1:8888
,即 Docker 中配置的socksProxyPort
端口。
如果不满足,则将该请求直接“放行”。
编写完成 PAC 文件后,将其保存在/Library/WebServer/Documents
目录下,假设文件名称为docker.pac
。
配置 HttpServer 的端口和 type
HttpServer 默认使用 80 端口,这对我们来说可能会造成一些麻烦,所以我们应修改该端口。
只需编辑/etc/apache2/httpd.conf
,搜索Listen
,把那一堆奇怪的 XML 标签删掉,改成Listen 你想用的端口
就行,这里使用11451
(可惜只有 5 位!)。
这里同时还需为 pac 文件配置 type,如果没有该配置,该文件可能会不被识别,最终配置见下。
1 |
|
启动 HttpServer
我们首先使用如下命令启动 HttpServer 服务——
1 |
|
然后使用curl
测试一下是否启动了,如果这个命令正确返回了我们编写的 pac 文件的信息就说明启动成功。
如果没启动,请百度😂。
1 |
|
配置系统的 PAC 配置
前往System Preferences
-> Network
-> Advanced
-> Proxy
,勾选Automatic Proxy Configuration
,在 URL 中填入地址localhost:11451/docker.pac
。
测试
我们首先创建一个 Docker 的子网,再在该子网中创建一个 nginx 容器来检查能否通过 IP 进行访问。
1 |
|
在浏览器中访问172.172.0.101
(或者使用终端),如果出现 nginx 界面则配置成功。
https_proxy=http://127.0.0.1:7890
http_proxy=http://127.0.0.1:7890
all_proxy=socks5://127.0.0.1:7890
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 协议 ,转载请注明出处!