9
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Dockerコンテナ上でイメージファイルをマウントする

3行まとめ

  1. partedコマンドでバイト単位のパーティション開始位置を確認する。
  2. docker container runコマンドに--privilegedオプションを付加する。
  3. mount --options loop,offset=[オフセット値] [イメージファイル] [マウント先]でマウントする。

1. 概要

 Dockerコンテナ内でイメージファイル(例えばOSイメージ)をマウントしたいことがあります。
毎回似たようなことを調べているので、整理も兼ねて具体例をここに記しておきます。

2019年9月11日12時55分追記: mt08さんからのコメントによると、Raspbianは公式のルートファイルシステムが別途配布されているとのことです。そのため、Raspbianを対象にこれらを行うことにはほとんど意味がありませんが、他のイメージファイルでは有用かと思います。

2. 環境

 今回試した環境は以下の通りです。

  • OS: Ubuntu 16.04.5 LTS
  • Docker: 18.09.4
host$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.5 LTS"

host$ docker version
Client:
 Version:           18.09.4
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        d14af54
 Built:             Wed Mar 27 18:34:51 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.4
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       d14af54
  Built:            Wed Mar 27 18:01:48 2019
  OS/Arch:          linux/amd64
  Experimental:     false

3. 対象イメージ

 今回の対象イメージは、Raspberry Pi用のLinuxディストリビューションである「Raspbian Buster Lite」(2019-07-10版)です。
Dockerコンテナ内でダウンロードしても良いですが、試行錯誤を容易にするため、Dockerコンテナの外側でダウンロードしました。

host$ wget https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2019-07-12/2019-07-10-raspbian-buster-lite.zip
host$ ls -l 2019-07-10-raspbian-buster-lite.zip
-rw-rw-r-- 1 yuya yuya 426250971 Jul 10 09:23 2019-07-10-raspbian-buster-lite.zip

host$ sha256sum 2019-07-10-raspbian-buster-lite.zip
9e5cf24ce483bb96e7736ea75ca422e3560e7b455eee63dd28f66fa1825db70e  2019-07-10-raspbian-buster-lite.zip

host$ unzip 2019-07-10-raspbian-buster-lite.zip
host$ sha256sum 2019-07-10-raspbian-buster-lite.img
cce3cdaa078597d0b2181f7e121a452346c72bca9095893e56e01c82e524c276  2019-07-10-raspbian-buster-lite.img

4. Dockerコンテナ内でのマウント

 今回はUbuntu 18.04のDockerコンテナ上で作業を行いました。
以下、Dockerホスト側のプロンプトをhost$、Dockerコンテナ内のプロンプトをdocker$で示します。

host$ docker image pull ubuntu:18.04
18.04: Pulling from library/ubuntu
Digest: sha256:d1d454df0f579c6be4d8161d227462d69e163a8ff9d20a847533989cf0c94d90
Status: Image is up to date for ubuntu:18.04

host$ docker container run --interactive --tty --rm --privileged \
  --volume $(pwd):/workspace \
  ubuntu:18.04

 まず、イメージファイルに含まれるパーティションと、その位置(オフセット)を確認します。
今回のイメージには2つのパーティション(FAT32とext4)が含まれており、2つ目のパーティションが目的のパーティションです。このパーティションのStartの値(今回は276824064)を控えておきます。

 partedではなくfdiskでも確認できますが、セクタ単位で表示されるためバイト単位に換算が必要です。partedであればバイト単位で表示できます。

docker$ apt-get update && apt-get install --yes --no-install-recommends parted
docker$ parted /workspace/2019-07-10-raspbian-buster-lite.img unit B print
Model:  (file)
Disk /workspace/2019-07-10-raspbian-buster-lite.img: 2197815296B
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start       End          Size         Type     File system  Flags
 1      4194304B    272630271B   268435968B   primary  fat32        lba
 2      276824064B  2197815295B  1920991232B  primary  ext4

 続いて、イメージファイルをマウントします。mountコマンドのoffset=に、先ほど控えた値(パーティションの開始位置)を指定します。
マウントが成功すると、イメージファイルの内容を確認することができます。

docker$ mkdir --parents /mnt/image
docker$ mount --options loop,offset=276824064 /workspace/2019-07-10-raspbian-buster-lite.img /mnt/image

docker$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0    7:0    0    80K  0 loop
loop1    7:1    0    80K  0 loop
loop2    7:2    0   1.8G  0 loop /mnt/image
sda      8:0    0   3.7T  0 disk
`-sda1   8:1    0   3.7T  0 part /workspace
sdb      8:16   0 232.9G  0 disk
|-sdb1   8:17   0   512M  0 part
|-sdb2   8:18   0 216.5G  0 part
`-sdb3   8:19   0  15.9G  0 part
sdc      8:32   0   2.7T  0 disk
sdd      8:48   0 489.1G  0 disk
`-sdd1   8:49   0   489G  0 part /etc/hosts
sr0     11:0    1  1024M  0 rom

docker$ ls -l /mnt/image/
total 88
drwxr-xr-x  2 root root  4096 Jul 10 00:08 bin
drwxr-xr-x  2 root root  4096 Jul 10 00:20 boot
drwxr-xr-x  4 root root  4096 Jul 10 00:03 dev
drwxr-xr-x 80 root root  4096 Jul 10 00:21 etc
drwxr-xr-x  3 root root  4096 Jul 10 00:07 home
drwxr-xr-x 16 root root  4096 Jul 10 00:09 lib
drwx------  2 root root 16384 Jul 10 00:20 lost+found
drwxr-xr-x  2 root root  4096 Jul 10 00:03 media
drwxr-xr-x  2 root root  4096 Jul 10 00:03 mnt
drwxr-xr-x  3 root root  4096 Jul 10 00:07 opt
drwxr-xr-x  2 root root  4096 Jun  6 15:42 proc
drwx------  2 root root  4096 Jul 10 00:03 root
drwxr-xr-x  4 root root  4096 Jul 10 00:03 run
drwxr-xr-x  2 root root  4096 Jul 10 00:09 sbin
drwxr-xr-x  2 root root  4096 Jul 10 00:03 srv
drwxr-xr-x  2 root root  4096 Jun  6 15:42 sys
drwxrwxrwt  2 root root  4096 Jul 10 00:21 tmp
drwxr-xr-x 10 root root  4096 Jul 10 00:03 usr
drwxr-xr-x 11 root root  4096 Jul 10 00:03 var

5. 補足: --privilegedオプションについて

 docker container runコマンドに--privilegedオプションを付けない場合、以下の通りmountコマンドがエラーとなります。

host$ docker container run --interactive --tty --rm \
  --volume $(pwd):/workspace \
  ubuntu:18.04

docker$ mount -o loop,offset=276824064 /workspace/2019-07-10-raspbian-buster-lite.img /mnt/image
mount: /mnt/image: mount failed: Operation not permitted.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
9
Help us understand the problem. What are the problem?