【问题标题】:Mounting docker run in Azure Pipeline job在 Azure Pipeline 作业中安装 docker run
【发布时间】:2021-09-09 16:51:24
【问题描述】:

我正在尝试将存储库的根目录挂载到 Azure Pipeline 作业中的 docker 容器。在我的 Windows 本地上,我可以成功地将源设置为 $(pwd),但在我的 Ubuntu 托管代理上,使用 $(Build.SourcesDirectory) 时出现以下错误:

docker:来自守护进程的错误响应:类型的挂载配置无效 “bind”:绑定挂载源路径不存在:/var/vsts/28/s。

/var/vsts/28/s 的路径是正确的,请问有什么问题?

Yaml 定义:

jobs:
- job: Run
  pool:
    name: 'Docker'
  steps:
  - task: Docker@2
    displayName: Login to ACR
    inputs:
      command: login
      containerRegistry: acrServiceConnection
  - task: PowerShell@2
    inputs:
      displayName: Run pulumi go
      targetType: inline
      script: |
        docker run --rm --mount type=bind,source=$(Build.SourcesDirectory),target=/project myimage:latest

编辑:

当使用 MS 托管代理时,上述工作正常。这让我相信这是结帐地点的许可问题。对此有何建议?

在运行 ls -l 时,我在自托管和 MS 代理上得到相同的结果:

drwxr-xr-x 8 root root 4096 Sep  9 16:09 folder
-rw-r--r-- 1 root root 1347 Sep  9 16:09 file
-rw-r--r-- 1 root root  178 Sep  9 16:09 ..
-rw-r--r-- 1 root root 5457 Sep  9 16:09 ..

【问题讨论】:

  • 也许不是一个真正的答案,但你不能把项目克隆到容器中吗?因为这基本上就是您要挂载的目录中的内容。
  • 1.检查相同的管道是否适用于共享代理 - 我试过了,它工作得很好。 2. 搜索检出代码的实际目录的检出任务日志(会说:Initialized empty Git repository in /home/vsts/work/1/s/。 3. 可能是 FS 权限的问题?尝试添加一个脚本步骤,列出@987654329 中的所有文件@ 并且可能修改/删除一个文件来验证?
  • @TheFool 不幸的是,这对于我们的用例来说是不可能的。
  • @qbik 也没有迹象表明 repo 的初始化位置。详情见帖子。
  • this question 提到将--mount 更改为-v(如果路径不存在,则会尝试创建路径)。这至少应该给你一些线索 - 也许它会因不同的错误而失败,或者它会成功并创建一个空目录(然后路径错误)。

标签: docker azure-devops azure-pipelines azure-pipelines-yaml


【解决方案1】:

没有特别提到如何设置自托管代理,可以运行直接安装到VM 中的 Ubuntu 代理,也可以作为Docker container 运行。

如果代理作为 Docker 容器运行,则错误可能来自内部容器启动时它引用的路径仅存在于外部容器中,而不存在于主机上。

当您在管道中运行 Docker 容器并且在代理中执行的管道也启动了 docker 容器时,会发生以下情况

|=============================================|
|                    HOST                     |
|   |------------------------------------|    |
|   |       Outer container (Agent)      |    |  
|   |                                    |    |
|   |------------------------------------|    |
|                                             |
|   |------------------------------------|    |
|   |       Inner container (Agent)      |    |  
|   |       (Started from pipeline)      |    |
|   |------------------------------------|    |
|                                             |
|=============================================|

当一个 Docker 容器在另一个 Docker 容器中运行时,它们都使用主机的 docker 守护进程,因此所有挂载路径都引用主机,无论是从主机还是外部容器启动新容器

示例1:从宿主机挂载到外部容器的路径

docker run ... -v <path-on-host>:<path-on-outer-container> ...

示例2:从宿主机挂载到内部容器的路径

docker run ... -v <path-on-host>:<path-on-inner-container> ...

示例 2:挂载从外部容器到内部容器的路径 如果没有变通方法,就不可能从外部容器安装路径到内部容器,因为两个容器都在主机上的守护程序上运行。

可以确保主机上有一个“共享”空间,可以同时安装到外部容器和内部容器中。 (注意始终指定在主机上有效的路径,即使内部容器是从外部启动的)

另一个选项是在有关 Docker 代理的 Microsoft 文档中的 Mounting volumes using Docker within a Docker container 部分中描述的选项:

外层容器启动时声明一个ENV变量:

docker run ... --env DIND_USER_HOME=$HOME ...

在这之后,我们可以从外层启动内层容器:

docker run ... -v $DIND_USER_HOME:<path-on-inner-container> ...

【讨论】:

    【解决方案2】:

    如 cmets 中所述,这可能是权限问题。在您的编辑中,您向我们展示了文件的所有者是 root。在 Windows 中,这并不重要,因为 NTFS 不支持权限,就像它们在 Linux/ext4 上的工作方式一样,它是cannot store the permissions,所以在 Windows 上它们很可能只是被忽略了。

    按照建议,尝试在您的 docker run 前加上这样的 chown:

    sudo chown -R $USER $(Build.SourcesDirectory) && docker run ....
    

    或确保您的代码已使用正确的权限集签入 VC。

    【讨论】:

    • $USER 是空的,所以我得到“chown:‘/var/vsts/31/s’之后缺少操作数”。请注意,这在托管的 Linux 代理中确实有效。只是不在我们的自托管代理中。
    • “this”是指此解决方案或您的用例有效吗?您的构建系统是否公开了跑步者的用户名?或者也许就像将双引号更改为单引号以确保变量被延迟评估一样简单?
    猜你喜欢
    • 1970-01-01
    • 2019-06-26
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多