Got Some \W+ech?

Could be Japanese. Could be English. Android, セキュリティ, 機械学習などをメインに、たまにポエムったり雑感記載したりします。

Github + CircleCI + DockerでGCEを動かす - レジストリ編

  • 2017/08/31: コメントでの指摘を受け、一部コマンドを変更

背景:

  • 今、(ほぼ)1人チームで継続性が強く必要な仕事をしているので、あらゆる面で運用を楽にしていきたい。なのでコードで楽に管理でき、デプロイまで自動でやってくれて、オフィスアカウント(googleアカウント)との連携もできるGCPに強く興味がある。特にContainer周りやGCEは深くほっていきたいエリア。
  • 最終目標はDockerイメージをGCPで動かすところだが、今回はイメージをGithub + CircleCIを用いてレジストリにPushするところまでが目的
  • コードはこちらです。

Cloud SDKインストール & セットアップ

https://cloud.google.com/sdk/docs/quickstart-mac-os-x

% tar xvzf google-cloud-sdk-121.0.0-darwin-x86_64.tar.gz
% ./google-cloud-sdk/install.sh
% gcloud init
% gcloud components update kubectl // Instal kubectl

GKE setup

  • Clusterの作成をGUIで。gcloudかRESTでも作成可能
    • gophish-clusterをasia-east1-a上に作った
  • コマンド環境の設定
% export PROJECT_ID=gophish-150317
% gcloud config set project ${PROJECT_ID}
% gcloud config set compute/zone asia-east1-a
% gcloud config set container/cluster gophish-cluster
% gcloud container clusters get-credentials gophish-cluster
  • Dockerイメージのビルド
% docker build -t asia.gcr.io/${PROJECT_ID}/gophish:v1 .
  • ビルドしたイメージをGKEのContainer RegistryにPush
% gcloud docker -- push asia.gcr.io/${PROJECT_ID}/gophish:v1
% gcloud docker -- search asia.gcr.io/${PROJECT_ID}
  • 問題なくできていれば下記のようにイメージがタグ付きで表示される

自動ビルドをする

Github + CircleCIの構成で。

事前準備

  • Githubリポジトリを作る。ローカルで作ったファイルをPushしておく
  • GithubとCircleCIを連携する。circle.ymlはない状態だがとりあえずビルド一回ぐらい回す
  • GCPプロジェクトのサービスアカウントキー(JSON)を取得する
    • プロジェクト > API Manager > 認証情報 > 認証情報を作成 > サービスアカウントキー
    • 役割は「編集者」の役割 をもっているメンバーだけが可能みたいだ。とりあえずCompute Engine default service accountを使っといた。
    • https://cloud.google.com/container-registry/docs/access-control

circle.yml作成

  • Githubフローに似た流れのジョブを作る。つまり…

ブランチを切ってMaster向けPRを作成。 ↓ Dockerイメージをビルド + テスト ↓ レビュー ↓ マージ && テスト環境デプロイ ↓ リリースtagをきる on Github ↓ 本番環境デプロイ

  • 真のGithubフローだとprを送った時点でデプロイされる、といったことをどこかで読んだ事が、切り戻しまでの時間を考えるとアグレッシブだな、と思う。切り戻しまでの時間 < Maximum Tolerant Downtimeであればいい、という発想なのだろうか。組織と個人のレベルが高ければ実現できそうだな。

  • このフローを作るには、Github > Settings > Webhooksのイベントで以下を設定しておけばいい

    • Push, Pull request, Deployment, Release

どう動くか

  • BranchをきってPRを作った時にはテストまで実行されてデプロイはされない

  • MergeするとMasterブランチでのビルドが走る。デプロイまでされる. GCPでみるとlatestタグのついたイメージが更新されていることがわかる

  • GithubでReleaseをすると、WebHookしてくれて、やはりデプロイまでしてくれる。ただdeploy.shにリリースタグがある場合の追加処理があり、それによりリリースタグが付与されたDockerイメージがレジストリにpushされる。以下は v1.0.1をリリースした例。こういう形で変更管理を楽にできそう。

gist.github.com

  • 以上。

その他

  • CircleCI内でgcloudをupdateしてるけど、デフォルトで最新化しててくれませんかね…15秒もかかっとんぞ
  • Dockerイメージをビルドするのが遅い。これはCircleCIのコンテナ内でビルドしてるので、キャッシュされないから。対策としてはdependenciesで、ジョブ開始時点での最新イメージをGKEからpullしてくること。これをすると30秒くらい早くなる。
    • CircleCI 2.0でなんとかするらしい。
  • deploy.shって, deploymentのタイプ毎に分けた方がいいのかな〜