如何在 Windows 上安装 docker 套接字?

Posted

技术标签:

【中文标题】如何在 Windows 上安装 docker 套接字?【英文标题】:How do you mount the docker socket on Windows? 【发布时间】:2019-12-19 08:25:05 【问题描述】:

我正在尝试使仅在 Unices 上开发的应用程序在 Windows 上运行。它都是 dockerized 并且它使用 traefik 负载均衡器。用于运行 traefik 的 docker 卷如下所示:

volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro,delegated
- $PWD/load_balancer/traefik.toml:/etc/traefik/traefik.toml:ro,delegated

第一卷在 Mac 或 Linux 上运行良好,但在 Windows 上可以吗? The application is failing (the load balancer is giving a 404) 可能与该卷有关。当我启动图像时,套接字看起来像一个套接字:

/ # ls -laF /var/run/docker.sock
srw-rw----    1 root     root             0 Sep  2 11:04 /var/run/docker.sock=

这行得通吗?有什么方法可以测试吗?这样做的正确方法是什么?

试图弄清楚这一点,我尝试用这个替换它:

volumes:
- //./pipe/docker_engine:/var/run/docker.sock

基于我在网上找到的各种文章和错误报告。 docker 镜像启动,但以同样的方式失败,现在在 docker 容器中它看起来像一个目录:

/ # ls -laF /var/run/docker.sock
total 4
drwxr-xr-x    2 root     root            40 Sep  3 14:52 ./
drwxr-xr-x    1 root     root          4096 Sep  3 14:57 ../

按照 Marc ABOUCHACRA 的回答,我尝试了:

volumes:
- type: npipe
  source: ////./pipe/docker_engine
  target: /var/run/docker.sock
  consistency: delegated

但这也看起来像一个目录:

/ # ls -laF /var/run/docker.sock
total 4
drwxr-xr-x    2 root     root            40 Sep  3 14:52 ./
drwxr-xr-x    1 root     root          4096 Sep  3 14:57 ../

我也试过这个:

volumes:
- npipe:////./pipe/docker_engine:/var/run/docker.sock:ro,delegated

但失败并出现此错误:

ERROR: Volume npipe:////./pipe/docker_engine:/var/run/docker.sock:ro,delegated has incorrect format, should be external:internal[:mode]

整个docker-compose.yml 部分如下所示:

  lb:
    image: load-balancer
    build: $WORKSPACE/go-home/load_balancer
    ports:
    - 80:80
    - 443:443
    links:
    - wifi-ui-dev
    - wifi-ui-prod
    - portal
    - wifi-api
    env_file:
    - .env
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock:ro,delegated
    - $PWD/load_balancer/traefik.toml:/etc/traefik/traefik.toml:ro,delegated

我的问题是关于在 Windows 主机上运行这个 Docker 映像,它是一个 Linux,运行 Docker for Windows。我知道我可以通过在另一台机器上安装 Linux 或在 Windows 机器上安装 VM 来在 Linux 主机上运行它,这是等效的。运行 Windows 来宾也不是我所追求的,以防万一有办法将套接字从 Windows 公开到 Windows。

【问题讨论】:

这有帮助吗? github.com/docker/for-win/issues/1829, github.com/MicrosoftDocs/Virtualization-Documentation/issues/… @TarunLalwani:那是我了解 /pipe/docker_engine 的地方,但两个链接都没有提到 volumes:,所以我不确定语法是什么。该语法不会崩溃,但我不确定它是否也有效(docker 映像不工作,但我现在不知道这是否与套接字或其他东西有关)。 ***.com/questions/36765138/… 能否提供整个 docker 文件,以便我们尝试弄清楚? 我认为该术语具有误导性——您绑定一个套接字并装载一个卷。您是否要安装卷?对于非常利基的任务,例如从容器管理 docker 守护程序作为 CI/CD 管道工具的一部分,可能需要绑定到 docker 套接字。如果你正在挂载一个卷,特别是你试图从容器中访问主机的目录,那么在 Windows 上有几种方法可以做到这一点。最简单的是通过 WSL?然后您可以保持所有 compose/dockerfiles 原样。如果你不能,那么你可以使用 powershell 中的 windows 路径,但你必须共享 【参考方案1】:

如果你在windows上遇到如下错误:

无法为服务搬运工创建容器:无法识别的卷规范:无法映射文件“\.\pipe\docker_engine”。此平台只能映射目录 错误:启动项目时遇到错误。

尝试在其中添加一个额外的斜线,从而产生以下卷部分:

volumes:
  - source: \\.\pipe\docker_engine\
    target: \\.\pipe\docker_engine\
    type: npipe

使用 compose 3.7 和 docker CE 19.03.12 测试

【讨论】:

非常感谢!终于让我的容器运行了:)【参考方案2】:

如果您不能也不想使用网络套接字,那么您可以使用命名管道。 语法取决于您运行的是 Linux 容器还是 Windows 容器以及您使用的 shell。

Linux 容器

如果您在 Windows 机器上运行 Linux 容器,这似乎可以使用 Powershell 或 bash:

docker run --rm -it -v "//var/run/docker.sock://var/run/docker.sock" image_with_docker docker version

请注意/var/run/docker.sock 前面的额外/,用于源卷和目标卷。

Windows 容器

如果您在 Windows 机器上运行 Windows 容器,这似乎可以使用 Powershell 或 bash:

docker run -v "//./pipe/docker_engine://./pipe/docker_engine" --rm -it image-with-docker docker version

请注意,这仅适用于 Powershell:

docker run -v "\\.\pipe\docker_engine:\\.\pipe\docker_engine" --rm -it image-with-docker docker version

因此,最好使用带有/的版本。

额外 - docker-compose.yml

如果您使用 docker-compose.yaml 文件,这适用于 Windows 容器。

version: '3.7'

services:
  docker:
    image: image-with-docker
    command:
      - docker
      - version
    volumes:
      - type: npipe
        source: \\.\pipe\docker_engine
        target: \\.\pipe\docker_engine

对于 Linux 容器,您可以使用缩写形式:

  docker:
    image: image-with-docker
    command:
      - docker
      - version
    volumes:
      - //var/run/docker.sock://var/run/docker.sock

额外 - Kubernetes

如果您在 Kubernetes 的 Windows 节点上运行 Windows 容器,这似乎可行:

apiVersion: v1
kind: Pod
spec:
  containers:
    - name: docker
      image: image-with-docker
      command:
        - powershell
      args:
        - Start-Sleep
        - "999999"
      volumeMounts:
        - mountPath: \\.\pipe\docker_engine
          name: dockersock
  volumes:
    - name: dockersock
      hostPath:
        path: \\.\pipe\docker_engine
        type: null
  nodeSelector:
    kubernetes.io/os: windows

在这种情况下,除了使用\外,请注意dockersock卷定义中的type: null:如果不设置,它将不起作用。

注意事项

一切都在 docker 19.03 和 Kubernetes 1.18 上进行了测试。

Client:
 Version:           19.03.3
 API version:       1.40
 Go version:        go1.12.10
 Git commit:        2355349d-
 Built:             10/14/2019 16:41:26
 OS/Arch:           windows/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.8
  API version:      1.40 (minimum version 1.24)
  Go version:       go1.12.17
  Git commit:       afacb8b
  Built:            Wed Mar 11 01:37:20 2020
  OS/Arch:          windows/amd64
  Experimental:     false

【讨论】:

【参考方案3】:

无法对绑定挂载类型使用短语法:npipe:////./pipe/docker_engine:/var/run/docker.sock:ro,delegated

您需要在撰写文件中使用长语法:

volumes:
  - type: npipe
    source: ////./pipe/docker_engine
    target: /var/run/docker.sock
    consistency: delegated

您可以在official documentation 中找到一些关于长语法的文档。此语法来自 v3.2

还要记住@lucas-ramage 所说的仅在使用 npipe 时才使用 windows 容器

【讨论】:

那么,npipe 只有在 guest 是 Windows docker 镜像时才有效? 是的(至少,文档是这么说的)。如果您使用的是 Docker for Windows,那么您应该使用 npipe(仅适用于 windows 容器),或者您可以通过 TCP 套接字 进行连接。你可以找到(真的很轻)文档here 当我使用这个解决方案时,socket 看起来就像 Docker 容器内的一个文件夹。我用相关信息更新了问题。【参考方案4】:

根据Docker for Windows FAQ,

在 Docker Desktop for Windows 上,客户端可以通过命名管道连接到 Docker 引擎:npipe:////./pipe/docker_engine

另见issue on GitHub,

windows 版本的 docker 不使用 unix socket (/var/run/docker.sock),而是使用 npipe (npipe:////./pipe/docker_engine)。所以你要么

切换到 linux 容器,该容器在带有 unix 套接字的完全虚拟化 linux 中运行 docker 将 npipe 而不是 unix 套接字传递给容器(仅限 Windows 容器) 使用网络套接字(应该适用于 linux 和 windows 容器)

但是,由于这是一个 Linux 容器,您的选择是 A) 在虚拟机中运行 docker(上面的首选),或 B) 使用网络套接字(第三个选项)。

【讨论】:

感谢您的回答。我确实尝试通过命名管道但它不起作用。 Docker 不喜欢这种语法,我不确定正确的语法是什么。我不知道如何使用网络套接字来实现相同的目标。有什么想法吗?

以上是关于如何在 Windows 上安装 docker 套接字?的主要内容,如果未能解决你的问题,请参考以下文章

『中级篇』如何在window上安装docker

如何在Window 10上安装Docker

无法创建服务器 TCP 监听套接字 *:6383 绑定:无法在 docker 上的 redis 集群中分配请求的地址(在 Windows 中)

如何在 Windows 上通过 Kitematic 使用 Docker

如何在docker中运行windows

如何安装一个新的应用 windows docker