前書き
Hashicorpによるhttps://www.packer.io/[Packer]は、複数のプラットフォームおよび環境に対して同一のマシンイメージを迅速に作成するためのコマンドラインツールです。 Packerでは、_template_と呼ばれる構成ファイルを使用して、事前構成されたオペレーティングシステムとソフトウェアを含むマシンイメージを作成します。 その後、このイメージを使用して新しいマシンを作成できます。 単一のテンプレートを使用して、実稼働環境、ステージング環境、および開発環境の同時作成を調整することもできます。
このチュートリアルでは、Packerを使用してCentOS 7でNginx Webサーバーを構成します。 次に、Packerを使用してこのDropletのスナップショットを作成し、DigitalOceanダッシュボードですぐに使用できるようにして、新しいDropletを作成できるようにします。
前提条件
Packerを起動して実行する前に、いくつかのものが必要です。
-
sudo特権を持つ非ルートユーザーで構成されたCentOS 7サーバー。これはhttps://www.digitalocean.com/community/tutorials/how-to-add-and-delete-users-に従ってセットアップできます。 on-a-centos-7-server [CentOS 7サーバーでユーザーを追加および削除する方法]。
-
*読み取り*および*書き込み*特権を持つDigitalOcean APIトークン。 トークンを取得するには、https://www.digitalocean.com/community/tutorials/how-to-use-the-digitalocean-api-v2 [DigitalOcean API v2の使用方法]を確認してください。
ステップ1-Packerのダウンロードとインストール
サーバーにログインした後、Packerバイナリパッケージをダウンロードし、現在のユーザー用にPackerをインストールし、インストールが成功したことを確認します。
システムでPackerを実行する最も簡単な方法は、Hashicorpの公式リリースhttps://releases.hashicorp.com/packer/[website]から最新のバイナリパッケージをダウンロードすることです。 執筆時点で、最新バージョンは0.12.2です。
Hashicorp Webサイトからバイナリパッケージをダウンロードするには、「+ curl +」ユーティリティを使用します。
curl -O https://releases.hashicorp.com/packer//packer__linux_amd64.zip
ダウンロードしたら、 `+ unzip `ユーティリティをインストールし、それを使用してパッケージの内容を ` / usr / local +`ディレクトリに解凍します。これは、Packerをすべてのユーザーが利用できるようにするための推奨場所です。
sudo yum install -y unzip
sudo unzip -d /usr/local packer_0.12.2_linux_amd64.zip
CentOSにはすでに「+ packer 」というプログラムが含まれており、コマンドを実行するたびに完全なパスを入力するだけですが、この問題を回避するより効率的な方法は、「 packer.io 」をマッピングするシンボリックリンクを作成することです` / usr / local / packer `へ。 次のコマンドを使用して、 ` / usr / local / bin +`フォルダーにシンボリックリンクを作成します。
sudo ln -s /usr/local/packer /usr/local/bin/packer.io
コマンドラインで「+ packer.io +」が利用できることを確認して、インストールが成功したことを確認します。
packer.io
インストールが成功すると、次の結果が出力されます。
Outputusage: packer [--version] [--help] <command> [<args>]
Available commands are:
build build image(s) from template
fix fixes templates from old versions of packer
inspect see components of a template
push push a template and supporting files to a Packer build service
validate check that a template is valid
version Prints the Packer version
これで、Packerがインストールされ、マシンで動作します。 次の手順では、プロジェクトディレクトリをセットアップし、テンプレートを構成して基本的なCentOSスナップショットを作成します。
ステップ2-DigitalOcean Builderの構成
PackerでDropletを作成し、ソフトウェアと構成ファイルをインストールしてから、そのDropletを新しいマシンの作成に使用できるイメージに変換します。 Packerは、_template_と呼ばれる構成ファイルを使用します。このファイルには、Packerにイメージの作成方法を指示するすべての詳細が含まれています。 この構成は、構成ファイルの一般的な形式であるhttps://www.digitalocean.com/community/tutorials/an-introduction-to-json[JSON]を使用して作成します。
Packer-speakでは、_builder_は、Packerで作成するイメージの設計図を含むJSONオブジェクトです。 `+ digitalocean +`ビルダーを使用して、Packerに、NYC1リージョンで起動される512 MB CentOS 7.3ドロップレットを作成するよう指示します。
このチュートリアルで作成するテンプレートおよび構成ファイルを保持する新しいディレクトリを作成して変更します。
mkdir ~/packerProject
cd ~/packerProject
プロジェクトディレクトリができたので、テキストエディタで `+ template.json +`という新しいファイルを開きます。
vi ~/packerProject/template.json
各ビルダーは、「+ template.json」の「+ builders」セクションに移動する必要があります。 ここにこのセクションを追加し、このコードをファイルに配置して、 `+ digitalocean +`ビルダーを含めます。
〜/ packerProject / template.json
{
"builders": [
{
"type": ""
}]
}
`+ type `キーは、イメージの作成に使用するBuilder Packerビルダーを定義します。 ` digitalocean +`ビルダーは、Packerがスナップショットを作成するDigitalOcean Dropletsを作成します。
Packerは、DigitalOceanのイメージを作成することを知っていますが、ビルドを完了するには、さらにいくつかのキーと値のペアが必要です。
これらのキーと値を追加して、NYC1リージョンで起動される512 MB CentOS 7ドロップレットからスナップショットを作成することにより、ドロップレットの構成を完了します。 ファイルを次のように変更します。
〜/ packerProject / template.json
{
"builders": [
{
"type": "digitalocean"
}]
}
Packerは、 `+ ssh_username +`値を使用してDropletsに接続します。 Packerが正常に機能するには、この値を「ルート」に設定する必要があります。
`+ template.json +`を保存して、テキストエディターを終了します。
上記のコードブロックには、DigitalOcean Dropletを作成するために必要な最小限の構成が含まれていますが、次の表に示すように、追加の構成オプションを使用できます。
Key | Value | Required | Description |
---|---|---|---|
|
String |
Yes |
The API token to use to access your account. It can also be specified via environment variable |
|
String |
Yes |
The name (or slug) of the base image to use. This is the image that will be used to launch a new Droplet and provision it. See https://developers.digitalocean.com/documentation/v2/#list-all-images for details on how to get a list of the the accepted image names/slugs. |
|
String |
Yes |
The name (or slug) of the region to launch the Droplet in. Consequently, this is the region where the snapshot will be available. See https://developers.digitalocean.com/documentation/v2/#list-all-regions for the accepted region names/slugs. |
|
String |
Yes |
The name (or slug) of the Droplet size to use. See https://developers.digitalocean.com/documentation/v2/#list-all-sizes for the accepted size names/slugs. |
|
String |
No |
The URL of a non-standard API endpoint. Set this if you are using a DigitalOcean API-compatible service. |
|
String |
No |
The name assigned to the Droplet. DigitalOcean sets the hostname of the machine to this value. |
|
Boolean |
No |
Set to |
|
String |
No |
The name of the resulting snapshot that will appear in your account. This must be unique. |
|
String |
No |
The time to wait, as a duration string, for a Droplet to enter a desired state (such as “active”) before timing out. The default state timeout is “6m”. |
|
String |
No |
User data to launch with the Droplet. See An Introduction to Droplet Metadata for more information. |
これで有効なテンプレートが作成されましたが、APIトークンはテンプレートにハードコーディングされています。 これは悪い習慣であり、潜在的なセキュリティリスクです。 次のステップでは、このトークンの変数を作成し、 `+ template.json +`から移動します。
ステップ3-ユーザー変数の作成と保存
Packerでは、変数の値を別のファイルに作成して保存できます。 イメージを作成する準備ができたら、このファイルをコマンドライン経由でPackerに渡すことができます。
変数を別のファイルに保存することは、機密情報や環境固有のデータをテンプレートから排除するための理想的な方法です。 これは、チームメンバーと共有したり、GitHubなどの公開リポジトリに保存したりする場合に重要です。
ローカルコピーのみを保存する場合でも、テンプレートの外部に変数を保存することはPackerのベストプラクティスです。
この情報を保存するために、 `+ packerProject +`ディレクトリで新しいJSONファイルを作成して開きます:
vi ~/packerProject/variables.json
次に、 `+ my_token +`変数を追加し、その値をDigitalOcean APIトークンに設定します。
〜/ packerProject / variables.json
{
"my_token": ""
}
`+ variables.json +`を保存して、エディターを終了します。
次に、変数を使用するようにテンプレートを構成しましょう。 `+ my_token `変数または他の変数を使用する前に、 ` template.json `ファイルの先頭にある ` variables +`セクションで変数を定義することにより、まず変数が存在することをPackerに伝える必要があります。
エディターで `+ template.json +`を開きます。
vi template.json
以前に定義した「+ builders 」セクションの上に新しい「 variables 」セクションを追加します。 この新しいセクション内で、 ` my_token +`変数を宣言し、デフォルト値を空の文字列に設定します。
〜/ packerProject / template.json
{
"builders": [
...
}
`+ variables +`セクションで定義された変数はグローバルに利用可能です。
次に、 `+ builders `セクションのAPIトークンを ` my_token +`の呼び出しに置き換えます。
〜/ packerProject / template.json
{
...
"builders": [
{
"type": "digitalocean",
"api_token": ,
...
}]
}
ご覧のとおり、ユーザー変数への呼び出しは、特定の形式を使用する必要があります: +" {{user \ `\
}} + `。 二重中括弧と同様に、引用符とバッククォートが必要です。
ファイルを保存し、エディターを終了します。
これで、基本的なスナップショットを作成する作業用テンプレートと、APIキーを保存するための個別の変数ファイルが作成されました。 イメージを検証して構築する前に、テンプレートに `+ provisioners +`セクションを追加して、イメージを作成する前にマシンにNginx WebサーバーをインストールしてセットアップするようにPackerを構成します。
手順4-プロビジョニングツールの構成
`+ provisioners +`セクションは、Packerが実行中のDropletにソフトウェアをインストールして構成してから、マシンイメージに変換する場所です。 Builderと同様に、Dropletを構成するために使用できるさまざまなタイプのプロビジョニング機能があります。
Nginxを設定するには、Packerの「+ file 」プロビジョニングツールを使用して設定ファイルをサーバーにアップロードし、「 shell 」プロビジョニングツールを使用してこれらのファイルを使用するインストールスクリプトを実行します。 ` file`プロビジョニングツールを使用すると、イメージに変換される前に、実行中のマシンとの間でファイルやディレクトリを移動できます。 `+ shell`プロビジョニングツールを使用すると、そのマシンでシェルスクリプトをリモートで実行できます。
プロビジョニングツールは、テンプレート内に表示されるのと同じ順序で実行されます。 これは、アップロードされたファイルがシェルスクリプトに必要なため、 `+ file`プロビジョニングツールを最初に置くことを意味します。
`+ template.json `の ` builders `セクションの直後に ` provisioners +`セクションを追加し、使用する2つのプロビジョニングツールを設定します。
〜/ packerProject / template.json
{
...
"builders": [
{
...
}]
}
「+ file 」プロビジョニングツールには、ローカルファイルパスを指す「 source of」と、実行中のマシン上の既存のファイルパスを指す「+ destination on」が必要です。 Packerは、既存の宛先にのみファイルを移動できます。 このため、通常はファイルを `+ / tmp +`ディレクトリにアップロードします。
ハイライトされた行を「+ template.jsonp」に追加して、「+ file」プロビジョニングツールを設定します。
〜/ packerProject / template.json
{
...
"provisioners": [
{
"type": "file"
},
...
}
次のステップで、ローカルマシンに `+ configs `フォルダーを作成します。 それを行う前に、 ` shell`プロビジョニングツールをセットアップして設定ファイルの編集を完了しましょう。
+ shell`プロビジョニングツールは、実行中のマシンに渡す必要があるスクリプトの配列を含む
+ script`キーを受け取ります。 各スクリプトは、テンプレートで指定された順序でアップロードおよび実行されます。
次に、スクリプトへのフルパスを指定して、 `+ shell +`プロビジョニングツールを設定します。
〜/ packerProject / template.json
{
...
"provisioners": [
{
"type": "file",
"source": "configs/",
"destination": "/tmp"
},
{
"type": "shell"
}]
}
スクリプトは個別にリストする必要があります。これにより、スクリプトの実行順序を制御できます。
テンプレートの `+ provisioners +`セクションが完成しました。 ファイルを保存してVimを終了します。
次に、Packerがイメージの作成に使用するシェルスクリプトと構成ファイルを作成します。
手順5-構成ファイルとインストールスクリプトの追加
適切な構成ファイルとデフォルトのWebページを備えた、完全に構成されたNginxインストールとともにイメージを出荷する必要があります。 このセクションでは、チュートリアルhttps://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-に基づいて、事前定義された構成からこれらのファイルを作成しますon-ubuntu-16-04 [Ubuntu 16.04でNginxサーバーブロック(仮想ホスト)をセットアップする方法]。Nginxの構成はこのチュートリアルの範囲外です。
単一のインストールスクリプトで処理される3つの個別の構成ファイルを作成してアップロードすることにより、サーバーにNginxをプロビジョニングします。
最初に、プロジェクトフォルダー内に新しいディレクトリを作成して、構成ファイルを保存します。
mkdir ~/packerProject/configs
`+ / configs +`に変更して、Nginx設定ファイルを作成します。
cd ~/packerProject/configs
最初に、新しいドメインから提供するデフォルトのWebページが必要です。 ファイル `+ index.html.new +`を作成します:
vi index.html.new
この新しいファイルに、次を挿入します。
〜/ packerProject / configs / index.html.new
HELLO FROM YOUR TEST PAGE
次に、ドメインのリスニングポートとWebページの場所を定義するドメインのサーバーブロックを定義するNginx構成ファイルが必要です。 `+ newDomain.conf +`というファイルを作成します:
vi newDomain.conf
このファイルに次の構成を配置します。
〜/ packerProject / configs / newDomain.conf
server {
listen 80;
listen [::]:80;
server_name ;
location / {
root /var/www/html/newDomain;
index index.html index.htm;
}
}
最後に、Nginxにドメインの構成を新しいディレクトリ `+ / etc / nginx / vhost.d / +`からロードさせます。 これは、メインのNginx設定ファイルを編集することを意味します。
`+ nginx.conf.new +`を作成します:
vi nginx.conf.new
デフォルトのNginx構成ファイルを使用しますが、特定のサイト構成が含まれるように変更します。 このファイルに次の内容を入れます。
〜/ packerProject / configs / nginx.conf.new
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
ファイルを保存して終了します。
設定ファイルを用意したら、Packerが必要なソフトウェアをインストールするために使用するスクリプトを定義しましょう。 スクリプトを保存する新しいフォルダーを作成します。
mkdir ~/packerProject/scripts
次に、この新しいディレクトリに移動して、Nginx Webサーバーをインストール、設定、有効化、起動するインストールスクリプト `+ configureNginx.sh +`を作成します。
cd ~/packerProject/scripts
vi configureNginx.sh
次のファイルをファイルに貼り付けます。作成した構成ファイルを使用して、Nginxをインストール、構成、および起動します。
〜/ packerProject / scripts / configureNginx.sh
#!/bin/bash
# Script to install Nginx and enable on boot.
# Update your system:
yum update -y
# Install EPEL Repository, update EPEL, and install Nginx:
yum install -y epel-release
yum update -y
yum install -y nginx
#Start Nginx service and enable to start on boot:
systemctl enable nginx
systemctl start nginx
# Create new 'vhost' directory for domain configuration:
mkdir /etc/nginx/vhost.d
# Create a new directory to serve new content.
mkdir -p /var/www/html/newDomain
# Create a copy of original configuration files and import configuration:
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.original
cp /tmp/nginx.conf.new /etc/nginx/nginx.conf
# Copy over the server block configuration:
cp /tmp/newDomain.conf /etc/nginx/vhost.d/newDomain.conf
# Copy over the html test page:
cp /tmp/index.html.new /var/www/html/newDomain/index.html
# Restart Nginx:
systemctl restart nginx
テンプレートが完成し、スナップショットを検証して構築する準備ができました。
ステップ6-ドロップレットの検証と構築
Packerの `+ validate +`サブコマンドを使用してテンプレートをテストします。 テンプレートが正常に検証されると、Dropletを構築してスナップショットを作成します。
プロジェクトのルートに変更します。
cd ~/packerProject
`+ validate +`サブコマンドは、有効な構文と設定オプションのテンプレートをチェックします:
packer.io validate -var-file=variables.json template.json
「+ -var-file 」フラグは「 variables.json 」を読み取り、「 template.json 」内の「 my_token +」の値を設定します。
次の出力が表示されます。
OutputTemplate validated successfully.
`+ template.json +`に問題がある場合、エラーメッセージが表示されます。 このメッセージはエラーに応じて異なりますが、ほとんどの場合、構文をダブルチェックしてタイプミスを修正することで修正できます。
`+ build `サブコマンドは、テンプレートの ` builders +`セクションで定義したビルドを実行します。 つまり、PackerにDropletを作成し、DigitalOceanダッシュボードでそのDropletのスナップショットを作成するように指示します。
`+ packer.io build +`を呼び出してドロップレットをビルドし、スナップショットを作成します。
packer.io build -var-file=variables.json template.json
`+ -var-file `フラグは、 ` build `と ` validate +`サブコマンドの両方でまったく同じ方法で動作することに注意してください。
正常なビルドの出力は次のようになります。
Outputdigitalocean output will be in this color.
==> digitalocean: Creating temporary ssh key for Droplet...
==> digitalocean: Creating Droplet...
==> digitalocean: Waiting for Droplet to become active...
==> digitalocean: Waiting for SSH to become available...
==> digitalocean: Connected to SSH!
==> digitalocean: Gracefully shutting down Droplet...
==> digitalocean: Creating snapshot: packer-1467580504
==> 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: ') in region 'nyc1'
ビルドが成功すると、DigitalOceanスナップショットリポジトリに新しいスナップショットが見つかります。 出力でスナップショットの名前を見つけることができます。 この例では、「+ packer-1487878703 +」です。
ここから、DigitalOceanダッシュボードにアクセスし、*画像*を選択すると、新しいスナップショットがリストに表示されます。
image:https://assets.digitalocean.com/articles/packer_snapshot_cent7/COddO4K.png [DigitalOceanダッシュボードのDockerスナップショット]
これで、この新しいスナップショットを使用して新しいドロップレットを作成できます。 *その他*を選択し、*ドロップレットの作成*を選択します。 次に、フォームに入力して新しいマシンを作成します。
マシンがオンラインになったら、ダッシュボードからそのIPアドレスを確認し、新しいマシンにログインします。
次に、Nginxサーバーの構成ファイルを編集します。
vi /etc/nginx/vhost.d/newDomain.conf
そして、 `+ example.com +`をマシンのIPアドレスまたは使用するドメイン名に置き換えます。
〜/ packerProject / configs / newDomain.conf
server {
listen 80;
listen [::]:80;
server_name ;
location / {
root /var/www/html/newDomain;
index index.html index.htm;
}
}
あるいは、次のように、 `+ sed +`コマンドを使用してファイル内の値を置き換えることができます。
sudo sed -i 's/^.*server_name example.com/server_name /' /etc/nginx/vhost.d/newDomain.conf
「+ sed +」の詳細については、https://www.digitalocean.com/community/tutorials/the-basics-of-using-the-sed-stream-editor-to-manipulate-text-in-linux [このチュートリアル]。
トラブルシューティング
エラーメッセージで十分に説明されていない問題が発生する場合があります。 これらのシナリオでは、デバッグモードを有効にするか、Packerログを検査するか、またはその両方によって、ビルドに関する詳細を抽出できます。
デバッグモードは、リモートビルドの各ステップのビルダー固有のデバッグ情報を提供します。 DigitalOceanビルドのデバッグモードを有効にすると、プロジェクトフォルダーに一時的なプライベートキーが生成され、スナップショットに変換される前に実行中のドロップレットに接続して検査できます。
コマンドラインで `+ -debug `フラグを ` packer.io build +`に渡すことでデバッグモードに入ることができます:
packer.io build --var-file=variables.json template.json
デバッグモードで問題を診断できない場合は、Packerログを有効にしてみてください。 これらのログは、主にローカルビルダーのデバッグに使用されますが、リモートビルドに関する有用な情報も提供する場合があります。
Packerログを有効にするには、 `+ PACKER_LOG +`環境変数を「0」または空の文字列を除く任意の値に設定します。
packer build --var-file=variables.json template.json
`+ PACKER_LOG_PATH +`環境変数も設定しない限り、ログはコンソールに出力されます。
それでも問題が解決しない場合は、https://www.packer.io/community/ [Packer community]の誰かに連絡してみてください。
結論
Packerの基本に慣れたので、この基盤を構築することに興味があるかもしれません。
テンプレートに2番目のビルダーを追加して、DigitalOceanスナップショットと一緒にローカルテスト環境を作成してみてください。 たとえば、 `+ virtualbox-iso `ビルダーは、企業と愛好家の両方が使用する無料のオープンソース仮想化製品であるhttp://virtualbox.org [VirtualBox]のイメージを生成します。 VirtualBoxイメージに「 post-processor +」を定義し、DigitalOceanスナップショットをミラーリングするVagrant環境を作成できます。 これにより、Webサイトの変更をライブドロップレットにプッシュする前にローカルでテストできます。 詳細については、https://www.packer.io/docs/post-processors/vagrant.html [Vagrant post-processor documentation]をご覧ください。
または、Webサーバーをデータベースに接続することもできます。 2つ目の「+ digitalocean」ビルダーを追加し、「+ provisioner」セクションで「+ only」キーを使用して、各ビルドに異なるプロビジョニングを適用します。
構成管理ツールの使用に慣れている場合、Packerにはhttps://www.ansible.com/[Ansible]、https://puppet.com/[Puppet]、https:/のすぐに使えるサポートが付属しています。 /www.chef.io/[Chef]など。 これらのプロビジョニングツールのいずれかを使用して、ユースケースに合わせてドロップレットをさらに設定してみてください。 以前に構成管理を試したことがない場合は、https://www.digitalocean.com/community/tutorials/how-to-create-ansible-playbooks-to-automate-system-configuration-on-ubuntu [ Ansible Playbookを作成してUbuntuのシステム構成を自動化する方法]。