LoginSignup
3
1

More than 1 year has passed since last update.

Cloud BuildでGKEにデプロイ

Last updated at Posted at 2021-05-27

Cloud Build はGCP上でアプリケーションを自動でビルド、デプロイできるサービスです。

GitHubと連携してリポジトリへのプッシュをトリガーに発動することができます。
(ブランチや、特定のタグをトリガーとして設定ができます)

ビルドのステップをyamlに記述して構成することができます。

自分の用途でビルド~デプロイまで以下のような流れとなります。

GitHubにプッシュ(トリガーとなるタグ付けをしてプッシュ)
 ↓
CloudBuild が起動(トリガーに設定されたタグにより起動)
 ↓
イメージをビルド
 ↓
ビルドされたイメージを ContainerRepository にプッシュ
 ↓
Unitテスト実行
 ↓
コンテナイメージをGKEにデプロイ

GKE(事前準備)

クラスター、ノードプールなどをあらかじめ設定しておく必要があります
(詳細はこの記事では省略します)
image.png

CloudBuildのトリガー設定

対象(連携する)リポジトリ、イベント、構成用yamlの指定などを行います。

イベントはCloudBuildを開始するためのリポジトリ上のアクションで
特定のブランチやタグなどのpushなどを設定できます。

以下の例ではrelease_.{7}としていますが、
release_(コミットhashの短縮版)でタグ付けしたものをトリガーの条件としています。
image.png
image.png

リポジトリのディレクトリ構成(サンプル)

├── cloud_build
│   ├── cloudbuild.yaml   ・・・ CloudBuild構成用yaml
│   ├── apply.yaml      ・・・ GKEへのデプロイ用yaml(CloudBuild構成用yaml内から呼び出し)
│   └── dockerfile
│   │   ├── nginx
│   │   │   ├── Dockerfile  ・・・ CloudBuild内イメージビルド用
├── laravel           ・・・アプリケーション(laravelプロジェクト)
│   ├── app
│   ├── bootstrap
│   ├── config
・
・
・

上記のように構成用yaml(/cloud_build/cloudbuild.yaml)を配置した場合は
トリガーに以下のように設定します。
image.png

構成用yamlの記述

実行するステップの作業を記述します

キー 指定内容
name ビルドの各ステップで利用する一般公開されているDockerイメージを指定します。
CloudBuildではgcr.io/cloud-builders/******のようなイメージが用意されていて、例えばgcr.io/cloud-builders/dockerを利用するとクラウドビルド上でDockerコマンドを実行することができます。
args nameに指定したイメージ実行時に渡す引数を記述します
id ビルドステップの識別子となります
waitFor ビルドステップの順番の制御に利用できます
#######################################################################
# リポジトリ内から .dockerignoreファイルを削除
#######################################################################
steps:
- name: 'ubuntu'
  args:
    - bash
    - -c
    - 'rm -rf .dockerignore'
  id: 'rm-dockerignore'
#######################################################################
# イメージをビルド
# ($TAG_NAMEはGitコミットのタグの値、ビルドしたDockerイメージに同じタグ付け)
#######################################################################
- name: 'gcr.io/cloud-builders/docker'
  args:
    - build
    - -f
    - cloud_build/dockerfile/nginx/Dockerfile
    - --tag
    - asia.gcr.io/$PROJECT_ID/laravel:$TAG_NAME
    - .
  waitFor: ['rm-dockerignore']
#######################################################################
# ビルドしたイメージを container registry にプッシュ
#######################################################################
- name: 'gcr.io/cloud-builders/docker'
  args:
    - push
    - asia.gcr.io/$PROJECT_ID/laravel:$TAG_NAME
#######################################################################
# GKEデプロイ用のyaml内のコンテナイメージのタグを置換
#######################################################################
- name: 'ubuntu'
  args:
    - bash
    - -c
    - 'sed -i.bk s/latest/$TAG_NAME/g cloud_build/apply.yaml'
  id: 'laravel-build-done'
#######################################################################
# テスト実行
#######################################################################
- name: 'gcr.io/cloud-builders/docker'
  args:
    - run
    - --rm
    - --workdir=/var/www/html/laravel
    - --entrypoint=composer
    - asia.gcr.io/$PROJECT_ID/laravel:$TAG_NAME
    - test:coverage
  waitFor: ['laravel-build-done']
  id: 'phpunit-done'
#######################################################################
#gcloud認証
#######################################################################
- name: 'gcr.io/cloud-builders/gcloud'
  args:
  - beta
  - container
  - clusters
  - get-credentials
  - $_CLUSTER_NAME
  - --zone=$_ZONE
  - --project=$PROJECT_ID
  waitFor: ['-']
  id: 'gcloud-get-credentials'
#######################################################################
# アプリのデプロイ設定
#######################################################################
- name: 'gcr.io/cloud-builders/kubectl'
  args:
    - apply
    - --filename=cloud_build/apply.yaml
  env:
    - CLOUDSDK_COMPUTE_ZONE=$_ZONE
    - CLOUDSDK_CONTAINER_CLUSTER=$_CLUSTER_NAME
  waitFor: ['gcloud-get-credentials','phpunit-done']
#######################################################################
timeout: 1000s

yaml内に変数を埋め込んでいますが、CloudBuild実行時に値が置換されます。

$PROJECT_IDはGCPのプロジェクトIDが設定されます。

$TAG_NAMEはトリガーとなったGitリポジトリのタグ名が埋め込まれています。

$_ZONE$_CLUSTER_NAMEはそれぞれGKEのゾーン名、クラスタ名ですが、
CloudBuildのトリガー設定画面で設定しています。
image.png

GitHubへのプッシュとトリガーの稼働の実際

トリガー発動のためのタグ付けします
コミットhashを元にタグ付けをしてみます(git rev-parse --shortで短いコミットhashが取得できます)

$ git tag release_$(git rev-parse --short HEAD)
$ git log --oneline
* 459ddf9 (HEAD -> **, tag: release_459ddf9) *****

タグをプッシュします

$ git push origin ** --tags
Enumerating objects: 25, done.
Counting objects: 100% (25/25), done.
Delta compression using up to 6 threads
Compressing objects: 100% (13/13), done.
Writing objects: 100% (14/14), 1.40 KiB | 715.00 KiB/s, done.
Total 14 (delta 10), reused 0 (delta 0)
remote: Resolving deltas: 100% (10/10), completed with 9 local objects.
To github.com:*******/********.git
 * [new tag]         release_459ddf9 -> release_459ddf9

CloudBuildのビルドの詳細でビルドプロセスが確認できます

image.png

正常に完了すると全てのステップがグリーンになります

image.png

最後のステップでGKEへデプロイを行っています。
kubectl get pods -wでGKEのポッドの状態をウォッチすると
新たにビルドされたイメージがデプロイされることで
元々稼働していたポッドが終了し
新たなポッドが生成されていることがわかります

$ kubectl get pods -w
NAME                                         READY   STATUS    RESTARTS   AGE
*****-******-857db5db5f-pmxkh               1/1     Running   0          3d6h
#元々稼働していたポッドが終了していく
*****-******-857db5db5f-pmxkh               1/1     Terminating   0          3d6h
*****-******-857db5db5f-pmxkh               0/1     Terminating   0          3d6h
*****-******-857db5db5f-pmxkh               0/1     Terminating   0          3d6h
*****-******-857db5db5f-pmxkh               0/1     Terminating   0          3d6h
#新たなポッドが立ち上がり始める
*****-******-857d58675c-gcmgb               0/1     Pending       0          0s
*****-******-857d58675c-gcmgb               0/1     Pending       0          0s
*****-******-857d58675c-gcmgb               0/1     ContainerCreating   0          0s
#新たなポッドが起動完了
*****-******-857d58675c-gcmgb               1/1     Running             0          25s

以下はテストが失敗した場合のパターンです。
テストステップの失敗によりCloudBuildも失敗となり、
アプリケーションのデプロイもされることがありません。
image.png

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1