2014-08-30 131 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加載到碼頭中