在远程Linux Azure托pipeDocker实例上删除未使用的Docker镜像会导致“未知的速记标志:'in -aq'错误

介绍

大家好,我使用以下指南在Azure中设置Docker机器:

  • https://blogs.msdn.microsoft.com/jcorioland/2016/08/19/build-push-and-run-docker-images-with-visual-studio-team-services/
  • https://docs.docker.com/machine/drivers/azure/

我设法使这一切都工作,当在Windows上进行构build时,我现在可以使用Linux Docker主机从创build的源创build泊坞窗镜像。 (通过将DockerHostConnnection设置为我的Linux构build机器,通过简单地使用“Docker:构build映像”步骤,然后执行“Docker:push a image”步骤:

在Azure中构建Docker镜像的步骤

但是,该过程会将创build的映像保留在磁盘上。

接下来我要做的是创build一个清理图像的夜间构build。 我基本上创build了一个新的版本,并添加了以下步骤:

  1. 在之前显示docker图像:(docker图像-a)
  2. Docker信息:(docker信息)
  3. 删除docker图像:(dockerrmi $(docker图像-aq))
  4. 泊坞窗图像后显示:(泊坞窗图像-a)

问题

每当我运行这个构build虽然我似乎收到以下错误:

错误码头-a

奇怪的是,命令“docker images -aq”在之前的步骤中工作正常:

码头图像-aq工作正常

调查

我开始通过手动启动从我自己的计算机到远程docker主机的命令进行一些调查,但是遇到与以下.cmd文件相同的问题:

docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' login -u ********** -p ********** ********** docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' images -aq docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' rmi $(docker images -a) docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' logout ********** 

.cmd文件的结果:

.cmd文件的结果

当从.cmd本地运行它时,我看到相同的错误:

本地cmd

从PowerShell运行它,但它工作正常,但:

PowerShell工作正常

编辑…(更多调查后)

使用这些知识,我将.cmd文件修改为一个似乎效果更好的.ps1文件。 一个问题是,$(docker ….)从本地docker安装中获取了它的信息。 我将脚本更改为以下版本,现在可以从本地机器运行到Azure Linux docker主机:

 docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' login -u ********** -p ********** ********** docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' images -a docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' rmi -f $(docker -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' images -aq) docker.exe -H tcp://**********:2376 --tls --tlscacert='ca.pem' --tlscert='cert.pem' --tlskey='key.pem' logout ********** 

所以基本上现在这个工作,但是,我怎么能得到这个工作与Azure的Docker构build步骤?

因为基本上Azure Docker集成步骤似乎有两个问题:

  1. 我认为命令运行CMD而不是PowerShell导致-a错误
  2. 当做类似“docker -H …. rmi $(docker images -aq)”时,第二个docker命令(docker images …)将与本地docker实例进行通信。 所以我实际上喜欢这个解决scheme,而不必手动提供IP地址和所有的证书。 (如果我找不到一个好的解决scheme,我可以用这个问题解决这个问题)

此任务不允许将一个命令的输出传送到另一个命令。 如果我们把inputps -aqf“status = exited”| ForEach-Object {docker rm -vf $ _}在任务中input其实际运行的child_process.spawn(<docker exe的path>,ps -aqf“status = exited”| ForEach-Object {docker rm -vf $ _})

整个input作为parameter passing给docker.exe,因此在同一个任务中将输出redirect到另一个可执行文件是不可能的。 即使在任务中运行另一个可执行文件也不可能 这可能是为了安全原因而devise的。

简单的cmd行也是如此。 pipe道输出是不允许的,整个“-aqf”status = exited“| ForEach-Object {docker rm -vf $ _}”作为parameter passing给docker.exe

它作为命令行运行,不支持命令嵌套,您可以使用Shell脚本任务。

类似的线程: 在VSTS / TFS中的命令嵌套

我已经修改了Docker VSTS任务来支持输出命令,以便可以链接多个Docker命令。

我已经创build了一个Github仓库,并提交了一个pull请求: https : //github.com/devedse/vsts-docker

在以下示例中,我使用输出variables首先获取Docker镜像,然后将其删除。 使用VSTS中刚刚发布的条件任务的function,我也设法使VSTS的构build跳过“删除图像”的步骤,只要没有find图像。

获取Docker镜像:

获取Docker镜像

如果有任何发现,删除Docker镜像

如果有任何发现,删除Docker镜像