【发布时间】:2020-03-29 14:21:18
【问题描述】:
我使用 docker-compose 来启动一些容器,作为我正在开发的应用程序的一部分。其中一个容器需要在主机上启动一个 docker swarm 服务。在适用于 Windows 的 Docker 和适用于 Mac 的 Docker 上,我可以使用 REST Api 通过使用“host.docker.internal”DNS 名称连接到主机 docker 守护程序,这非常有效。但是,如果我在 linux 上运行相同的 compose 文件,“host.docker.internal”将不起作用(但似乎它可能会出现在下一个版本的 docker 中)。更糟糕的是,在 Linux 上,我可以使用“主机”的网络模式来解决这个问题,但 Windows 或 Mac 不支持。
我该怎么做:
- 无需创建多个 docker-compose.yml 文件或不同的应用程序代码,即可创建 docker-compose 文件或构建容器化应用程序,使其根据主机平台 (windows|mac|linux) 略有不同?
- 无论主机操作系统如何,都以一致的方式访问主机 docker 守护进程?
如果重要的话,正在访问主机的 docker 守护进程的容器正在使用 docker python sdk 并在没有 TLS 的情况下通过 tcp 对 docker 进行 api 调用(这仅用于开发)。
更新解决方案详情
对于更多背景知识,有一个允许用户上传 zip 文件的 Web 应用程序 (aspnet core/C#)。除其他外,该 zip 文件包含一个导出的 docker 映像文件。在所有这些前面还有一个 nginx 容器,以允许 ssl 终止和负载平衡。 Web 应用程序拉出 docker 映像,然后使用 docker 守护进程的 http api,加载映像,重新标记映像,然后将其推送到私有 docker 存储库(该存储库在开发人员网络的某个位置运行,在 docker 外部)。之后,它将消息发布到消息队列,其中一个单独的 python 应用程序使用 python docker 库将 docker 映像部署到 docker swarm。
出于开发目的,应用程序都作为容器运行,因此需要与运行在主机上的 docker 作为独立的 swarm 节点进行交互。 SoftwareEngineer 的回答让我走上了正确的道路。我首先将主机中的 docker 套接字映射到 Web 应用程序容器中,但遇到了 .net 核心的限制,直到 .net 5 才能解决,即没有通过 unix 套接字执行 http 的干净方法。
我最终意识到 nginx 可以将代理 http 流量反向到 unix 套接字,从而解决了这个问题。我将所有容器(包括从 zip 中动态加载的 swarm 服务)设置为覆盖网络的一部分,以使它们能够相互访问,并允许我访问 http 端点以通过 http 控制主机的 docker/swarm 守护进程。
我遇到的最后一个障碍是 nginx 无法写入 /var/run/docker.sock 文件中的映射,因此我修改了 nginx.conf 以允许它在容器中以 root 身份运行。
【问题讨论】:
-
将
/var/run/docker.sock映射到/var/run/docker.sock在所有主机平台上都适用于我 -
Windows 没有任何 /var/run/docker.sock 的概念,除非有一些我不知道的新东西。
-
几分钟前,我在 wsl2 (ubuntu) 中使用 docker-desktop 完成了这项工作,效果很好。我还使用标准的 windows cli (cmd) 进行了尝试,它也可以在那里工作。我想有一些你不知道的:)
-
不幸的是,这些机器还不能访问 wsl2,该技术是否适用于 wsl(1)?
-
另外,如果映射了 /var/run/docker.sock,那么 api 调用的 uri 会是什么样子?
标签: docker docker-compose