packer + puppet を使ってdockerのイメージを作成してみる
開発環境の構築にpackerを使うともっと楽にできるという噂を聞いたので試してみます。 最近軽く試してみる系のエントリばかりなのですが、今回もそれ系です。
packerとは
マシンイメージの構築を自動で行ってくれるツールです。HashiCorp製。
Docker の他には、AWS(AMI), VMware, VirtualBox などに対応しています。 https://www.packer.io/intro/index.html
また、Ansible・Chef・Puppetといった構成管理ツールを使って環境構築することができます。
インストール
次(以下リンク)の3つの方法で、インストールすることができます。
Install Packer - Getting Started - Packer by HashiCorp
このうち今回は、2.Installing from source This method is only recommended for advanced users.
で行いました。
実行してみる
今回はお試しなので、 puppet(Masterless)を使って、rubyがインストールされた dockerのイメージを作りました。
参考:
Puppet Masterless - Provisioners - Packer by HashiCorp
Docker - Builders - Packer by HashiCorp
できたpackerの設定はこのようになりました。
packer.json
{ "builders": [{ "type": "docker", "image": "centos:7", "export_path": "image.tar", "pull": false }], "provisioners": [{ "type": "shell", "inline": [ "rpm -q puppet5-release || rpm -Uvh https://yum.puppet.com/puppet5/puppet5-release-el-7.noarch.rpm", "rpm -q puppet-agent || yum install -y puppet-agent" ] }, { "type": "puppet-masterless", "manifest_file": "ruby.pp", "puppet_bin_dir": "/opt/puppetlabs/bin", "prevent_sudo": true }], "post-processors": [{ "type": "docker-import", "repository": "centos-ruby-image" }] }
ruby.pp
package { "ruby": provider => "yum", ensure => "latest" }
設定した内容に対して、以下でビルドを行います。
packer build packer.json
実行した結果
docker run -it centos-ruby-image /bin/bash
rubyが入ったことを確認
ruby -v ruby 2.0.0p648 (2015-12-16) [x86_64-linux]
packerを使ってみて
- Dockerfileで良いのでは?と思っていたが
今回イメージしたものくらいの範囲であれば、Dockerfileでピッと作ったほうが楽かもしれないが、環境構築に必要なタスクが多くなってくると、Dockerfileに RUN
や ADD
の嵐になりメンテもしにくくなってきてしまう。そんなとき、packerでpuppetなどの構成管理ツールを使ってイメージ化できると大変便利ということがわかった。
- ちょっと面倒なこと
しかし、packerでは、type: shell
で記述したコマンドをDockerfileのようにキャッシュしてくれないため、例えば、yum install ruby
環境を作成するとき・失敗してリトライするときは何度も実行されてしまう。
※ Dockerfileは RUN
や ADD
の内容をキャッシュしてくれている。
RUN yum install -y vim
がキャッシュされている例
docker build -t test:1 . Sending build context to Docker daemon 98.82kB Step 1/2 : FROM centos:7 ---> 1e1148e4cc2c Step 2/2 : RUN yum install -y vim ---> Using cache ---> 57027d76839e
今回は、初回簡単なイメージを作成し、次回以降生成されたイメージを使って、コマンド、manifest_file を追加していくという方法で作成したが、良い感じの作成方法・デバッグ方法があれば教えてください。
Dockerfileとの住み分け
dockerでpull したimageをちょっと変更を加えるくらいで良いケース、例えば、アーキテクチャごとにコンテナを分けて連動して使いたい場合などは、すでに各コンテナ側にミドルウェアが搭載されており、変更する箇所も少ないのでDockerfileで十分かもしれない。
逆にアプリケーション自体をコンテナ化する場合、一つのイメージにアプリケーションに必要なすべてのアーキテクチャを入れることから、ガッツリ手を入れると思うので、そういうときは、packer + 構成管理ツールで行うのが良いかと思った。
参考: