【发布时间】:2018-09-04 12:28:16
【问题描述】:
我有一个测试,它启动一个 Docker 容器,执行验证(与 Docker 容器中的 Apache httpd 对话),然后停止 Docker 容器。
当我在本地运行这个测试时,这个测试运行得很好。但是当它在托管的 VSTS 上运行时,因此是一个托管的构建代理,它无法连接到 Docker 容器中的 Apache httpd。
这是.vsts-ci.yml 文件:
queue: Hosted Linux Preview
steps:
- script: |
./test.sh
这是重现问题的test.sh shell 脚本:
#!/bin/bash
set -e
set -o pipefail
function tearDown {
docker stop test-apache
docker rm test-apache
}
trap tearDown EXIT
docker run -d --name test-apache -p 8083:80 httpd
sleep 10
curl -D - http://localhost:8083/
当我在本地运行这个测试时,我得到的输出是:
$ ./test.sh
469d50447ebc01775d94e8bed65b8310f4d9c7689ad41b2da8111fd57f27cb38
HTTP/1.1 200 OK
Date: Tue, 04 Sep 2018 12:00:17 GMT
Server: Apache/2.4.34 (Unix)
Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT
ETag: "2d-432a5e4a73a80"
Accept-Ranges: bytes
Content-Length: 45
Content-Type: text/html
<html><body><h1>It works!</h1></body></html>
test-apache
test-apache
这个输出完全符合我的预期。
但是当我在 VSTS 上运行这个测试时,我得到的输出是(不相关的部分替换为…)。
2018-09-04T12:01:23.7909911Z ##[section]Starting: CmdLine
2018-09-04T12:01:23.8044456Z ==============================================================================
2018-09-04T12:01:23.8061703Z Task : Command Line
2018-09-04T12:01:23.8077837Z Description : Run a command line script using cmd.exe on Windows and bash on macOS and Linux.
2018-09-04T12:01:23.8095370Z Version : 2.136.0
2018-09-04T12:01:23.8111699Z Author : Microsoft Corporation
2018-09-04T12:01:23.8128664Z Help : [More Information](https://go.microsoft.com/fwlink/?LinkID=613735)
2018-09-04T12:01:23.8146694Z ==============================================================================
2018-09-04T12:01:26.3345330Z Generating script.
2018-09-04T12:01:26.3392080Z Script contents:
2018-09-04T12:01:26.3409635Z ./test.sh
2018-09-04T12:01:26.3574923Z [command]/bin/bash --noprofile --norc /home/vsts/work/_temp/02476800-8a7e-4e22-8715-c3f706e3679f.sh
2018-09-04T12:01:27.7054918Z Unable to find image 'httpd:latest' locally
2018-09-04T12:01:30.5555851Z latest: Pulling from library/httpd
2018-09-04T12:01:31.4312351Z d660b1f15b9b: Pulling fs layer
[…]
2018-09-04T12:01:49.1468474Z e86a7f31d4e7506d34e3b854c2a55646eaa4dcc731edc711af2cc934c44da2f9
2018-09-04T12:02:00.2563446Z % Total % Received % Xferd Average Speed Time Time Time Current
2018-09-04T12:02:00.2583211Z Dload Upload Total Spent Left Speed
2018-09-04T12:02:00.2595905Z
2018-09-04T12:02:00.2613320Z 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (7) Failed to connect to localhost port 8083: Connection refused
2018-09-04T12:02:00.7027822Z test-apache
2018-09-04T12:02:00.7642313Z test-apache
2018-09-04T12:02:00.7826541Z ##[error]Bash exited with code '7'.
2018-09-04T12:02:00.7989841Z ##[section]Finishing: CmdLine
关键是这个:
curl: (7) Failed to connect to localhost port 8083: Connection refused
10 秒应该足以让 apache 启动。
为什么curl 不能在其 8083 端口上与 Apache 通信?
附:
我知道像这样的硬编码端口是垃圾,我应该改用临时端口。我想让它首先使用硬编码端口运行,因为这比使用临时端口更简单,然后在硬编码端口工作后立即切换到临时端口。如果硬编码的端口因为端口不可用而无法工作,错误应该看起来不同,在这种情况下,docker run 应该会因为端口无法分配而失败。
更新:
为了确定,我已经使用 sleep 100 而不是 sleep 10 重新运行测试。结果不变,curl无法连接到localhost端口8083。
更新 2:
扩展脚本以执行docker logs 时,docker logs 显示 Apache 正在按预期运行。
当扩展脚本执行docker ps时,会显示如下输出:
2018-09-05T00:02:24.1310783Z CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2018-09-05T00:02:24.1336263Z 3f59aa014216 httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:8083->80/tcp test-apache
2018-09-05T00:02:24.1357782Z 850bda64f847 microsoft/vsts-agent:ubuntu-16.04-docker-17.12.0-ce-standard "/home/vsts/agents/2…" 2 minutes ago Up 2 minutes musing_booth
【问题讨论】:
-
您使用的是托管构建代理还是私有构建代理?
-
@DanielMann 好点。我正在使用托管的构建代理。我正在相应地更新问题。
-
您可以在日志中看到正在拉取镜像。恕我直言 10 秒来拉取图像、运行它并等待 https 预热可能还不够。请尝试其他睡眠值,看看会发生什么
-
@jannis 如果您查看时间戳,则在拉取图像之前 10 秒不会开始。并且不涉及https。在
docker run命令返回 之后 开始的10 秒。在我的机器上,此后不到 1 秒就可以访问端口 8083。我不明白为什么启动一个普通的 Apache 需要超过 1-2 秒。但我会尝试更长的睡眠值。 -
@jannis 我刚刚测试了 100 秒,行为是相同的。
标签: docker azure-devops azure-pipelines