話題の記事

Dockerイメージをchef-soloでプロビジョニングする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

DockerでコンテナイメージをbuildするときにはDockerfileにOSイメージの指定や導入パッケージ、実行したいコマンドなどを記述してパッケージングします。

このDockerfileはほぼコマンドべた書きのような形なので難しいわけでは無いのですが、実行処理が多くなればなるほど長く読みづらくしまうし、テストも大変です。また既にChefやPuppet、Ansibleなどの構成管理ツールを用いているのであれば、既存の資産をうまく流用したほうが楽が出来ます。

ということで、Dockerfileにはほとんど仕事をさせずに、Dockerfileからchef-soloをキックしてコンテナをプロビジョニングしてみました。

やってみた

ファイル構成は以下のような形です。今回はopscode謹製のbuild-essentialをレシピとして用意しました。

.
├── Dockerfile
└── chef-repo
    ├── cookbooks
    │   └── build-essential
    │       ├── attributes
    │       ├── libraries
    │       ├── metadata.json
    │       ├── metadata.rb
    │       └── recipes
    ├── nodes
    │   └── docker.json
    └── solo.rb

Dockerfileの内容は以下のとおり。ホスト側の./chef-repoディレクトリをコンテナイメージにADDして、後はchef-soloを実行しているだけです。

FROM centos

ENV CHEFHOME /chef-repo
ADD chef-repo /chef-repo

RUN curl -L http://www.opscode.com/chef/install.sh | bash
RUN cd ${CHEFHOME} && chef-solo -c ${CHEFHOME}/solo.rb -j ${CHEFHOME}/nodes/docker.json

chef-repo/solo.rbの内容は以下のとおり、cookbookのパスを指定しているだけです。

file_cache_path "/tmp/chef-solo"
cookbook_path ["/chef-repo/cookbooks"]

chef-repo/nodes/docker.jsonで実行したいレシピを指定します。今後セットアップしたい内容が変わったとしてもDockerfileを編集するのではなく、この内容を修正して使いたいレシピを増やしたり減らしたりします。

{
  "run_list" : [ "recipe[build-essential]" ]
}

ではbuildしてみます。結果は一部省略しています。

$ sudo docker build -t centos:build .
Uploading context 62.46 kB
Uploading context 
Step 0 : FROM centos
 ---> 0b443ba03958
Step 1 : ENV CHEFHOME /chef-repo
 ---> Using cache
 ---> 328c5a3b8e71
Step 2 : ADD chef-repo /chef-repo
 ---> d0cd42db8307
Step 3 : RUN curl -L http://www.opscode.com/chef/install.sh | bash
 ---> Running in d10235ae7fbb
Thank you for installing Chef!
 ---> d2aa1482b7b9
Step 4 : RUN cd ${CHEFHOME} && chef-solo -c ${CHEFHOME}/solo.rb -j ${CHEFHOME}/nodes/docker.json
 ---> Running in 92fc0a19bfbd
[2014-05-15T05:18:19+00:00] INFO: Forking chef instance to converge...
[2014-05-15T05:18:20+00:00] INFO: *** Chef 11.12.4 ***
[2014-05-15T05:18:44+00:00] INFO: Setting the run_list to ["recipe[build-essential]"] from CLI options
[2014-05-15T05:18:44+00:00] INFO: Run List is [recipe[build-essential]]
[2014-05-15T05:18:44+00:00] INFO: Run List expands to [build-essential]
[2014-05-15T05:18:44+00:00] INFO: Starting Chef Run for 5cecbeb1290c
[2014-05-15T05:18:44+00:00] INFO: Running start handlers
[2014-05-15T05:18:44+00:00] INFO: Start handlers complete.
 ---> 789e47216455
Successfully built 789e47216455
Removing intermediate container 4db1a3f2632a
Removing intermediate container d10235ae7fbb
Removing intermediate container 92fc0a19bfbd

ちゃんとbuildが通りました!

ではbuildしたイメージを使ってrunしてみます。

$ sudo docker run -i -t centos:build /bin/bash
bash-4.1# which gcc
/usr/bin/gcc
bash-4.1# which autoconf
/usr/bin/autoconf

build-essentialに含まれるパッケージがインストールされていることが分かりますね!

まとめ

以上、コネタでした。