2014-08-30 28 views
7

Chciałbym zbudować obraz Docker bez samodociągu. Przyjrzałem się Packer, ale wymagało to zainstalowania Docker na hoście producenta.Format obrazu dokowania

Spojrzałem na Docker Registry API documentation, ale ta informacja się nie pojawia.

Domyślam się, że obraz jest po prostu archiwum, ale chciałbym zobaczyć pełną specyfikację formatu, tj. Jaki format wyjściowy jest wymagany i czy są wymagane pliki metadanych. Mógłbym spróbować pobrać obraz z rejestru i sprawdzić, co jest w środku, ale nie ma informacji, jak pobrać sam obraz.

Ideą mojego projektu jest zaimplementowanie skryptu, który tworzy obraz z atutów, które skompilowałem i przesłałem do rejestru. Chciałbym użyć OpenEmbedded do tego celu, w gruncie rzeczy byłoby to rozszerzenie na Bitbake.

Odpowiedz

4

Po przeczytaniu James Coyle's blog, stwierdziłem, że potrzebne są docker save i docker load polecenia.

> 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 

Plik VERSION zawiera tylko 1.0 i json zawiera sporo informacji:

{ 
    "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 
} 

Plik layer.tar wydaje się być pusty. Tak więc inspekcja rodzica i dziadka nie zawierała żadnego pliku w ich plikach layer.tar.

Więc zakładając, że 4.0K jest średnia wielkość dla pustego archiwum:

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

Aby zobaczyć, że zawierają one proste przyrostowych zmian w systemie plików.

Jednym z wniosków jest to, że najlepiej jest po prostu użyć Docker do zbudowania obrazu i przekazania go do rejestru, tak jak robi to Packer.

Sposób na zbudowanie obrazu od podstaw to described in the docs.

Okazuje się, że docker import - scratch nie dba o to, co znajduje się w archiwum. Po prostu zakładam, że to 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 

Pod względem OpenEmbedded integracji, to chyba najlepiej zbudować rootfs archiwum, które jest czymś Yocto zapewnia wyjęciu z pudełka i użyć official Python library importować głównego systemu plików pliku archiwum z import_image(src='rootfs.tar', repository='scratch') a następnie wcisnąć go metoda rejestru prywatnych .

To nie jest najbardziej eleganckie rozwiązanie, ale tak właśnie powinno wyglądać w tej chwili. W przeciwnym razie prawdopodobnie można po prostu zarządzać i wdrażać wersje rootfs na swój własny sposób, i po prostu użyć docker import na hoście docelowym, który nadal nie będzie pasował, ale jest nieco prosty.

4

Format obrazu Docker jest określona tutaj: https://github.com/docker/docker/blob/master/image/spec/v1.md

Najprostszy możliwy obraz jest plik tar zawierające następujące informacje:

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

Gdzie wersja zawiera 1.0, layer.tar zawiera treść chroot i json/repozytoriami są pliki JSON określone w specyfikacji powyżej.

Powstała smoła może być załadowana do doku poprzez: docker load < image.tar