エンジニアの桂です。
Jenkins を管理し続けるのが辛くなってきたので、GCP の Cloud Build でデプロイする方法を模索しました。
基本的なデプロイはまあまあすんなり出来たんですが、限定公開クラスタ (private cluster) の IP 制限で蹴られてしまってクラスタの操作ができないという問題でどハマりしてしまいました。
結論から言うと、マスター承認済みネットワーク (master authorized networks) を動的に変更すると言うワークアラウンドで回避するのが一番簡単じゃないか、と言うところに落ち着きました。
背景
Stack Overflow の Google 関係者によるものと思われる回答によると、
It’s currently not possible to add Cloud Build machines to a VPC. Similarly, Cloud Build does not announce IP ranges of the build machines. So you can’t do this today without creating a “ssh bastion instance” or a “proxy instance” on GCE within that VPC.
ということで、2018/08 時点、そしておそらく現時点 (2019/09) でも限定公開クラスタへ Cloud Build でそのままデプロイするということは不可能なようです。
bastion とか proxy インスタンス作るのは大仰だし面倒だし結構気をつけとかないと重大なセキュリティホールになるので、やりたくないですね。そこで、冒頭のワークアラウンドが候補に上がります。
手順
それでは、マスター承認済みネットワークを動的に変更する変更を具体的に紹介します。
通常利用する IP アドレスに加え、 Cloud Build サーバのパブリック IP を動的に取得して、 gcloud container clusters update
でマスター承認ネットワークを変更しています。
事前準備
container.clusters.update 権限が必要なので、その権限を持つ role を Cloud Build のサービスアカウントに設定します。
gcloud projects add-iam-policy-binding ${PROJECT_ID} --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com --role=roles/container.clusterAdmin
Cloud Build YAML
Cloud Build ワーカーの IP アドレスを inet-ip.info などを使って特定し、マスター認証済みネットワークに設定します。
- id: permit to access to the cluster
name: gcr.io/cloud-builders/gcloud
entrypoint: bash
args:
- -c
- |
BUILDER_IP=$(curl inet-ip.info)
gcloud container clusters update $_CLOUDSDK_CONTAINER_CLUSTER --zone $_CLOUDSDK_COMPUTE_ZONE \
--enable-master-authorized-networks --master-authorized-networks=xxx.xxx.xxx.xxx/32,yyy.yyy.yyy.yyy/32,$${BUILDER_IP}/32
許可したマスター承認済みネットワークはクラスタ操作完了後、同様の手順で元に戻しておきます。
Pros and cons
利点
- 簡単
欠点
- 非限定公開クラスタよりは安全だが、やや脆弱になる
- Cloud Build サービスアカウントにクラスタ操作を許可する必要がある
- IP リストを GCP コンソール上から変更してもデプロイ時に上書きされる
- [多分] クラスタ設定コンソールでは IP に名前をつけられるが、
gcloud
ではできない
あとがき
正直ダサいですが、近い将来きっと Google が公式の手法を提供してくれると信じたいですね。
ジラフでは GCP の beta 版に足りない機能をいい感じに工夫して解決してくれる仲間から、オフィスの雰囲気をいい感じにしてくれるメンバーまで幅広く募集してます。興味があったらぜひご連絡ください!