Enjoy Architecting

Twitter: @taisho6339

【GCP Anthos】 Regionに跨って冗長化したKubernetsのマルチクラスタをロードバランシングする

Anthosとは?

本記事の目的

本記事ではマルチクラスタを構築し、Anthosの機能を使ってクラスタにまたがって負荷分散することができるかに焦点をあてる。 GKE HubのIngress For Anthosという機能を用い実現する。 本当はマルチクラウドクラスタで負荷分散させたかったが、GKE以外のクラスタはまだサポートされていないようだ。

Anthosへのクラスタ登録とクラスタモニタリングの仕組み

Anthosはクラスタ管理のため、各クラスタ内にGKE Connector Agentをデプロイする。 このAgentがAnthosに情報を集約し、Anthosのコントロールプレーンからの命令を各クラスタで実行することになる。 AgentがAnthosの命令を実行する流れ 引用: https://cloud.google.com/anthos/multicluster-management/connect/security-features

Ingress For Anthosのアーキテクチャ

Anthosによるクラスタ間のロードバランシングは、Ingress For Anthosという仕組みを用いて実現する。 これは下記イメージのようなアーキテクチャになっている。

アーキテクチャ 引用: https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-for-anthos

登場人物について

  • Config Cluster

    • Ingress For Anthosの設定リソースを配置するクラスタ
    • アプリケーション用のクラスタと一緒にしてもいいが、Config Clusterの障害がサービス影響を出さないためにも分離しておいたほうが良い
  • Anthos Member Cluster

  • Anthos Ingress Controller

    • クラスタの外でGoogleマネージドで稼働しているグローバルなIngress Controller
    • Config Clusterを監視し、リソース作成、変更のタイミングでクラスタ間ロードバランシングの設定を行う
  • MultiClusterService(MCS)

    • クラスタに作成されるServiceのテンプレートであり、MultiClusterIngressから参照するServiceの論理的な単位となる
      • MultiClusterIngressはこのMultiClusterServiceを指定してルーティングする
    • このリソースが作成されると、各クラスタにテンプレートから生成されたServiceが作成される
  • MultiClusterIngress(MCI)

    • このリソースが作成されると、GCLBとZone NEG(MCSによって各クラスタに作成されたServiceに紐づく)が作られ、GCLBのバックエンドにはNEGが紐付けられる

動作イメージ

  • MultiClusterIngressがConfig Clusterに作成されたタイミングで、Anthos Ingres Controllerが単一のGCLBを作成し、それぞれのクラスタに紐づくZone NEGをバックエンドとしてぶら下げる
    • このNEGは、MultiClusterServiceを元に各クラスタに作成されたServiceにルーティングされる
    • 一つのNEG(クラスタ)へのアクセスが正常でない場合、すぐに別のNEGへfallbackされる

Config Clusterの可用性について

当然疑問に上がってくるのは、Config Clusterの可用性はどう担保するのか?というところ。 ちなみにConfig Clusterが死ぬとMultiClusterIngressとMultiCluserServiceの設定変更ができなくなる。 つまりすでに適用した設定でのロードバランシングには影響しないが、なるべくRegionalなクラスタで運用するようなどしたほうが良い。 ただ、個人的にはサービスダウンに直結するわけではない & MultiClusterServiceとMultiClusterIngressを頻繁にメンテすることはあんまりなさそうなのでそこまでガチな可用性はなくても良さそうに感じている。 (ここにマルチクラスタ冗長化とかあんまやりたくはない...)

実際に動かしてみる

セットアップ

GKEクラスタをAnthosのクラスタメンバーに登録

gcloud container hub memberships register  gke-anthos-asia    \
   --project=[project_name] \
   --gke-cluster=asia-northeast1-a/gke-anthos-asia \
   --service-account-key-file=./service-account.json
gcloud container hub memberships register gke-anthos-eu   \
   --project=[project_name] \
   --gke-cluster=europe-north1-a/gke-anthos-eu \
   --service-account-key-file=./service-account.json

ConfigクラスタをAnthosに設定

gcloud alpha container hub ingress enable \
  --config-membership=projects/[project_name]/locations/global/memberships/gke-anthos-config

アプリケーションのデプロイ

結果

  • クラスタがAnthosのメンバーとして認識された様子(本記事の手順では割愛しているが、EKSも検証のため入れてみた) f:id:taisho6339:20200506210718p:plain

  • ロードバランサーのバックエンドに自動的に作成されたNEGが紐付いている f:id:taisho6339:20200506210647p:plain

  • 中身はクラスタのMultiClusterServiceによって作成されたHeadlessServiceから取得されたPodのIPに紐付いている f:id:taisho6339:20200506210714p:plain

  • 試しにcurlしてみると、GCLBがAnyCastで最寄りのクラスタ(ネットワーク的に)にルーティングしてくれるため、常に東京クラスタの結果が帰ってくる

❯❯❯ curl 34.107.232.154/ping
{"Hostname":"34.107.232.154","Version":"1.0","GCPZone":"asia-northeast1-a","Backend":"zone-ingress-5f6ff94966-2phdz"}%

試しにAsiaクラスタを殺してみる

  • deploymentを殺し、Podが存在しないようにする
❯❯❯ kubectl delete -f deployment.yaml
deployment.apps "zone-ingress" deleted
❯❯❯ curl 34.107.232.154/ping
{"Hostname":"34.107.232.154","Version":"1.0","GCPZone":"europe-north1-a","Backend":"zone-ingress-5f6ff94966-7hlt7"}%

まとめ

GKEのクラスタであればかんたんにロードバランシングできるので、 クラスタ自体のアップデートをしたいが、ダウンタイムを許容したくないときやRegion障害などに活用できそうだということがわかった。 EKSなどのサポートも進めばよりいっそう便利なので対応を待望しています。

参考