ククログ

株式会社クリアコード > ククログ > LXCのテンプレートをカスタマイズする方法

LXCのテンプレートをカスタマイズする方法

最近LXC - Linux Containersで開発環境を構築したので、その作業の中からコンテナのカスタマイズについて書きます1

LXCではlxc-createコマンドでテンプレートを指定してコンテナを作成します。例えば、Fedora19のコンテナを作成するコマンドは以下の通りです。

$ sudo lxc-create -t fedora -n fedora19 -- --release 19

これで作成されるのはミニマムな環境なので、色々とパッケージを追加したりユーザを追加したり設定をしたりして使うことになります。 Chef などのプロビジョニングツールを利用して初期設定をすることもできますが、開発環境にそれらのツールを導入したくない場合もあります。

ここではFedora向けのテンプレートを改造して、パッケージを追加する方法を簡単に紹介します。

まず、実装を確認します。/usr/share/lxc/templates/lxc-fedoraの内容を確認すると、ただのシェルスクリプトであることがわかります。

このファイルの最後の方を確認すると以下のように、前の方で定義した関数を順番に実行しているだけです。全部引用すると長くなるので重要な部分のみを引用しています。

trap revert SIGHUP SIGINT SIGTERM
copy_configuration
install_fedora
configure_fedora
type /bin/systemd >/dev/null 2>&1
if [ $? -ne 0 ]; then
    configure_fedora_init
else
    configure_fedora_systemd
fi
echo "container rootfs and config created" 

これを見るとcopy_configurationで設定をコピーしてinstall_fedoraでFedoraをインストールした後configure_fedoraでFedoraの設定をしています。 最後にsystemdの有無で、設定を変えています。

順番に見ていくとcopy_configurationはコンテナの設定ファイルを所定のパスに作成しているだけなので、今回は変更する必要がありません。

install_fedoraの中では、キャッシュがあったらそれを更新(update_fedora)してから、コピー(copy_fedora)しています。 キャッシュがなればダウンロード(download_fedora)してから、コピー(copy_fedora)しています。

なので、download_fedoraの中身を見れば、どうやってカスタマイズすれば良いのかわかりそうです。

download_fedoraではyumの--installrootオプションを使ってパッケージのインストール先を変更しつつchroot環境を構築し、完成したディレクトリツリーを所定のパスに移動しています。 またFedoraのバージョンでfedora-releaseというパッケージの命名規則が変わっていますが、うまくインストールできるようにしています。

重要な部分を引用すると以下の通りです。

download_fedora()
{
    # download a mini fedora into a cache
    echo "Downloading fedora minimal ..." 
    YUM="yum --installroot $INSTALL_ROOT -y --nogpgcheck" 
    PKG_LIST="yum initscripts passwd rsyslog vim-minimal dhclient chkconfig rootfiles policycoreutils fedora-release" 
    MIRRORLIST_URL="http://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$release&arch=$arch" 

    # fedora-release-*.rpm をダウンロードしている部分は省略

    mkdir -p $INSTALL_ROOT/var/lib/rpm
    rpm --root $INSTALL_ROOT  --initdb
    rpm --root $INSTALL_ROOT -ivh $INSTALL_ROOT/fedora-release-$release.noarch.rpm
    $YUM install $PKG_LIST

    mv "$INSTALL_ROOT" "$cache/rootfs" 
    echo "Download complete." 

    return 0
}

単純に考えるとPKG_LISTに欲しいパッケージを追加すればよさそうです。しかし、それだとパッケージリストを変更して試すために毎回テンプレートを修正しなければなりません。 それは面倒なので、追加のパッケージリストは別ファイルにしてテンプレートのオプションで指定できるようにしてみます。

元にしたテンプレートをコピーして/usr/share/lxc/templates/以下に lxc-で始まる名前で置けばテンプレートとして使うことができます。 例えばlxc-fedora-customという名前でファイルを作成するとlxc-createで指定するテンプレート名はfedora-customになります。

ここではFedora向けのテンプレートをコピーしたものに機能を追加します。

差分はこうなります。

--- lxc-fedora  2014-04-28 11:38:41.960333132 +0900
+++ lxc-fedora-custom      2014-04-28 12:18:29.650862732 +0900
@@ -178,6 +178,12 @@
         return 1
     fi

+    if [ ! -z "$package_list" ]; then
+        echo "Install extra packages" 
+        $YUM groupinstall $(grep -E "^@" "$package_list" | sed -e "s,^@,,")
+        $YUM install $(grep -v -E "^(#|@)" "$package_list")
+    fi
+
     mv "$INSTALL_ROOT" "$cache/rootfs" 
     echo "Download complete." 

@@ -322,12 +328,13 @@
   -c,--clean        clean the cache
   -R,--release      Fedora release for the new container. if the host is Fedora, then it will defaultto the host's release.
   -A,--arch         NOT USED YET. Define what arch the container will be [i686,x86_64]
+  --package-list    Path to package list file
   -h,--help         print this help
 EOF
     return 0
 }

-options=$(getopt -o hp:n:cR: -l help,path:,name:,clean,release: -- "$@")
+options=$(getopt -o hp:n:cR: -l help,path:,name:,clean,release:,package-list: -- "$@")
 if [ $? -ne 0 ]; then
     usage $(basename $0)
     exit 1
@@ -342,6 +349,7 @@
         -n|--name)      name=$2; shift 2;;
         -c|--clean)     clean=$2; shift 2;;
         -R|--release)   release=$2; shift 2;;
+        --package-list) package_list=$2; shift 2;;
         --)             shift 1; break ;;
         *)              break ;;
     esac

1行に1つパッケージ名を書いたテキストファイルを用意して --package-list オプションに指定すれば追加のパッケージをインストールしたコンテナを簡単に作ることができます。

このパッチをあてたテンプレートは以下のように利用します。

$ sudo lxc-create -t fedora-custom -n my-fedora19 -- --release 19 --package-list packages.txt

追加のパッケージをインストールする以外にも様々なカスタマイズが考えられます。

  • Ubuntuのテンプレートのようにホスト側のユーザをコンテナ側にも作成して、そのユーザのホームディレクトリをバインドマウントする
  • アーキテクチャを指定できるようにする
  • mirror URLを指定できるようにする
  • 別のディストリビューションのテンプレートを作成する

まとめ

LXCのテンプレートをカスタマイズして、初期導入パッケージをカスタマイズする方法を紹介しました。

  1. LXCのバージョンは0.9系を想定していますが、0.8でも1.0でも基本的には変わりません。