LoginSignup
4
1

More than 3 years have passed since last update.

CircleCIを使ってGitのコミットごとにGCPにDockerイメージを作る

Last updated at Posted at 2020-07-10

はじめに

コミットごとにDokerのイメージを作るようにしました。
それぞれのコミットごとに完全動作するコンテナが出来上がります。コミットごとに別々の環境がデプロイされると開発が良くなると考えています。

これには

  1. CIの一つとしてイメージのビルドが通る、イメージを使ってテストを実行できる、といったことが可能になる
  2. それぞれのイメージでデプロイができ、実行(テスト)ができる
  3. 検証をする場合にイメージのビルドを行わず、プルすることができる

といったメリットがあります。

コミットごとデプロイについての関連記事です。

PWAアプリがブランチごとに自動デプロイされる開発フローを取り入れたらすごく捗った話
https://qiita.com/yousan/items/b2741110ca2c0dae6330

Dockerfileの準備

テスト用に Dockerfile を作成しておきます。

Dockerfile
FROM golang:latest

テスト用なのでどういったDockerfileでも構いません。

設定

CircleCIの設定

CircleCIでGCPを使う場合の参考ページです
https://circleci.com/docs/2.0/google-auth/

基本的にこのページに沿っていけば実現できるのですが、うまく動かないポイントも多いため注意が必要です。

まずCircleCIでAdd Projectし、GitHub(やGitLab, Bitbucket)と連携しておきます。
(GitHubとCircleCIの連携は済ませているとします)

Screen Shot 2020-07-10 at 16.43.35.png

GCPでのサービスアカウントの登録

GCP上でサービスアカウントを登録します。

Screen Shot 2020-07-10 at 16.45.38.png

作成したサービスアカウントからキーをJSONでダウンロードしておきます。

Screen Shot 2020-07-10 at 16.46.00.png

image.png

次に「IAM」から作成したサービスアカウントに対して権限を付与します。

権限
Cloud Build サービス アカウント
Storage オブジェクト管理者
Storage オブジェクト作成者
Storage オブジェクト閲覧者
閲覧者

Screen Shot 2020-07-10 at 16.48.02.png

Cloud Buildを実行するための権限、CGRにイメージをアップロードするためのCloud Storage関連の権限、プロジェクトを参照するための閲覧権限が必要でした。

思った以上に権限が必要で、足りないと途中でエラーが出るためその対処は大変です。
CircleCIによるGCPの参考ページにもGCRの場合には追加の権限が必要になる、との記載があります。

If you are having issues pushing container images to GCR you may need more granular permissions than the default service account provides. You can grant permission changes in the Cloud Storage IAM Console
https://circleci.com/docs/2.0/google-auth/

「プロジェクトの編集者」といった権限を与えるとなんでもできてしまうため権限が足りなエラーは解消しますが、自動化する場合には万が一の漏洩を考えて最小限の権限とすることが必要です。

ローカルでの試験

CircleCIでの手順に進む前にローカル環境から正しく動くか、権限が足りているか、ということを確認しておきます。
こうすることでCircleCI、GCPといった複数のサービスをまたがって行う作業に対してトラブルを早めに見つけられるようにしておきます。

まずプロジェクトIDとリージョン(ゾーン)を設定しておきます。(プロジェクト名をexampleとしていますが適宜読み替えてください)

$ export GOOGLE_PROJECT_ID=example
$ export GOOGLE_COMPUTE_ZONE=ap-northeast1

先ほどダウンロードしたCircleCI用のキーでgcloudコマンドで認証を掛けます。

$ echo <ダウンロードしたキーの場所>  | gcloud auth activate-service-account --key-file=-

Activated service account credentials for: [circleci@example.iam.gserviceaccount.com]

プロジェクトとリージョンの設定を行います。

$ gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
$ gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}

アカウントが切り替わっていることを確認しておきます。

$ gcloud config list

[compute]
zone = ap-northeast1
[core]
account = circleci@example.iam.gserviceaccount.com
disable_usage_reporting = False
project = example

Your active configuration is: [default]

先ほど作成したDockerfileをビルドしてみます。

$ gcloud builds submit --tag gcr.io/${GOOGLE_PROJECT_ID}/test .


Creating temporary tarball archive of 10 file(s) totalling 5.4 KiB before compression.
Uploading tarball of [.] to [gs://example_cloudbuild/source/1594367971.xxxxxxxxxxxxxxxx.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/xxxxxxxxxxxxxxxxxxxxxx].
.....


latest: digest: sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx size: 1795
DONE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ID                                    CREATE_TIME                DURATION  SOURCE                                                                                            IMAGES                                    STATUS
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx  2020-07-10T07:59:32+00:00  18S       gs://example_cloudbuild/source/1594367971.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.tgz  gcr.io/example/test (+1 more)  SUCCESS

成功しました。

確認しておきます。

$ gcloud container images list-tags gcr.io/example/test

DIGEST        TAGS                                    TIMESTAMP
b413792axxxx  latest                                  2020-07-07T18:20:07

正しく作成されていますね。

CircleCIへの組み込み

CircleCIでビルドが通るように設定を行います。

環境変数を設定します。

CircleCIのプロジェクトを開いた画面中にある Project Settings から Environment Variables を選択します。

image.png

それぞれの変数を設定しています。
鍵のJSONについては pbcopy などを利用すると便利です。

$ cat ~/Download/example.json | pbcopy
環境変数名
GCLOUD_SERVICE_KEY 先の手順で作成したサービスアカウントの
GOOGLE_PROJECT_ID プロジェクトID
GOOGLE_COMPUTE_ZONE コンピュートゾーン (ap-northeast1 ap-northeast2 など)

下記のように3つの変数を設定します。

image.png

セットアップ

次にCircleCIの config.yml を設定します。

CircleCIではgoogle/cloud-sdkというイメージを使うとgcloudが一通り揃っています。

circleci/config.yml
version: 2.1
jobs:
  build:
    docker:
      - image: google/cloud-sdk
    steps:
      - checkout
      - run: |
          echo $GCLOUD_SERVICE_KEY | gcloud auth activate-service-account --key-file=-
          gcloud --quiet config set project ${GOOGLE_PROJECT_ID}
          gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE}
          gcloud builds submit --tag gcr.io/${GOOGLE_PROJECT_ID}/test .

コミット、プッシュをして動作させます。
circleciコマンドが入っている場合、下記のように validate を掛けておくと構文エラーをへらすことができます。

$ circleci config validate && git add .circleci/config.yml &&  git commit -m 'Add CircleCI config' && git push origin HEAD

CircleCIでのビルドを確認します。

image.png

問題がなければ正しくビルドされ、GCRにイメージが作成されているはずです。

Cloud Runでの実行

冒頭に述べた「それぞれのDockerイメージに対してテストを行う」を行いたいと思います。
GKEではクラスタ上にPodを作りますが、すべてのDockerイメージに対してPodを作成することは難しいです。というのもPodごとに動作メモリが必要で、クラスタで最大利用可能メモリが決まっており、それを超えてPodを作成することができません。

そのためビルド済みDockerイメージのテストをCloud Runを使って実行します。

参考: Google Cloud Run を使うまで
https://qiita.com/massie_g/items/5a9ce514eaa7c460b5e3

費用など

GCRでは Cloud Storage としてイメージが保管されるため、月々の費用がかかります。
2020年7月現在、概算で下記の通りです。

Standard のバケット料金は、1 GB あたり月額約 $0.026 です。
https://cloud.google.com/container-registry/pricing?hl=ja

巨大なイメージを管理する場合には注意が必要です。

4
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
4
1