サーバレスVPCアクセスとInternal LBでGAE=>GKEを内部通信にする
GAE(Google App Engine)で動いているアプリケーションから、GKE(Google Kubernetes Engine)のクラスタにいるAPIを叩くことになったのですが、インターネットを経由するのが嫌で、GCP内部に閉じたやり方をしたのでご紹介します。
構成概要
GAEのアプリケーションはスタンダード環境、GKEは限定公開クラスタになっていて、private
という名前のVPCネットワークに入っています。APIのServiceはInternal Load BalancerにしてVPC内にエンドポイントを晒し、GAEはサーバレスVPCアクセスコネクタ経由でこのVPCにアクセスしています。あとは気持ちの問題ですが、APIのIPアドレス直叩きはなんか微妙だったので、Cloud DNSでGCP内部解決用のドメインを設定しました。
GAEのアプリケーションにVPCアクセスコネクタを設定する
まずはVPCアクセスコネクタを作成します。公式のドキュメントにしたがって進めれば簡単にできます。
VPCアクセスコネクタの作成が完了したら、app.yamlに設定を追加します。公式のドキュメントにある通り、追加する設定は以下のように書きます。
# app.yaml
vpc_access_connector:
name: projects/{PROJECT_ID}/locations/{REGION}/connectors/{CONNECTOR_NAME}
先に作成したVPCアクセスコネクタについて、PROJECT_ID
、REGION
、CONNECTOR_NAME
を埋めて gcloud app deploy
コマンドでデプロイすれば完了です。
Internal Load Balancerを設定する
Serviceの種類をInternal Load Balancerにすることで、VPCネットワーク内部からのみアクセスできるようになります。難しい設定は特に必要なく、cloud.google.com/load-balancer-type: "internal"
というアノテーションをつけるだけです。
apiVersion: v1
kind: Service
metadata:
name: myapi
annotations:
cloud.google.com/load-balancer-type: "internal"
spec:
type: LoadBalancer
loadBalancerIP: {LOAD_BANANCER_IP} #最初コメントアウトしておく
selector:
app: myapi
ports:
- name: web
port: 80
targetPort: 8080
loadBalancerIP
は作成時に自動的に割り振られるので、最初はコメントアウトしておいて、割り振られたら {LOAD_BALANCER_IP}
に入れます。割り振られているかどうかは、kubectlコマンドで確認できます。割り振られると下のようにEXTERNAL-IP
にVPCネットワーク内のIPアドレスが表示されます。
kubectl get svc myapi
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapi LoadBalancer 10.0.18.117 192.168.32.55 80:32179/TCP 1m
Cloud DNSで内部通信用のドメインを設定する
ここまでで、GAEのアプリケーションからVPCネットワークに接続し、GKE上で稼働するAPIにIPアドレスでアクセスできるようになりました。上の例だと、GAEのアプリケーション内からhttp://192.168.32.55
を指定すればAPIにつながる状態になっています。
ここからは気持ちの問題なのですが、このIPアドレスに内部用のDNS名を設定します。これは非常に簡単にできます。
Cloud DNSのWebコンソールを開き、ゾーンを作成ボタンからフォームを開きます。
フォームに必要情報を入力してゾーンを作成します。ゾーンのタイプを非公開にして、ネットワークには当該のVPCネットワークを指定します。非公開ネットワークのDNSなので、すでに使っているものでなければ好きなドメインを設定できます。下の例では、api.private
という名前にしました。
作成が完了すると、DNSゾーンのページが表示されます。
あとは、先ほどのIPに紐づけてAレコードを追加すれば完了です。めでたく、http://my.api.private
という名前でアクセスできるようになりました。
まとめ
この記事では、GAEからGKEに内部通信する方法をご紹介しました。
僕たちのチームでは、アプリケーションにはGAE、データ関連のバッチ処理などのためにGKE上にArgoを立てて利用しているのですが、アプリケーションからArgoのRest APIにアクセスしたい要件があり今回ご紹介した方法で実装しました。
最初は外向きにIPを公開しないといけないかもと思って認証をどうするかとかも考えていたのですが、サーバレスVPCアクセスとInternal Load Balancerのおかげで内部に閉じた作りにすることができてよかったです。
この記事がもし何かの参考になれば嬉しいです。
Discussion