はじめに
2016.09以降のバージョンのAmazon LinuxであればDockerHubに公式イメージが公開されている。これ以降のバージョンを使用する場合には、この公式イメージを使用すれば良い。
https://hub.docker.com/_/amazonlinux/
一方、これよりも前のバージョンのAmazon Linuxを使用したい場合、他人が作成したDockerイメージか、自分でdockerイメージを作成する必要がある。
本記事では自分でdockerイメージを作成する手順を示す。
昔のAmazon Linuxで本番稼動したままバージョンを上げられずに運用しているプロジェクトで、開発環境をDocker化したいときなどに本手順が参考になると思う。
作成手順
大まかな流れは以下のようになる。
- 手順1: イメージ化したいバージョンのEC2インスタンスを作成して起動後に停止する。
- 手順2: docker化するために、最新のバージョンのEC2インスタンスを作成する。
- 手順3: イメージ化対象のEC2からEBSをデタッチし、作業用EC2インスタンスにアタッチする。
- 手順4: EBSをマウントし、不要なファイルを削除する。
- 手順5: dockerイメージを作成する。
- 手順6: dockerのイメージをファイルに書き出し
以降、2013.03
のバージョンのAmazon Linuxをdocker化する前提で記載する。
手順1: イメージ化したいバージョンのEC2インスタンスを作成して起動後に停止する。
古いバージョンのAmazon Linuxは、EC2インスタンス作成の最初の画面でコニュニティAMIタブを選択し、amzn-ami-pv
を検索すれば見付かる。
対象バージョンのAmazon Linuxのボリュームが欲しいだけなのでこのインスタンスは起動後何もせずに停止して構わない。
手順2: docker化するために、最新のバージョンのEC2インスタンスを作成する。
古いバージョンのAmazon Linuxは、EC2インスタンス作成の最初の画面でコニュニティAMIタブを選択し、amzn-ami-pv
を検索すれば見付かる。
手順1で作成したインスタンスとAvailability Zoneなどを合わせること。そうしないと、EBSをアタッチできない。
手順3: イメージ化対象のEC2からEBSをデタッチし、作業用EC2インスタンスにアタッチする。
- EC2の管理画面のサイドバーにある「ボリューム」を開く。
- 手順1で作成したEC2のEBSを選択する。
- デタッチを選択する。
- 手順2で作成したEC2のインスタンスにアタッチする。
- 手順2で作成したEC2インスタンス内で下記コマンドを実行していく。(
/data
にマウントする手順を記載している)/dev/xvdf
に関しては、環境に応じて異なる。lsblk
コマンドを実行して確認すること。
1
2
$ sudo mkdir /data
$ sudo mount /dev/xvdf /data
以下の手順では/data
にマウントしたものと仮定して説明する。
最後にアンマウントする場合には、以下のコマンドを実行すれば良い(参考)。
1
$ sudo umount -d /dev/xvdf
手順4: EBSをマウントし、不要なファイルを削除する。
不要なものの一例:
1
2
/data/var/cache/yum/*
/data/home/ec2-user
/data/var/log/*
も必要に応じて削除するか、ファイルを空にしてもよさそう(ファイルがないとエラーが発生するものもあるので空にするのが良いがちょっと面倒くさい)。
手順5: dockerイメージを作成する。
ローカル使用のイメージを作成するだけであれば、ec2-userのログだけ削除の方が良さそう。特にyumのcacheを消すと、yum関連の操作時にchecksumエラーが発生する。
- その後、以下コマンドでimageとしてimport。 t2.microインスタンスでも4分弱で終了した。
1
2
3
4
5
$ sudo yum -y install docker
$ sudo /etc/init.d/docker start
$ sudo su -
# cd /data
# tar --numeric-owner -cjp . | docker import - local/amzn:2013.03
手順6: dockerのイメージをファイルに書き出し
1
$ sudo docker save local/amzn:2013.03 | gzip - > amazonlinux-image-2013.03.tar.gz
dockerを利用するホストでdockerイメージを読み込む
後は、今ファイルに書き出したファイルをscpなどでdockerのホストにコピーしてきてイメージを読み込むだけとなる。
1
$ gzip -dc amazonlinux-image-2013.03.tar.gz | docker load
ハマりポイント
今回かなり苦労したところがある。
それは、yumでパッケージをインストールしようとすると、
1
Rpmdb checksum is invalid: dCDPT(pkg checksums)
のようなエラーが発生する。
とりあえずの回避策として、
1
RUN yum -y install {package-name} | true
Dockerfileの中に上記のように| true
を各コマンド毎に入れていけばbuildはできる(はず)だが、この対策はあまりにも酷い。
で、どうにか解決策が無いものかと思い色々と探していたところこのページを見つけた。
There is a yum patch, simply add this in your Dockerfile : RUN yum install -y yum-plugin-ovl Tested in Centos 7/6 + RHEL 7/6 http://man7.org/linux/man-pages/man1/yum-ovl.1.html Enjoy Docker/overlay :)
OverlayFS特有の問題らしく、yum-plugin-ovl
というパッケージを入れれば解決するらしい。
実際にDockerfileの最初の方(yum update
, yum install
などよりも前)に、RUN yum install -y yum-plugin-ovl
を入れたところ上記問題は解決した。
この解決策が正しい対応なのかを見るために、DockerHubに登録されている公式イメージの中を見たところ、yum-plugin-ovl
が入っていた。恐らく公式でもこの対応をしているのだろう。
自分で作成したAmazon LinuxのDockerイメージを使用するときに、Dockerfileにこのパッケージをインストールする記述を入れるのが微妙だなと思い、古いバージョンのAmazon Linuxを作成した後、停止する前にEC2上でインストールしようとしたがパッケージが見付からずインストールできなかった。
このためdockerイメージを作成した後、このパッケージをインストールしただけの状態のdockerイメージを再作成すれば良さそう。