Google Container Builder ファイル作れるの作れないの！

こんにちわ、こんにちわ
皆さんCIしてますか？お金かかっちゃってますか？ ダメウーマン

ココ数年CircleCIのお世話になってきたのですがv2が出るとかでないとか？Dockerベースになるやら良さげな雰囲気がしたのですが・・・まだベータということも有り、イマイチなところが有りました。プライベートのDockerコンテナ使えないからDocker on dockerして再度引っ張ってくるとかとかとか・・

UIは素晴らしいし、メタに環境変数色々持てるし素晴らしいんですが
見通しの悪さ、コア数課金も気になり始めている今日このごろ、CIはネットのように当たり前に使いたいので、コア数不足とか料金とかあまり気にしたくありません。

そこで、ちょい前から気になっていたGCCB(Google Cloud Container Builder)を使ってみようと思い色々調査中です。

# GCCB
## 良さげな点

- イメージがGCPプロジェクト内のプライベートなバケットに置ける
- github連携が有るので、プライベートなorg、repoから簡単にclone出来る
- もちろん、push時にCI回る（Google Cloud Source Repositoriesが踏み台になる）
- 料金やっすい（1ビリングアカウントで、毎日120分の無料ビルド時間）
    - 超過分 $0.0034/ビルド分なので、毎日6時間20日回しても月額$16
    - (CircleCIの有料プランは$50~)
- 出来ることはDocker内で処理するので、CiｒcleCIと同等という認識

## ワルそげな点

- UI超イケテナイ
- 外部通知系のインテグレーションがほぼ無いので手作りが必要
- ユーザー少ないので、ドキュメントが少ない


# 連携まで
トリガー作製から始まる、サービスを選択しその中のリポジトリーを指定する。

- Cloud Source Repository
- GitHub
- Bitbucket

の3つのサービスが選択できる（それ以外の選択肢はない）

好きなブランチを狙い撃ちでトリガーに出来るし、トリガー毎に設定ファイルの場所を指定できるので、適当なBuildスクリプをと適当なPathに置いてトリガー仕込めば好きな挙動をさせることが出来る。設定が統一神ファイルじゃなくていいので気が楽。

## GCCB ファースト所感
適当なDockerfile作って、ビルドしてgcr.ioにプッシュして好きなコマンド発行できるようになるところまでサクッと行った。特に難しいことはない。

それ以降の挙動がなんとなく今までのDockerの使い方というか、ふれあい方というか考え方と違いって居てキョドった。

Dockerって、1人称目線がクローンされるというか、つながっていないパラレルワールドを生成していくというか、ざっくりとしたステートレスなプロセスが上がっていってOS内で小さな生態系が出来上がって、なんとなく上手に共生していくそんな実行イメージがあった。

その目線から、GCCBを見始めたんだけどなんか勝手が全然違っていた。
GCCBもCIにありがちなステップで動作手順を記述していく、各ステップは非同期で実行したり、完了を待ってから実行したり結構自由な感じで使える。その各ステップは、ホストOSで実行されることなく、DockerImageをPullしてきてコンテナ起動した中で実行される。
ステップごとにコンテナを変えることも出来るし、同じのを再度使うことも出来る。

## ココで疑問
ステップごとにコンテナ変わったら、引き継ぎで作業できなくね？

今回の目的は、GAE SEにデプロイする環境のCircleCIの移行先としてGCCBを検討していた。しかし、GCCBはGKEに使うコンテナをBuildして、所定のストレージにPUSHするサービスとして提供され始めたみたい。なので複雑なプロセスやりづらくなってるのか！！と、一瞬納得するもテストとか動かすはずだしそんな簡単に諦めきれないのでキーボードを叩き続ける。

例えばチュートリアルには、

0. Step0　gsutilコマンドのコンテナで適当な実行バイナリをcpしてくる
1. Step1　処理対象のデータをwgetコンテナでDLしてくる
2. Step2　実行バイナリにデータ食わせて処理結果を保存
3. Step3　gsutilコマンドのコンテナで処理結果を適当なバケットにアップロード

みたいなことやってる。（このステップごとに違うイメージPULLしてきて、実行されている、特に--volumeオプション等は指定されていない）チュートリアルドキュメントを読んでるときにはfmfmって思ってたんだけど、よくよく考えると、バイナリ落としてくるとか、ファイル落としてくるって、そのコンテナ内のストレージに落ちてるんであって、各ステップ感は別コンテナなので受け渡しできないじゃん！！って
どうやってんだ？？？みたいな状態になったわけです。

# /workspace 神の領域

bash動く素のubuntuイメージ使って、lsしたりpwdしたり（この度にgithubにPush、GCCBがimage pull走る・・・orz）色々動作を見ているとworkspaceという謎の領域が有るぽい、各コンテナが実行するときにはその領域が自動でマウントされてるぽい？んで、各ステップ間で使いまわされているということがわかった。なのであとは簡単じゃん、なんでも放り込めばいいじゃん・・・

と思いきや、この `/workspace` の挙動がいまいちよくわからない。普通のHDDの用に使えそうで使えなかった。touchもmkdirもcpもPermissionエラーでfileが生成できない。それなのに `gsutil cp` とか `wget` で持ってきたファイルは、 `/workspace` 内に保存できてる・・・なんじゃこりゃ・・

とは言え、適当にテスト走らせてデプロイするだけなんで認証周りをクリアできれば、ファイル生成する必要なさそうなので今回は問題なし

# GCP サービスアカウント認証について
GCCBでBuild実行すると `hoge@cloudbuild.gserviceaccount.com` みたいなサービスアカウントが生成されてこの実行権限で動く。今回の目的は、GAEへのDeployなので、このサービスアカウントの認証スコープにGAEのデプロイもしくはプロジェクト権限当てれば、Build＞test＞ゴニョ＞deployまで、すっと流れて超便利。GCPで閉じたCI環境ができあがる！！

と思ったが、上記サービスアカウントに複数のスコープを付けても上手くデプロイしてくれなかった。なんでだろ？

別途GAEデプロイ用のサービスアカウントを作成して `gcloud auth  activate-service-account` してあげれば良いんだけども、このコマンドで gcloud コマンドがgrantされたとしても、 `/workspace` にトークンが保存されないため次ステップ以降では、流用できない。各ステップ内で都度実行する必要がある。

今回はこんなスクリプトを書いて、gcloudのinfo、gaeのバージョンリスト取得、GAE/go
 SEへのデプロイが動いている。

```
/<google-cloud-sdk-PATH>/gcloud auth  activate-service-account hoge@<project-id>.iam.gserviceaccount.com --key-file ./<where-path>/service_account.json

/<google-cloud-sdk-PATH>/gcloud info
/<google-cloud-sdk-PATH>/gcloud app versions list

VERTXT=`git rev-parse HEAD|cut -c 1-7`
/<google-cloud-sdk-PATH>/gcloud app deploy ./<GAE-source-path>/app.yaml -v from-gccb-$VERTXT
```
*上記例は、service_account.jsonを生で渡してますがこの辺はヨキに計らう必要がありそう。今後の課題

# ナウ 所感
コンテナビルダーっていうサービス名だけど、CIとしても十分使えるしなにより、同一GCP内で動作しているサービスなので、バケットやらgcloudコマンドやらが何もせずにスルッと動くのは快適（GAEの認証は一手間かかるが）

例えば、GCSから適当な静的ファイルを配信していて、ソースをgithubで管理してるとなるとマスターにpushするだけで、GCSに適切にファイルをデプロイすることが出来る。その際に、ACLやCORSの設定も一気に **自動** でやってくれるのは何より心強いのではないか？この使い方だったらほぼ無料で使えるっていうのがイイよね。別サービスへアカウント登録もいらないｗｗ

今後GKEやGAEに限らずGCP全般で大活躍していく予感のするGCCBだなという予感
最初とっつきづらいけど、慣れてくると使いやすい。Dockerと考えずにコマンドビルドして、shellがインコグニートモードになってると思えば、苦もなく使えると思います。
安いし速いし、並列度も制限ないし、ハッピーGCCBライフ！

# 未確認情報
将来的には、GAEへのデプロイが簡単になるぽいので更に便利になりそう。
<img width="422" alt="スクリーンショット_2017-05-19_13_19_04.png" src="https://qiita-image-store.s3.amazonaws.com/0/4036/041a7126-c02f-7212-94b5-401f224c4db2.png">