这个问题有点老了,但是对于登陆这个页面的未来读者,我想让你知道你并不孤单,我们感受到你的痛苦。这个 API 确实和看起来一样可怕。
TL;DR 答案是“/images/create
响应格式未记录;/images/XXX/json
在您的创建调用完成后丢弃输出和查询。”
几年前我写了一些编排工具,我发现/images/create
API 非常烦人。但让我们深入了解:
- 没有记录在案的
200
响应模式;v1.19 文档仅给出了一些记录的示例。v1.37(我写这篇文章时最新的)文档甚至没有走那么远,没有提供任何详细信息。
- 响应以 发送
Transfer-Encoding: chunked
,并且发送的每条记录前面都有十六进制的字节数。这是一个低级的摘录(绕过 curl,所以我们可以看到实际通过网络发送的内容):
host-4:~ rg$ telnet localhost 2375
Trying ::1...
Connected to localhost.
Escape character is '^]'.
POST /images/create?fromImage=jenkins/jenkins:latest HTTP/1.1
Host: localhost:2375
User-Agent: foo/1.0
Accept: */*
HTTP/1.1 200 OK
Api-Version: 1.39
Content-Type: application/json
Docker-Experimental: true
Ostype: linux
Server: Docker/18.09.1 (linux)
Date: Wed, 06 Feb 2019 16:53:19 GMT
Transfer-Encoding: chunked
39
{"status":"Pulling from jenkins/jenkins","id":"latest"}
5e
{"status":"Digest: sha256:abd3e3f96fbc3445c420fda590f37e2bd3377f69affd47b63b3d826d084c5ddc"}
45
{"status":"Status: Image is up to date for jenkins/jenkins:latest"}
0
- 是的,它流式传输图像下载进度——不提供对分块记录的低级访问权限的客户端库可能只是在将数据提供给您之前将其连接起来。如您所见,API 的早期版本返回 JSON 记录,唯一的分隔符是分块传输编码,因此客户端代码收到一个未分隔的 JSON 连接块,并且必须通过跟踪 curlies/quotes/escape 字符来解析它!它已经更新为现在发出由换行符分隔的记录,但我们可以指望它们总是在那里吗?谁知道!此行为无需任何仪式即可更改,并且如果您在较新的守护程序上调用较旧版本的 API,则不会保留此行为。
- 它
200 OK
立即返回,不代表成功或失败。(考虑到调用的性质,我想它可能应该返回202 Accepted
。理想情况下,我们会得到一个Location
指向一个新 URL 的标头,我们可以用它来查询进度/状态。)
- 返回的响应数据是巨大的、垃圾邮件的,而且只是......愚蠢。如果您有一个在 TCP 上侦听的 docker 实例,请尝试
curl -Nv -X POST http://yourdocker:2375/images/create?fromImage=jenkins/jenkins:latest -o /tmp/omgwtf.txt
. 你会很惊讶。传输服务器渲染的 ASCII 条形图浪费了大量带宽!!!. 事实上,记录以三种不同的方式返回每一层的进度,作为当前和总字节数的数字字段、作为条形图以及作为具有 MB 或 GB 单位的漂亮打印字符串。为什么这不只是在客户端上呈现?好问题。
相反,您需要您的客户端解析千字节或兆字节的垃圾邮件。
- 条形图有一个随机转义的
>
字符 unicode 表示,尽管它安全地位于 JSON 字符串中。有人只是在墙上发出逃生电话,看看是什么卡住了?¯\_(ツ)_/¯
- 记录本身是相当随意的。有一个
id
字段会更改它所引用的内容,并且是了解解析人类可读字符串的记录类型的唯一方法。 Pulling from XXX
vs Pulling fs layer
vsDownloading
等等。据我所知,知道它是否完成的唯一真正方法是跟踪所有 id,并确保Pull complete
在套接字关闭时获得一个 for each。
- 您也许可以寻找,
Status: Downloaded newer image for XXX
但我不确定是否有多种可能的响应。
/images/XXX/json
正如我在开始时提到的那样,在声明完成后,您可能会获得最好的运气/images/create
。这两个调用的组合将给出一个非常可靠的指示是否/images/create
有效。
这是一个较长的串联客户端响应块,显示了几种不同的记录类型。为简洁起见编辑:
{"status":"Pulling from jenkins/jenkins","id":"latest"}
{"status":"Pulling fs layer","progressDetail":{},"id":"ab1fc7e4bf91"}
{"status":"Pulling fs layer","progressDetail":{},"id":"35fba333ff52"}
{"status":"Pulling fs layer","progressDetail":{},"id":"f0cb1fa13079"}
{"status":"Pulling fs layer","progressDetail":{},"id":"3d1dd648b5ad"}
{"status":"Pulling fs layer","progressDetail":{},"id":"a9f886e483d6"}
{"status":"Pulling fs layer","progressDetail":{},"id":"4346341d3c49"}
..
"status":"Waiting","progressDetail":{},"id":"3d1dd648b5ad"}
{"status":"Waiting","progressDetail":{},"id":"a9f886e483d6"}
{"status":"Waiting","progressDetail":{},"id":"4346341d3c49"}
{"status":"Waiting","progressDetail":{},"id":"006f2208d67a"}
{"status":"Waiting","progressDetail":{},"id":"fb85cf26717d"}
{"status":"Waiting","progressDetail":{},"id":"52ca068dbca7"}
{"status":"Waiting","progressDetail":{},"id":"82f4759b8d12"}
...
{"status":"Downloading","progressDetail":{"current":110118,"total":10780995},"progress":"[\u003e ] 110.1kB/10.78MB","id":"35fba333ff52"}
{"status":"Downloading","progressDetail":{"current":457415,"total":45344749},"progress":"[\u003e ] 457.4kB/45.34MB","id":"ab1fc7e4bf91"}
{"status":"Downloading","progressDetail":{"current":44427,"total":4340040},"progress":"[\u003e ] 44.43kB/4.34MB","id":"f0cb1fa13079"}
{"status":"Downloading","progressDetail":{"current":817890,"total":10780995},"progress":"[===\u003e ] 817.9kB/10.78MB","id":"35fba333ff52"}
{"status":"Downloading","progressDetail":{"current":1833671,"total":45344749},"progress":"[==\u003e ] 1.834MB/45.34MB","id":"ab1fc7e4bf91"}
{"status":"Downloading","progressDetail":{"current":531179,"total":4340040},"progress":"[======\u003e ] 531.2kB/4.34MB","id":"f0cb1fa13079"}
{"status":"Downloading","progressDetail":{"current":1719010,"total":10780995},"progress":"[=======\u003e ] 1.719MB/10.78MB","id":"35fba333ff52"}
{"status":"Downloading","progressDetail":{"current":3205831,"total":45344749},"progress":"[===\u003e ] 3.206MB/45.34MB","id":"ab1fc7e4bf91"}
{"status":"Downloading","progressDetail":{"current":1129195,"total":4340040},"progress":"[=============\u003e ] 1.129MB/4.34MB","id":"f0cb1fa13079"}
{"status":"Downloading","progressDetail":{"current":2640610,"total":10780995},"progress":"[============\u003e ] 2.641MB/10.78MB","id":"35fba333ff52"}
{"status":"Downloading","progressDetail":{"current":1719019,"total":4340040},"progress":"[===================\u003e ] 1.719MB/4.34MB","id":"f0cb1fa13079"}
{"status":"Downloading","progressDetail":{"current":4586183,"total":45344749},"progress":"[=====\u003e ] 4.586MB/45.34MB","id":"ab1fc7e4bf91"}
{"status":"Downloading","progressDetail":{"current":3549922,"total":10780995},"progress":"[================\u003e ] 3.55MB/10.78MB","id":"35fba333ff52"}
{"status":"Downloading","progressDetail":{"current":2513643,"total":4340040},"progress":"[============================\u003e ] 2.514M
...
{"status":"Pull complete","progressDetail":{},"id":"6d9b49fc8a28"}
{"status":"Extracting","progressDetail":{"current":380,"total":380},"progress":"[==================================================\u003e] 380B/380B","id":"6302e8b6563c"}
{"status":"Extracting","progressDetail":{"current":380,"total":380},"progress":"[==================================================\u003e] 380B/380B","id":"6302e8b6563c"}
{"status":"Pull complete","progressDetail":{},"id":"6302e8b6563c"}
{"status":"Extracting","progressDetail":{"current":1548,"total":1548},"progress":"[==================================================\u003e] 1.548kB/1.548kB","id":"7348f018cf93"}
{"status":"Extracting","progressDetail":{"current":1548,"total":1548},"progress":"[==================================================\u003e] 1.548kB/1.548kB","id":"7348f018cf93"}
{"status":"Pull complete","progressDetail":{},"id":"7348f018cf93"}
{"status":"Extracting","progressDetail":{"current":3083,"total":3083},"progress":"[==================================================\u003e] 3.083kB/3.083kB","id":"c651ee7bd59e"}
{"status":"Extracting","progressDetail":{"current":3083,"total":3083},"progress":"[==================================================\u003e] 3.083kB/3.083kB","id":"c651ee7bd59e"}
{"status":"Pull complete","progressDetail":{},"id":"c651ee7bd59e"}
{"status":"Digest: sha256:abd3e3f96fbc3445c420fda590f37e2bd3377f69affd47b63b3d826d084c5ddc"}
{"status":"Status: Downloaded newer image for jenkins/jenkins:latest"}
这段代码现在在 Internet 上运行。=8-O