マシン・イメージを自動構築し、作業効率を高めるPacker入門
Packerとは?
Packerはマシン・イメージの自動生成や管理をするコマンドライン・ツールです。Packerの背景や機能解説のほか、AWS(Amazon Web Services)とDigitalOceanで実際にPackerを使う方法、Atlasとの連携方法をご紹介します。
マシン・イメージ管理とPacker
Packerは何を解決するのか?
クラウド(IaaS)や仮想化環境を使う上で避けて通れないのが、マシン・イメージをどのように管理するべきかという課題です。ベンダーから用意されているマシン・イメージは、OS環境がほぼ初期状態のままです。その状態から、タイムゾーンや言語設定、管理用アカウントの作成、開発環境のインストール、ミドルウェアや各種サーバのセットアップなどを済ませて、実際に使える環境を整えるのに時間がかかります。
この課題を解決するのが、ある程度準備された環境をテンプレート的なマシン・イメージとして扱う「ゴールデンイメージ」を持つ考えです(図1)。ゴールデンイメージをチームや社内で共有することで、共通している環境構築の手間が省けるため。開発環境や本番環境を迅速に利用できるようになります。またそれにより、各々の担当者は本来の役割である、コーディングやテスト、運用などに専念できるようになります。
このようにマシン・イメージをテンプレートのように扱うのは便利ですが、反面マシン・イメージの作成や管理が煩雑になりがちです。例えば、Amazon Web Services(以下、AWS)の場合、EBS-Backed Linux AMI を元に自分のマシン・イメージを作るには、インスタンスを起動し、環境構築、スナップショット作成後にAMIの登録作業が必要です(図2)。この作業は、OSのバージョン変更やリージョンごとに行う必要があります。またセットアップする開発環境・ミドルウェアの環境が変わっても、この一連の作業が必要になります。
これらの一連の作業は、マシン・イメージの更新頻度は低くても面倒になりがちです。そこでPackerの出番となります。Packerは、マシン・イメージに関する面倒な問題を解決するための、コマンドライン上のツールです。PackerはVagrantと同じくHashiCorpによる開発が行われており、オープンソースとして公開されています。
Packerの特徴
Packerは、マシン・イメージに関する面倒な作業を単純化します。クラウド上のGUIを使わなくても、マシン・イメージを自動生成できます。それだけでなく、開発環境やミドルウェアやアプリケーションの設定を自動的に行う、プロビジョニング機能も備えています。また、複数のクラウド・仮想化環境のマシン・イメージを抽象化するだけでなく、並列に処理することもできるため、作業の共通化や時間短縮に役立ちます。
Packerを使ったマシン・イメージの管理には、常にPacker用のテンプレート・ファイルを使います。このファイルには、どこのクラウド環境を使うか、どのようなマシン・イメージを作成するかなどを記述します。テンプレートの内容はJSON形式のファイルのため、構成に些細な変更を加えたり、別のクラウドで同様の環境を再現したりするのも容易になります。
Packerの機能とアーティファクト
Packerは、様々なパーツによって構成されていますが、その全てを使う必要はありません。最低限必要なのはビルダー(builder)であり、これはベンダーが提供するマシン・イメージを元に、アーティファクト(artifact)を作成するものです。
アーティファクトとは、Packer独自の抽象化されたマシン・イメージの概念です。Packerを通して自動生成したマシン・イメージや管理に付随する情報が、アーティファクトと呼ばれています。アーティファクトの内容とは、利用するクラウドや仮想化システムの環境によって異なります。以下は一例です。
AWS | AMIと、AMI IDなど付属する管理情報 |
---|---|
DigitalOcean | テンプレート |
VMware | ディレクトリ内のファイル群 |
このように、それぞれの環境により最終的なマシン・イメージの形態は異なります。これらを抽象化した成果物という意味で、アーティファクトという言葉が用いられています。
Packerが持つ機能は、アーティファクトの作成だけではありません。Packerの基本機能は、前述のビルダーと呼ばれるマシン・イメージ作成・管理機能ですが、ほかにもプロビジョナー、ポスト・プロセッサーの各機能で構成されています(図3)。
それぞれの機能は、次のような役割があります。
ビルダー(builder)
Packerの主要部分であり、マシン・イメージの生成を行います。JSON形式のテンプレートを元に、特定の環境上でマシン・イメージの起動、設定適用、作成を自動的に行います。最終的に、成果物としての新しいマシン・イメージを作成します。Packerでは、これら管理情報を含めてアーティファクトと呼ばれる単位で管理できるようになります。
プロビジョナー(provisioner)
マシン・イメージの中に、ミドルウェアやアプリケーションなど、ソフトウェアのインストールや設定を自動的に行います。シェルスクリプトの自動実行のほか、構成管理ツールであるChefかPuppetを実行する機能を持ちます。既にChefやPuppetをお使いであれば、Packerで自動実行できる便利な機能です。
ポスト・プロセッサー(post-processor)
ビルダーの実行結果を元に、新しいアーティファクトを作ります。ある環境向けに作られたものをTar形式で圧縮する機能や、DockerやAtlasの環境にアップロード(プッシュ)する機能があります。
Packerの中でビルダーを使うことは必須ですが、プロビジョナーやポスト・プロセッサーは必要がなければ使わなくても構いません。作業に合致する部分、とりわけ繰り返し作業で当てはまる所があればPackerを使うことが、時間の節約や効率化につながります。こういったPackerのような提案型スタイルは、HashiCorpが提供する他のツールやサービスと同様の設計思想に基づいています。
対応しているプラットフォーム
Packerの特徴の1つとして、様々なプラットフォームに対応している点が挙げられます。AWSのAmazon EC2向けAMIのほか、DigitalOcean、Google Compute Engine、Docker、OpenStack、VirtualBox、VMware、QEMUなどの環境に対応しています。
Packerのセットアップ方法
Packerを使うためには、GitHubで配布されているソースコードからコンパイルするか、バイナリをダウンロードします。多くの環境に対応していますので、バイナリファイルのダウンロードが手軽です。
ダウンロード用URL(https://packer.io/downloads.html)から、使いたいOSやマシン環境に合わせたPackerをダウンロードします。次の手順は、Linux環境(x86_64)でPackerのセットアップを行う方法です。wgetでアーカイブを取得した後、中のバイナリを/opt/packerに展開し、パスを通しています。
$ wget -O packer_0.7.5_linux_amd64.zip https://dl.bintray.com/mitchellh/packer/packer_0.7.5_linux_amd64.zip $ unzip packer_0.7.5_linux_amd64.zip $ sudo unzip ./packer_0.7.5_linux_amd64.zip -d /opt/packer/ $ export PATH=/opt/packer:$PATH $ echo 'export PATH=/opt/packer:$PATH' >> ~/.bashrc
パスが正しく通っていれば、次のように実行してバージョン情報を確認できます。
$ packer version Packer v0.7.5
これでPackerを使う準備が整いました。
クラウド上でPackerを使うには?
ここでは、実際にDigitalOceanとAWS上で、Packerを使う方法を見ていきます。作業はコマンドライン上で行いますが、覚える項目はとても少ないですし、JSON形式のテンプレートは見慣れなくても、さほど難しいものではありません。一歩ずつ試してみましょう。
DigitalOcean上で展開する方法
Packerを使う上で、一番シンプルで分かりやすいのは、DigitalOceanを使って新しいマシン・イメージを作る方法です。DigitalOceanは、SSDの基盤上で利用できるVPSサービスで、シンプルかつ速く利用できるものとして注目されています。
DigitalOceanで提供されているマシン・イメージは、他のクラウド同様にOS環境は初期状態のままです。ドロップレット(droplet)と呼ばれる仮想サーバを起動後、初期設定を済ませたものは、スナップショットを作成できます。DigitalOceanでは、このスナップショットとして保存されたイメージを元に、新しくサーバを起動できます。
事前準備として、DigitalOceanのアカウントが必要です。それから、アクセストークンを発行します。DigitalOceanのAPI画面から「Personal Access Tokens」列にある「Generate New Token」をクリックし、「Token Name」にはPacker等を記入し、「Generate Token」をクリックすると文字列が表示されます。これがPackerで使うトークンなのでエディタ等に控えておきます。なお、実際にPackerを走らせると、課金が必要となりますので、ご注意ください。
続いて、テンプレートとなるファイルを用意します。エディタを用いて、「example.json」という名称のファイルを作成・編集します。以下の例は、Packerを使う上で基本となるテンプレートです。シンガポール・リージョン「sgp1」に、マシン・イメージはUbuntu Server 14.04 LTSの「ubuntu-14-04-x64」を使います。仮想サーバの名称は「packer-example タイムスタンプ」とします。リージョンやマシン・イメージだけでなく、名前も任意のものを使えますので、自分の環境に合わせて自由に書き換えても構いません。
ここで重要なのは「builders」と「provisioners」で囲まれた範囲です。
「builders」ではPackerのビルダーとして、どのようなマシン環境を作成するのかという挙動を指定します。この例ではDigitalOceanの環境なので「type」に「digitalocean」を記述しましたが、環境が変わる場合は他のビルダーに書き換えます(例:AWSを使う場合は、「"type": "amazon-ebs"」になります)。またオプションも変わる場合がありますので、ご注意ください。
もう一方の「provisioners」で囲まれた部分には、プロビジョナーがサーバの中で自動的に行う処理を記述します。この例ではOS起動から30秒待機し、その後シェルスクリプト上でコマンドを実行し、Apacheサーバをインストールします。ほかにChefやPuppetも使えます。もしプロビジョニングが不要であれば、provisionersの記述は不要です。プロビジョナーの詳細については、ドキュメントをご確認ください。
テンプレート作成後は、文法チェックのコマンド「packer validate 」を実行します。JSONの記法に問題がなければ、次のように問題がない旨の表示がされます。
$ packer validate example.json Template validated successfully.
次に、Packerを使って新しいイメージを自動的にビルドしてみましょう。「packer build」コマンドの引数で、JSONファイルを指定します。
$ packer build example.json digitalocean output will be in this color. ==> digitalocean: Creating temporary ssh key for droplet... ==> digitalocean: Creating droplet... ==> digitalocean: Waiting for droplet to become active... (省略) ==> digitalocean: Gracefully shutting down droplet... ==> digitalocean: Creating snapshot: packer-sample 1428040540 ==> digitalocean: Waiting for snapshot to complete... ==> digitalocean: Destroying droplet... ==> digitalocean: Deleting temporary ssh key... Build 'digitalocean' finished. ==> Builds finished. The artifacts of successful builds are: --> digitalocean: A snapshot was created: 'packer-sample xxxx' in region 'Singapore 1'
この後、自動的にドロップレットの作成、プロビジョニング(Apacheセットアップ)が進行します。その後、自動的に作業時に使ったドロップレットを停止し、テンプレートを作成した後、ドロップレットを削除します。
このようにPackerは数分間に渡る作業を自動的に行い、最終的に「packer-sample xxxx」という名称のテンプレートを作成します。これで新しくドロップレットを作成する際は、このテンプレートを元に起動できるようになります。以降は、必要に応じてビルダーやプロビジョナーの内容を書き換えることで、類似の環境を簡単に再現できます。
AWSで新しいAMI(マシン・イメージ)をビルドする方法
手作業でAMIを作成するには、イメージを起動後に環境を構築し、新しくスナップショットを作成した後に新しいAMIを登録する必要があります。Packerは、これらの手順を一括して行えます。
Packerは環境構築のためにAmazon Virtual Private Cloud(Amazon VPC)を使います。そのため、事前にAWSマネジメント・コンソールで作業用のVPC環境を用意し、VPC IDとサブネットIDを控えておきます。また事前に「aws_access_key」と「aws_secret_key」の情報を確認しておきます。また、AWS IAMの権限設定を詳細に行う場合は、Packerのドキュメントを参考にお願いします。
事前準備の後、テンプレートとなるファイルを用意します。エディタを使い、「example.json」という名称のファイルを作成・編集します。以下の例は、東京リージョン「ap-northeast-1」に、Ubuntu Server 14.04 LTSのAMI「ami-bebda6bf」を元に、インスタンス「t1.micro」で「packer-example タイムスタンプ」という名称のAMIを作成するものです。
先ほどのDigitalOceanの例と同様、「builders」で囲まれた中でPackerの挙動を指定します。今回はAWSの環境なので「type」に「amazon-ebs」を選びます。それにともない、AWS独自のVPSのオプションが増えています。またAWSの場合は、アクセスキーとシークレットキーをJSONに記述する必要はありません。
「packer validate example.json」を実行して、文法上の問題がないことを確認します。それから、AWSに新しいイメージを自動的にビルドするため、「packer build」コマンドの引数で、AWSのアクセスキーとシークレットキーを指定します。
$ packer build \ -var 'aws_access_key=<アクセスキー>' \ -var 'aws_secret_key=<シークレットキー>' \ example.json
後は自動的に処理が進行します。最終的にAWSのEC2コンソール上の「IMAGES」から「AMIs」をクリックすると「packer-example」という名称で作成されていることが分かります。
AWSを使う上で、AMIはS3に保管されるため、課金が発生します。また、Packerが作成するのはAMIだけでなく、作成過程でスナップショットも使用していますので、不要な場合はあわせて削除することにもご注意ください。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- インフラの構成管理を自動化するTerraform入門
- 開発から運用に至るフローを一体化するAtlas
- SecretもPulumiで使いこなしたい! PulumiのSecurityを試してみよう
- コード化でDevOpsを支えるHashiCorpのツールと開発背景
- 開発環境の構築・共有を簡単にするVagrant入門
- 「Pulumi Stack」とは ー Pulumiによるマルチステージ環境の構築方法
- Pulumiの最新機能「Pulumi ESC」を使ってみよう
- 3scaleの基本的な使い方
- KubernetesのConfig&Storageリソース(その1)
- Policy as Codeでインフラのコンプライアンスを自動実現! 「Pulumi CrossGuard」を活用してみよう