Go
GoogleAppEngine
docker
GoogleCloudPlatform
GoogleCloudContainerBuilder

30分でできる(当社比) Google Cloud Container Builderを利用した AppEngine SE環境への自動デプロイ

More than 1 year has passed since last update.

AppEngine FEのビルドにも使われている Google Cloud Container Builder

ビルドトリガーとして、GitのレポジトリへのPushなども設定できるため、簡易なCIツールとしても利用できるのではないかと思ってやってみた。
使用感としては、割と手軽にCIっぽいことできて便利って感じ。

記事内で使用しているコード

.
├── Dockerfile.deploy
├── Dockerfile.glide
├── README.md
├── app
│   └── default
│       ├── app.yaml
│       └── main.go
├── cloudbuild.yaml
├── deploy.sh
└── src
    ├── gccb_sample
    │   └── route.go
    ├── glide.lock
    └── glide.yaml

# 上記の構成についての詳細は、前回の記事(Qiita - GAE/Go+glide的な構成での環境構築 ~ローカルサーバー立ち上げまで~)を参照

手順簡易まとめ

  1. GCPプロジェクトで、AppEngineのデプロイ権限を持つサービスアカウントを作成し、キーファイルを取得する
  2. AppEngineデプロイ用のDockerコンテナを作成し、 Google Container Registry にpush
  3. デプロイ用コンテナが実行されるカスタムビルドステップを作成
  4. Cloud Source Repositories にレポジトリを作成する
  5. Cloud Source Repositories の特定ブランチへのPushをイベントとした Google Container Registry のトリガーを作成する
  6. Cloud Source Repositories へソースをPushする

Google Cloud Container Builder(GCCB)とは

Google Cloud StorageGoogle Cloud Source Repository にあるソースコードからDockerイメージのビルドを行うサービス。
AppEngine FE環境 のビルドも実はGCCBを利用してDockerイメージがビルドされ、 Google Container Registory にビルドされたイメージが保存されるようになっている。

ビルドの開始は、 gcloud コマンドやREST APIなどで実行できるほか、 Google Source Repository, GitHub, Bitbucket へのPushもトリガーとすることが可能。

サービスアカウント作成とキーファイル取得

GCPへデプロイするためのサービスアカウントを作成し、キーファイルを生成する

サービスアカウント作成

IAMと管理 > サービスアカウント > サービスアカウントを作成 で、デプロイ用のサービスアカウントを作る。

IAM と管理

キーファイル生成

作成したサービスアカウントのオプションから キーを作成 を選択し、キーファイルをダウンロードする。
# 今回はJSON形式を指定。

IAM と管理

ここで作成したサービスアカウントとキーファイルは、デプロイ時に使用する

Dockerコンテナのビルド

GAE/Go SEへのデプロイを行うDockerコンテナをビルドする。
今回のサンプルでは、デプロイ前にglideを使用して依存ライブラリの取得も行いたいため、デプロイ用コンテナとは別にビルド用コンテナをビルドしている。

ベースイメージのPull

ビルド用コンテナ、デプロイ用コンテナのベースイメージをpullしておく

$ gcloud docker -- pull gcr.io/cloud-builders/glide
$ gcloud docker -- pull gcr.io/cloud-builders/gcloud

ビルド用コンテナのビルド

依存ライブラリの取得を行うDockerイメージをビルドする。

Dockerfile

Dockerfile.glide
# Google Cloud Container Builder 公式イメージ
# https://github.com/GoogleCloudPlatform/cloud-builders
FROM gcr.io/cloud-builders/glide

ENV GOPATH=$GOPATH:/workspace

# GCCBのビルドステップ中は、各ステップの成果物やソースコードは全て `/workspace`
# ディレクトリに保存され、ワークディレクトリが `/workspace` となるためローカル
# でも同様の状態を再現するためにワークディレクトリを `/workspace` に設定しておく
WORKDIR /workspace

ENTRYPOINT ["sh"]
CMD ["-c", "cd src && glide.bash install"]

ビルド

$ docker build -t gcr.io/{YOUR_PROJECT_ID}/glide -f Dockerfile.deploy .

デプロイ用コンテナのビルド

AppEngine SE へアプリケーションのデプロイを行うDockerイメージをビルドする。

Dockerfile

Dockerfile.deploy
# Google Cloud Container Builder 公式イメージ
# https://github.com/GoogleCloudPlatform/cloud-builders
FROM gcr.io/cloud-builders/gcloud

# デプロイ先のプロジェクト名
ARG PROJECT_NAME
# サービスアカウントのキーファイル名
ARG KEY_FILE_NAME
# サービスアカウントID
ARG SERVICE_ACCOUNT_ID

# デプロイ時の環境設定
ENV APPLICATION=${PROJECT_NAME} \
    GAE_GO_SDK_VERSION=1.9.56 \
    ACCOUNT=${SERVICE_ACCOUNT_ID} \
    KEY_FILE_NAME=${KEY_FILE_NAME} \
    PATH=/go_appengine:$PATH \
    GOPATH=/workspace

# サービスアカウントのキーファイルを、Dockerコンテナ内にコピーする
COPY ${KEY_FILE_NAME} /${KEY_FILE_NAME}

RUN apt-get update && apt-get install -y \
    wget \
    unzip \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

# AppEngine SDK For Go のインストール
RUN wget https://storage.googleapis.com/appengine-sdks/featured/go_appengine_sdk_linux_amd64-${GAE_GO_SDK_VERSION}.zip \
 && unzip /go_appengine_sdk_linux_amd64-${GAE_GO_SDK_VERSION}.zip \
 && rm /go_appengine_sdk_linux_amd64-${GAE_GO_SDK_VERSION}.zip

WORKDIR ${GOPATH}

# デプロイスクリプトの実行
ENTRYPOINT ["sh"]
CMD ["deploy.sh"]

ビルド

$ docker build -t gcr.io/{YOUR_PROJECT_ID}/deploy \
  -f Dockerfile.deploy \
  --build-arg PROJECT_NAME={YOUR_PROJECT_NAME} \
  --build-arg SERVICE_ACCOUNT_ID={SERVICE_ACCOUNT_ID} \
  --build-arg KEY_FILE_NAME={SERVICE_ACCOUNT_KEY_FILE_NAME} \
  .

デプロイスクリプト

サービスアカウントを使用してデプロイしているだけ。

deploy.sh
gcloud auth activate-service-account $ACCOUNT --key-file /$KEY_FILE_NAME

appcfg.py update --application $APPLICATION --oauth2_access_token $(gcloud auth print-access-token 2> /dev/null) app/default

ローカルでビルドしたイメージを実行してみる

$ docker run --rm -v $PROJECT_ROOT:/workspac gcr.io/{YOUR_PROJECT_ID}/glide   # 依存ライブラリの取得
$ docker run --rm -v $PROJECT_ROOT:/workspac gcr.io/{YOUR_PROJECT_ID}/deploy  # デプロイ実行

上記実行してみて、特にエラーが発生せずにデプロイが成功していたら問題なくイメージのビルドができてる。

DockerイメージのPush

Google Container Registoryに、ビルドしたコンテナイメージをPushしておく

$ gcloud docker -- push gcr.io/{YOUR_PROJECT_ID}/glide
$ gcloud docker -- push gcr.io/{YOUR_PROJECT_ID}/deploy

カスタムビルドステップの作成

カスタムビルドステップを作成して、トリガーイベントの発生時に、作成したDockerイメージを利用してデプロイが行われるようにする。
カスタムビルドステップの設定ファイル(cloudbuild.yaml)はリポジトリに含めておくようにする。

cloudbuild.yaml
steps:
  - name: gcr.io/$PROJECT_ID/glide
  - name: gcr.io/$PROJECT_ID/deploy

Cloud Source Repositoriesの設定、トリガーの設定

レポジトリの作成

Source Repositories > レポジトリを作成で、レポジトリを作成する

Source Repositories   project ryutah.png

Google Cloud Container Builderのトリガー設定

作成したレポジトリをイベントとした、トリガーを作成する

トリガー作成手順

  1. Container Registory > トリガーを作成 > トリガーを作成 を選択
    Container Registry

  2. ソースを選択Cloud Source Repositories を選択
    Container Registry

  3. リポジトリを選択 で、先ほど作成したレポジトリを選択
    Container Registry

  4. トリガー設定 > ビルド設定 で cloudbuild.yaml を選択し、 cloudbuild.yaml の場所/cloudbuild.yaml を設定する
    Container Registry

コードのPush、ビルドの確認

ソースを Cloud Source Repositories にPushし、ビルドを開始させる

$ git remote add google https://source.developers.google.com/p/{project ID}
$ git config --local credential.helper gcloud.sh
$ git push google master

コードをPushすると、 Container Registory > ビルド履歴 で、ビルドが実行されているのが確認できる。

Container Registry

ビルドに成功すると、緑色のチェックマークがつく

Container Registry


以上が、GCCBを利用して AppEngine Starndard Environment にデプロイする方法。

実際に試してみると、結構仕組みも単純だし、ビルドにDockerコンテナを使用するためかなり自由度が高く、Circle CIなどを使用した場合と比べてもGCPないで完結するぶんお手軽感がある。
また、各ビルドステップでエラーコードが帰ると、途中でビルドが停止されるらしい(未検証)ので、デプロイ前にテストの実施を行うとかもできそうな感じ。

GAEの利用を考えていて、かつCIツールに何を使用するか決定していない場合は、選択肢の一つとして考えてもいいかもしれない。

参考

Qiita - Google Container Builder ファイル作れるの作れないの!
Qiita - CircleCIでService Account使ってGAE/goへdeployする
Qiita - 既存のGitローカルレポジトリをGoogle Cloud RepositoriesにPushする。