Dockerコンテナイメージファイル(tar)からファイル抽出

コンテナのイメージファイル(tar)から、Dockerを使わずにファイルを抽出する方法の紹介です。

まずは、以下のpythonスクリプトを書きます。
※ 1行目の #!/usr/bin/python3 は自身のpython3のパスに適宜読み替えてください。

docker-image-extract.py

#!/usr/bin/python3

import tarfile
import json
import os
import sys

image_path = sys.argv[1]
extracted_path = sys.argv[2]

image = tarfile.open(image_path)
manifest = json.loads(image.extractfile('manifest.json').read())

for layer in manifest[0]['Layers']:
    print('Found layer: %s' % layer)
    layer_tar = tarfile.open(fileobj=image.extractfile(layer))

    for tarinfo in layer_tar:
        print('  ... %s' % tarinfo.name)
        if tarinfo.isdev():
            print('  --> skip device files')
            continue

        dest = os.path.join(extracted_path, tarinfo.name)
        if not tarinfo.isdir() and os.path.exists(dest):
            print('  --> remove old version of file')
            os.unlink(dest)

        layer_tar.extract(tarinfo, path=extracted_path)

busyboxのコンテナイメージファイル busybox.tar の中身を busybox-image-files ディレクトリ名配下に抽出します。以下のようにコンテナ内の全ファイルが抽出されます。

# ./docker-image-extract.py busybox.tar busybox-image-files
Found layer: df8698476c65c2ee7ca0e9dbc2b1c8b1c91bce555819a9aaab724ac64241ba67.tar.gz
… bin
… bin/[
… bin/[[
… bin/acpid
… bin/add-shell
… bin/addgroup
… bin/adduser
… bin/adjtimex
… bin/ar
… bin/arch
~省略~
… var
… var/spool
… var/spool/mail
… var/www

このような感じでファイルが抽出されました。

# ls -l busybox-image-files/
total 40
drwxr-xr-x 2 root root 12288 Sep 25 22:31 bin
drwxr-xr-x 2 root root 4096 Sep 9 03:09 dev
drwxr-xr-x 3 root root 4096 Sep 25 22:31 etc
drwxr-xr-x 2 nobody nobody 4096 Sep 9 03:09 home
drwx------ 2 root root 4096 Sep 9 03:09 root
drwxrwxrwt 2 root root 4096 Sep 9 03:09 tmp
drwxr-xr-x 3 root root 4096 Sep 25 22:31 usr
drwxr-xr-x 4 root root 4096 Sep 25 22:31 var

参考 : https://www.madebymikal.com/quick-hack-extracting-the-contents-of-a-docker-image-to-disk/

タイトルとURLをコピーしました