見出し画像

【GCS+Pub/Sub+K8s+CloudRun for Anthos】ファイルが追加されたらCloudRunのプログラムが動く仕組みを作るまとめ

GCSにファイルが入る→GCSの更新を検知してPub/Subメッセージが飛ぶ→メッセージを受信した、K8s上に載せたCloudRunForAnthosアプリケーションが動く、という一連の仕組みをリリースするまでの全手順まとめ。長い闘いになるぞ。

ところで、なぜmanagedのCloudRunじゃなくてCloudRunForAnthosを使うのか

managedはお高いので経費削減。それがすべて。「運用中のK8sあるんだから相乗りしちゃえよ」です。
ただしForAnthosは細部で非常に面倒くさいことが頻発するので、GCPのこと聞けば何でも答えてくれるマンが近くに居る状態か、ドキュメント読めばなんでもわかっちゃうマンが手を出すならいいけど、そうじゃないならmanaged使うほうがいいと思う。私は泣きそう。

GCSバケットを作る

GUIから作ればOK。特別な設定は不要。

GCSバケットの変更を監視するPub/Subトピックを立てる

ここを読む。とりあえず大事なのはここ。

gsutil notification create -t TOPIC_NAME -f json gs://BUCKET_NAME

これで、トピックを立てて監視をセットまでまとめてできる。

GCS→Pub/Sub→CloudRun(onGKE)
の、Pubのところまでができました。Subは後で作ります。

GKEにクラスタを用意する

今回はすでにあるクラスタに乗っけるのでここは割愛。
必要になったらまた調べて追記します。

GKEクラスタへアクセスできるようにする

最近(2022年8月現在での最近)認証方法が変わったそうです。
詳細はこちらから

gcloud components install gke-gcloud-auth-plugin

で、アクセス認証用のプラグインをインストールして、

gcloud container clusters get-credentials CLUSTER_NAME

でアクセス先のクラスタ名を指定します。このとき

ERROR: (gcloud.container.clusters.get-credentials) One of [--zone, --region] must be supplied: Please specify location.

と怒られたら、

gcloud container clusters get-credentials CLUSTER_NAME --zone asia-northeast1-a

とクラスタが属しているノードゾーンかリージョンを添えればOK。

kubectl get pod

やってみて、表示されればOK。

この時、一度get-credentialsするとgcloud configを切り替えても、get-credentialsしたときにつなげたクラスタにつながるっぽいので、複数プロジェクトのK8sまたいで開発している場合は今どのクラスタにつながっているかはよく確認。一定期間で認証切れるみたいなので、PODの操作をするたびに gcloud container clusters get-credentials CLUSTER_NAME する。

ここからがとてもすごくやっかい。

この先でやりたいことは

  • GKEクラスタにCloudRunアプリケーションをリリースする

  • Pub/Subサブスクリプションを設定して(=Subを作って)、エンドポイントにCloudRunアプリケーションを指定する

の2点のみです。ただ、「GKEクラスタにCloudRunアプリケーションをリリースする」の準備も大変なら、「Pub/SubサブスクのエンドポイントにCloudRunを指定する」のも大変です。やることがいっぱいあります。

そして、「最終目的Aを実行するにはその準備のBとCが必要で、Bをするためにはさらに準備のDが必要で…」というおそろしマトリョシカになっているので、マトリョシカの外側から一個ずつやっていきます。

GKEクラスタ上にネームスペースを作る

なくてもいいんですが、一つのクラスタ上に複数の違うアプリケーションを載せる場合、あった方が管理が楽です。

kubectl create namespace MY-NAMESPACE

KSA(KubernetesServiceAccount)とGSA(GoogleServiceAccount)を発行してバインドする

K8sから各種GCPリソースにアクセスしたいときに認証情報として使うやつです。なので、デプロイするCloudRunアプリがほかのGCPリソースにアクセスする必要がないならこの部分はやらなくてもいいです、たぶん。

GSAを発行する

$ gcloud iam service-accounts create GSA_ACCOUNT_NAME

サービスアカウント名は「プロジェクト名-GSA」とか、GSAであることが分かりやすいようにしておくとよろしいかと

KSAを発行する

$ call kubectl create serviceaccount KSA_ACCOUNT_NAME --namespace NAMESPACE

こちらも「プロジェクト名-KSA」とかにするとわかりやすい。

GSAとKSAの間にIAM Policy Bindingを作成する

権限エラーでできないときは、自分のアカウントに「サービスアカウント管理者」権限を付ける

$ gcloud iam service-accounts add-iam-policy-binding ^
--role roles/iam.workloadIdentityUser ^
--member "serviceAccount:PROJECT-ID.svc.id.goog[K8S-NAMESPACE/KSA_ACCOUNT_NAME]" ^
GSA_ACCOUNT_NAME@PROJECT-ID.iam.gserviceaccount.com

KSAにGSAへのアノテーションを追加する

kubectl annotate serviceaccount KSA_ACCOUNT_NAME ^
--namespace NAMESPACE ^
iam.gke.io/gcp-service-account=GSA_ACCOUNT_NAME@PROJECT-ID.iam.gserviceaccount.com

ここでいったんアカウント設定まわりはおわり。

環境変数を管理するためのConfigMapを設定する

環境変数を登録する際、複数のアプリケーションで使いまわす可能性があり、変更があった場合はすべてを一斉に変更しないとならない値(共通で使うAPIのURLなど)はConfigmapという仕組みを使うと便利です。
使いまわせる任意のキーと値のペアを格納しておけます。

kubectl create configmap CONFIGMAP-NAME -n NAMESPPACE --from-literal=KEY=VALUE

--from-literal以降を複数回繰り返して書けば、一度に複数ペアを登録しておけます。
これで「CONFIGMAP-NAME」という名前のオブジェクトが作られるイメージ。その中にキーと値のペアが複数個保存される。

CloudRunアプリをデプロイする

やっとここまでたどり着けました。
これだけでもまたなかなか一苦労なので別記事に…
この時、先ほど設定したKSAを認証情報として登録するのを忘れない。

ドメインマッピングを行う

この後の処理でURLによるアクセスが必要になるので、サービスにドメインを割り当てます。

ドメインをとる

まず何かしらのドメインを取得しておきます。ちょっとお値段は張りますがGoogleDomainsを使うと認証が省略できるので楽です。
1サービスに1ドメイン割り当てるぜーたくをするなら、DNSサーバーへの登録は後回しにしておきます。(IPがまだ発行されていないので)
サブドメインを発行して複数サービスに1つのドメインを割り当てる場合は、なにかしらの情報で登録してしまって大丈夫です。

ドメインをサービスに割り当てる

GCPコンソールでAnthos>CloudRunForAnthosのページを開き、ADD MAPPING>ADD SERVICE DOMAIN MAPPINGの順に選択します。

上のドロップダウンから、ドメインを設定したいサービスを選択。

下の入力欄に、割り当てたいドメインを入力して、OK。
このとき、「sample.com」が取得してあったとして、1サービスに1ドメインなら「sample.com」と入力するし、サブドメインを使うなら「subdomain.sample.com」と入力します。

次の画面で発行されたIPアドレスをコピーして、完了を押します。

DNSサーバーにドメインとIPを登録する

ここで発行されたIPアドレスを、サブドメインに設定してDNSサーバーに登録します。この辺の処理方法は各ドメインの管理サイトで確認してください。
なお、DNSサーバーへの登録が反映されるのに最大24時間くらいかかる場合があるので、しばらく放っておきます。

これでURLでアクセスできるようになりました。

…あっ、HTTPS通信できないとこの先のPub/Subで突っかかるので、HTTPS通信できるようにしておいてください。何らかの形で。

Pub/Subのサブスクリプションを作ってアプリケーションと関連付ける

GUIからつくるとやりやすい。
エラー時に永遠に送り続けることがないように保持時間の上限設定しておいた方がいいです。逆に、有効期限はなしにしておかないと久々に使おうと思ったら消えてたりします。(使っていない場合リソース削減できるようにしたい場合は有効期限付けておくのがいい)

配信タイプをpushにして、エンドポイントに先ほど設定したドメインを設定すれば完了です。

で、このとき、CloudRunForAnthosは認証されたアクセスのみ受け入れる設定ができないので(managedならできるんだけどね…)アプリケーションの方で変なアクセスをはじく対策が必要なので注意。

お疲れ様でした。うひぃ長い闘いだった…

この記事が気に入ったらサポートをしてみませんか?