packer + puppet を使ってdockerのイメージを作成してみる

開発環境の構築にpackerを使うともっと楽にできるという噂を聞いたので試してみます。 最近軽く試してみる系のエントリばかりなのですが、今回もそれ系です。

packerとは

マシンイメージの構築を自動で行ってくれるツールです。HashiCorp製。

www.packer.io

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に RUNADD の嵐になりメンテもしにくくなってきてしまう。そんなとき、packerでpuppetなどの構成管理ツールを使ってイメージ化できると大変便利ということがわかった。

  • ちょっと面倒なこと

しかし、packerでは、type: shell で記述したコマンドをDockerfileのようにキャッシュしてくれないため、例えば、yum install ruby 環境を作成するとき・失敗してリトライするときは何度も実行されてしまう。

※ Dockerfileは RUNADD の内容をキャッシュしてくれている。

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 + 構成管理ツールで行うのが良いかと思った。

参考:

マシン・イメージを自動構築し、作業効率を高めるPacker入門 | Think IT(シンクイット)

Dockerfile の代わりに Packer を使って Docker に再々入門してみている - えいのうにっき