2014-08-30 157 views
7

我想构建一个没有docker的Docker镜像。我查看了Packer,但它需要在构建器主机上安装Docker。Docker镜像格式

我看了一下Docker Registry API documentation,但这些信息似乎并不存在。

我想图像只是一个tarball,但我希望看到格式的完整规范,即需要什么样的格式,以及是否需要任何元数据文件。我可以尝试从注册表中下载图像并查看里面的内容,但没有关于如何获取图像本身的信息。

我的项目的想法是实现一个脚本,创建一个图像,我已编译并上传到注册表的atefacts。我想用OpenEmbedded来实现这个目的,本质上这是对Bitbake的扩展。

回答

4

阅读James Coyle's blog后,我发现docker savedocker load命令是我所需要的。

> docker images 
REPOSITORY   TAG     IMAGE ID   CREATED    VIRTUAL SIZE 
progrium/consul  latest    e9fe5db22401  11 days ago   25.81 MB 
> docker save e9fe5db22401 | tar x 
> ls e9fe5db22401* 
VERSION json layer.tar 

VERSION文件只包含1.0,并且json含有相当多的信息:

{ 
    "id": "e9fe5db224015ddfa5ee9dbe43b414ecee1f3108fb6ed91add11d2f506beabff", 
    "parent": "68f9e4929a4152df9b79d0a44eeda042b5555fbd30a36f98ab425780c8d692eb", 
    "created": "2014-08-20T17:54:30.98176344Z", 
    "container": "3878e7e9b9935b7a1988cb3ebe9cd45150ea4b09768fc1af54e79b224bf35f26", 
    "container_config": { 
    "Hostname": "7f17ad58b5b8", 
    "Domainname": "", 
    "User": "", 
    "Memory": 0, 
    "MemorySwap": 0, 
    "CpuShares": 0, 
    "Cpuset": "", 
    "AttachStdin": false, 
    "AttachStdout": false, 
    "AttachStderr": false, 
    "PortSpecs": null, 
    "ExposedPorts": { 
     "53/udp": {}, 
     "8300/tcp": {}, 
     "8301/tcp": {}, 
     "8301/udp": {}, 
     "8302/tcp": {}, 
     "8302/udp": {}, 
     "8400/tcp": {}, 
     "8500/tcp": {} 
    }, 
    "Tty": false, 
    "OpenStdin": false, 
    "StdinOnce": false, 
    "Env": [ 
     "HOME=/", 
     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 
     "SHELL=/bin/bash" 
    ], 
    "Cmd": [ 
     "/bin/sh", 
     "-c", 
     "#(nop) CMD []" 
    ], 
    "Image": "68f9e4929a4152df9b79d0a44eeda042b5555fbd30a36f98ab425780c8d692eb", 
    "Volumes": { 
     "/data": {} 
    }, 
    "WorkingDir": "", 
    "Entrypoint": [ 
     "/bin/start" 
    ], 
    "NetworkDisabled": false, 
    "OnBuild": [ 
     "ADD ./config /config/" 
    ] 
    }, 
    "docker_version": "1.1.2", 
    "author": "Jeff Lindsay <[email protected]>", 
    "config": { 
    "Hostname": "7f17ad58b5b8", 
    "Domainname": "", 
    "User": "", 
    "Memory": 0, 
    "MemorySwap": 0, 
    "CpuShares": 0, 
    "Cpuset": "", 
    "AttachStdin": false, 
    "AttachStdout": false, 
    "AttachStderr": false, 
    "PortSpecs": null, 
    "ExposedPorts": { 
     "53/udp": {}, 
     "8300/tcp": {}, 
     "8301/tcp": {}, 
     "8301/udp": {}, 
     "8302/tcp": {}, 
     "8302/udp": {}, 
     "8400/tcp": {}, 
     "8500/tcp": {} 
    }, 
    "Tty": false, 
    "OpenStdin": false, 
    "StdinOnce": false, 
    "Env": [ 
     "HOME=/", 
     "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 
     "SHELL=/bin/bash" 
    ], 
    "Cmd": [], 
    "Image": "68f9e4929a4152df9b79d0a44eeda042b5555fbd30a36f98ab425780c8d692eb", 
    "Volumes": { 
     "/data": {} 
    }, 
    "WorkingDir": "", 
    "Entrypoint": [ 
     "/bin/start" 
    ], 
    "NetworkDisabled": false, 
    "OnBuild": [ 
     "ADD ./config /config/" 
    ] 
    }, 
    "architecture": "amd64", 
    "os": "linux", 
    "Size": 0 
} 

layer.tar文件显示为空。所以检查了父母和祖父母,他们都没有在他们的layer.tar文件中没有文件。

所以假设4.0K是一个空的压缩包的标准尺寸:

for layer in $(du -hs */layer.tar | grep -v 4.0K | cut -f2) 
do (echo $layer:;tar tvf $layer) 
done 

地看到,这些包含在文件系统简单的增量变化。

所以一个结论是,最好只使用Docker来构建映像并将其推送到注册表中,就像Packer一样。

从头开始构建图像的方法是described in the docs。原来docker import - scratch并不关心tarball里的内容。我只是假设这是rootfs。

> touch foo 
> tar c foo | docker import - scratch 
02bb6cd70aa2c9fbaba37c8031c7412272d804d50b2ec608e14db054fc0b9fab 
> docker save 02bb6cd70aa2c9fbaba37c8031c7412272d804d50b2ec608e14db054fc0b9fab | tar x 
> ls 02bb6cd70aa2c9fbaba37c8031c7412272d804d50b2ec608e14db054fc0b9fab/ 
VERSION json layer.tar 
> tar tvf 02bb6cd70aa2c9fbaba37c8031c7412272d804d50b2ec608e14db054fc0b9fab/layer.tar  
drwxr-xr-x 0/0    0 2014-09-01 13:46 ./ 
-rw-r--r-- 500/500   0 2014-09-01 13:46 foo 

在OpenEmbedded的一体化方面,它可能是最好的打造rootfs压缩包,这是一件好事Yocto提供开箱即用,并使用official Python library导入根文件系统与import_image(src='rootfs.tar', repository='scratch')压缩包,然后将其推私有注册表的方法。

这不是最优雅的解决方案,但这是它现在需要的工作方式。否则,人们可能会以自己的方式管理和部署rootfs修订版,并且只在目标主机上使用docker import,这仍然不太合适,但有点简单。

4

泊坞窗图像格式在这里指定:https://github.com/docker/docker/blob/master/image/spec/v1.md

最简单的图像是包含tar文件如下:

repositories 
uniqid/VERSION 
uniqid/json 
uniqid/layer.tar 

其中版本包含1.0,layer.tar包含内容的chroot和JSON /存储库是上述规范中指定的JSON文件。

生成的焦油可以通过docker load < image.tar加载到码头中