Container Builderを使ってGCPで利用するコンテナをビルドする

GCPへコンテナを配備するツールとして、Container Builderというものがあります。
Container Builderを利用することで、GitHubやSource Repositriesで管理されているソースコードから、コンテナをビルドして非公開DockerレジストリであるContainer Registryへ登録し、コンテナ化されたアプリケーションをデプロイするためのマネージド環境である、Kubernetes Engine(旧:Container Engine)などで容易に利用することができます。なんなら自動化してしまうことも可能ですのでとっても便利です。
これらのサービスを簡単に図にすると以下のような関係になります。

この記事では赤い枠線の部分について、アプリケーションをホスティングするWebサーバコンテナのビルドを例にして、Container Builderの使い方を以下の流れで解説します。

  1. アプリケーションの準備
  2. Container Builder用定義ファイルの作成
  3. gcloudコマンドによる手動ビルドとContainer Registryへの登録
  4. Source Repositoriesへのpushによる自動ビルドとContainer Registryへの登録

アプリケーションの準備

Container Builderがソースコードを元にアプリケーションをビルドする様子を見るために、ビルドを必要とするアプリケーションを用意します。
今回は以下のバージョンのAngularアプリケーションを利用することにします。

コード
Angular CLI: 1.6.3
Node: 8.9.0
OS: darwin x64
Angular CLIがインストールされていれば、次のコマンドでアプリケーションの雛形を作成することができます。
コード
ng new -si container-builder-sample

Container Builder用定義ファイルの作成

Container Builderでは、cloudbuild.yaml というファイルを利用して、ビルドタスクを定義します。
今回は以下のようなステップを記述します。

  1. npmのバージョンをログに出力
  2. 依存パッケージをインストール
  3. Angularアプリケーションをビルド
  4. Dockerfileを元にイメージを作成

上記のステップをcloudbuild.yamlへ記述すると以下のようになります。

コード
steps:
# 1:npmのバージョン表示
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['version']
  id: 'npm-version'
# 2:依存パッケージをインストール
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['install']
  id: 'npm-install'
# 3:アプリケーションをビルド
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['run-script', 'build']
  id: 'npm-build'
# 4:イメージを作成
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/cb-sample:0.1', '.']
  wait_for: ['npm-build']
images: ['gcr.io/$PROJECT_ID/cb-sample:0.1']
Dockerfileは以下のものを用意しました
コード
# 軽量なalpineベースのイメージを利用
FROM nginx:1.13.8-alpine

# /workspace以下にソースが配置される
WORKDIR /workspace

# アプリケーションをコンテナへコピー
# dist/ はビルドされたアプリケーションが展開されるディレクトリ
COPY dist/* /usr/share/nginx/html/

# 80番ポートをlisten
EXPOSE 80

gcloudコマンドによる手動ビルド

Container Builderのビルドタスクを実行する方法は大きく2つあります。
1つは、gcloudコマンドを使用してローカルのソースプログラムから手動で実行する方法です。
もう1つは、GitHubやSource Repositoriesへの特定のブランチに対するpushをトリガーに実行する方法です。
ここではgcloudコマンドを利用する方法を説明します。
ここまでの作業で、以下のようなファイル、ディレクトリが存在していることを確認しておきましょう。赤色の2ファイルを新規に追加しました。
その他のファイルは、Angularアプリケーションのためのファイルになるので、cloudbuild.yamlとDockerfileをアプリケーションに応じて修正すれば、どのようなファイルでも構いません。
.
├── Dockerfile
├── README.md
├── cloudbuild.yaml
├── e2e/
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src/
├── tsconfig.json
└── tslint.json
確認ができたら、以下のコマンドを実行することでビルドタスクが実行されます。

コード
gcloud container builds submit --config=cloudbuild.yaml .
実行の経過が以下のように出力されます。

コード
Creating temporary tarball archive of 97 file(s) totalling 59.1 KiB before compression.
Uploading tarball of [.] to [gs://ca-tominaga-test_cloudbuild/source/1515648182.22-2c6044c6dcda41cf911dbc1c9dd3f076.tgz]
...
...
DONE
------------------------------------------------------------------------
GCPのWebコンソールからも、Container Registry -> ビルド履歴 と辿ることで、以下の画像のように結果を参照することができます。

成功していれば、「イメージ」の中にcloudbuild.yamlで指定した名前とタグを持つDockerイメージが登録されているはずです。

作成されたイメージが正しくアプリケーションをホストできるか、ローカルにイメージを落として確認してみましょう。
上記画像の中の”cb-sample”をクリックすると、イメージの詳細画面へ遷移でき、PULLコマンドを表示することができます。

例えば以下のようなコマンドが表示されます。
コード
gcloud docker -- pull gcr.io/<project-id>/cb-sample:0.1
イメージのpullが確認できたら、ローカルで実行してみましょう。
今回はnginxコンテナの80番ポートにアクセスできればいいので、以下のようなdockerコマンドを実行すればいいですね。
コード
docker run -it -d --name nginx -p 127.0.0.1:8080:80 gcr.io/<project-id>/cb-sample:0.1
この状態で http://127.0.0.1:8080/ へアクセスし、Angularアプリケーションの雛形が表示されれば成功です。

Source Respositriesへのpushをトリガーとする自動ビルド

gcloudコマンドによる手動ビルドの他、Gitリポジトリの特定のブランチへpushされた際に、自動的にビルドを実行することもできます。
今回はGitリポジトリとしてGCPが提供する、Source Repositoriesを利用します。
レポジトリの作成方法は割愛しますが、GitHubとの連携も非常に簡単ですので、是非試してみてください。
ここからは、この時点でのリモートブランチが作成されていることを前提に話を進めます。

トリガーの作成

自動ビルドのトリガーをContainerRegistryのコンソールから作成します。
ソースとリポジトリの選択を、先程作成したGitリポジトリへ設定し、トリガーの設定は「トリガーのタイプ」「ブランチ」「ビルド設定」を以下のように指定しました。

これで、該当リポジトリのmasterブランチへpushされた際に、cloudbuild.yamlに基いてDockerイメージのビルドが行われます。
詳細なトリガーの作成はこちらからご参照ください。

イメージタグ名の設定

必須ではありませんが、自動ビルドの場合はどのコミットに対して作成されたイメージなのかを判別するために、コミットハッシュをタグ名にするとわかりやすくなります。
以下のようにcloudbuild.yamlを修正しておくと良いでしょう。

コード
steps:
# 1:npmのバージョン表示
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['version']
  id: 'npm-version'
# 2:依存パッケージをインストール
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['install']
  id: 'npm-install'
# 3:アプリケーションをビルド
- name: 'gcr.io/cloud-builders/npm:latest'
  args: ['run-script', 'build']
  id: 'npm-build'
# 4:イメージを作成
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/cb-sample:$COMMIT_SHA', '.']
  wait_for: ['npm-build']
images: ['gcr.io/$PROJECT_ID/cb-sample:$COMMIT_SHA']
$PROJECT_IDや$COMMIT_SHAのように、いくつかの変数を環境変数として設定することができます。

アプリケーションの変更

次回の記事では、今回作成したコンテナをKubernetes Engineで使用する方法を解説する予定です。コンテナの入れ替えによるアプリケーションのアップデートを確認しやすくするために、アプリケーションにも何か変更を加えておきましょう。
Welcome to app” の文字列を “Welcome to Container Builder”へ変更しておきます。
この状態でコミットをし、リモートブランチにpushします。
ビルドが成功し、Dockerイメージが作成されていることができたら、先程と同じように確認してみましょう。

料金

Container Builderの料金はビルドした時間とマシンタイプに応じて課金されます。
今回も用いたマシンタイプを指定しなかった場合のデフォルト指定である、n1-standard-1インスタンスに限っては、1日当たり最初の120分のビルドについては無料で利用することができます。
無料枠を超過した分については、1分当たり$0.003と非常に安く設定されています。
その他の詳しい料金については、こちらをご参照ください。

まとめ

Container Builderを利用することで、アプリケーションのビルドからDockerイメージの作成までを安価な料金でGCPに任せることができます。
DockerコンテナをGCPで利用する場合は欠かせないサービスだと思いますので、是非触ってみてください。
弊社ではクラウドエース(Cloud Ace)というサービスのコンテナ化も含めたGCPの導入・運用支援サービスを提供しておりますので、ご興味のある方はお問い合わせください。

次の記事を読み込んでいます
次の記事を読み込んでいます
次の記事を読み込んでいます