Hybrid connectivity NEG を使ってハイブリッドクラウド環境間の負荷分散を試してみる

Kazuki Uchima
google-cloud-jp
Published in
25 min readOct 15, 2021

はじめに

Cloud Load Balancing で Hybrid connectivity NEG を利用した、ハイブリッド/マルチクラウドでの負荷分散機能 (ハイブリッド負荷分散) がサポートされました。

本記事では Cloud Load Balancing を利用したハイブリッド負荷分散の概要を説明し、また実際にオンプレミス上の Anthos クラスタと Google Cloud 上の GKE クラスタでのパスベースルーティングを試してみます。

tl;dr

  • Hybrid connectivity NEG を利用することにより、オンプレミスや他社クラウド上のプライベートなエンドポイントを Cloud Load Balancing のバックエンドとして指定することができるようになりました。
  • Hybrid connectivity NEG を利用した負荷分散 (ハイブリッド負荷分散) を構成すると、単一の IP アドレスを入り口として、Google Cloud 上のアプリケーションとオンプレミスや他クラウド上にあるアプリケーション間での負荷分散 / パスベースルーティング等が実現可能となります。

Hybrid connectivity NEG (Hybrid NEG) とは

Hybrid connectivity NEG (以降 Hybrid NEG と記載) は、オンプレミスや他社クラウドなど、Google Cloud 以外の環境のエンドポイントを定義する NEG (Network Endpoint Groups)です。

元々、Google Cloud 以外の環境のエンドポイントを定義する仕組みとして Internet NEG という NEG もありましたが、Hybrid NEG は Internet NEG とは異なりプライベートアドレス帯をエンドポイントとして設定することができます。

つまり、これまでオンプレミスなどのエンドポイントを NEG として設定するにはインターネットからアクセス可能なパブリックなエンドポイントを用意する必要があったのですが、Hybrid NEG を利用するとパブリックなエンドポイントを用意する必要がなくなり、 Cloud VPN や Cloud Interconnect 等で接続したプライベートなエンドポイントを NEG として設定することができるようになりました。

その他にも、Internet NEG ではエンドポイントに対するヘルスチェックをサポートしていませんが、Hybrid NEG ではヘルスチェックを構成できるという違いもあります。

Hybrid NEG は現在、Cloud Load BalancingTraffic Director で利用することが可能です。今回はその中でも Cloud Load Balancing を利用した構成にフォーカスして説明します。

ハイブリッド負荷分散のユースケース

Hybrid NEG を使った ハイブリッド負荷分散機能の主なユースケースは以下の通りです:

  1. オンプレミス / 他クラウド上のエンドポイントにトラフィックを転送する

シンプルに外部もしくは内部クライアントから来たトラフィックをオンプレミス / 他クラウド上のエンドポイントに転送するケースです。

ハイブリッド / マルチクラウド上に分散しているエンドポイントを Cloud Load Balancing で公開することにより、単一の IP アドレス (ドメイン) でシンプルに構成することができます。

また、例えば特定のパスであればオンプレミス、それ以外は Google Cloud 上のエンドポイントにトラフィックを転送するといった環境を跨いだ柔軟なトラフィックコントロールを設定することが可能です。

この構成は以下のように Google Cloud 上のサービスと他環境上のサービスを組み合わせるようなユースケースで活用できます。

  • オンプレミスや他クラウド上にある既存アプリケーションを活用したい
  • 機密性が高くオンプレミス上で動かす必要のあるアプリケーションが存在する

2. オンプレミス / 他クラウド上のサービスを Google Cloud へ移行する

Hybrid NEG は内部 HTTP(S) LB でもサポートされているのですが(利用可能な LB 種別については後述します)、Hybrid NEG と内部 HTTP(S) LB の重み付けベースのトラフィック分割を組み合わせると、オンプレミスや他クラウドなど移行元環境と Google Cloud 上のサービス間でトラフィックを分割するような構成が可能となります。

これにより、他環境から Google Cloud 上への段階的な移行も実現することができます。

3. オンプレミス / 他クラウド上のサービスに対する Google Cloud のネットワーク・セキュリティサービスの適用

オンプレミス / 他クラウド上のサービスへのアクセスを Cloud Load Balancing 経由にすることで、以下のような Google Cloud のネットワーク・セキュリティ関連機能を非 Google Cloud 環境でも利用できるようになります。

特にオンプレミス環境では上記のようなマネージド サービスを活用することによる運用負荷の軽減も期待できます。

ハイブリッド負荷分散の構成要素

ここからハイブリッド負荷分散を構成する際に利用されるリソースの概要や注意点について説明します。

Cloud Load Balancing

Hybrid NEG は 2021.10 現在、以下 4 種類のロードバランサで利用することができます。(リージョン外部 HTTP(S) ロードバランシングは現状サポートしていません)

Cloud Interconnect / Cloud VPN

Google Cloud 環境とオンプレミス/他クラウド環境をプライベートに接続するために利用します。

Hybird Connectivity NEG (Hybrid NEG)

オンプレミスや他社クラウドなど、Google Cloud 以外の環境のエンドポイントを定義する NEG です。

Hybrid NEG は NON_GCP_PRIVATE_IP_PORT というネットワークエンドポイントタイプを指定することで作成することができます。

ヘルスチェック

Cloud Load Balancing のヘルスチェック機構を使ってオンプレミス / 他社クラウド上のエンドポイントのヘルスチェックを行います。

そのため、各バックエンドサービスは Google のヘルスチェック プローブ IP 範囲(130.211.0.0/22 と 35.191.0.0/16)からのトラフィックが到達 / 応答できるようにファイアウォールやルーティングを設定する必要があります。

バックエンドサービス

バックエンドサービスには他のタイプの NEG やインスタンスグループをバックエンドとして追加することができません。

そのため Hybrid NEG と Zonal NEG (on Google Cloud)を組み合わせるなど環境を跨いだ負荷分散を構成する場合は、Google Cloud 用に別のバックエンドサービスを作成する必要があります。(次の章で実際の構成イメージについて説明します)

バックエンドの分散モードは、外部 HTTP(S) ロード バランシングの場合 RATE に、TCP / SSL プロキシ ロード バランシングの場合は CONNECTION にする必要があります。

その他制約事項については公式ドキュメントもご確認ください。

実際に試してみる

では実際に Hybrid NEG を使って Anthos clusters on VMware 上のサービスを Cloud Load Balancing 経由で外部公開してみようと思います。

大まかな構成は以下のようになります。

流れは以下の通りです(Anthos クラスタと GKE クラスタは事前に構築されている前提で進めます):

  1. オンプレミスとの VPN 接続
  2. オンプレミス側でのサンプルアプリケーションのデプロイ
  3. Hybrid Load Balancing の設定
  4. オンプレミス / Google Cloud 間でのトラフィック分散を試す
  5. Cloud Armor セキュリティポリシーの有効化

1. オンプレミスとの VPN 接続

まずは Google Cloud とオンプレミス間でプライベートなアクセスができるように VPN を構成します。

はじめに Google Cloud 側で VPN GW を作成します。今回は Static なルート設定しか行わないので Classic VPN を利用します。(本番環境だと HA VPN を利用し、冗長性をとっていただくのが良いと思います)

「リモートピア IP アドレス」にオンプレミス側 VPN 機器の IP アドレスを入力し、「IKE 事前共有キー」に自動生成 or 予め決めておいたキーを入力します。

ルーティングオプションでは、「リモート ネットワーク IP の範囲」にオンプレミス側の IP アドレスレンジを設定し、「ローカル IP 範囲」として Google Cloud VPC 側のサブネットレンジや Cloud Load Balancing のヘルスチェックレンジを指定しておきます。

続いてオンプレミス側の VPN 設定です。今回はオンプレ側は strongSwan を使って Google Cloud との VPN 接続を構成します。

対象のサーバに SSH し、strongSwan をインストールし VPN の各種設定をします。

# strongSwan のインストール
$ sudo apt install strongswan
# VPN の各種設定
$ sudo vi /etc/ipsec.conf
$ cat /etc/ipsec.conf
# ipsec.conf - strongSwan IPsec configuration file
# basic configurationconfig setup
# strictcrlpolicy=yes
# uniqueids = no
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
authby=secret
keyexchange=ikev2
mobike=no
conn gcp
esp=aes128-sha1-modp1024,3des-sha1-modp1024
ikelifetime=600m
keylife=180m
rekeymargin=1m
keyingtries=5
keyexchange=ikev2
left=10.0.10.1
leftsubnet=10.0.10.0/24
leftid=<オンプレ VPN の Global IP>
leftfirewall=yes
right=<Cloud VPN の GW Global IP>
rightsubnet=10.100.10.0/24,10.100.20.0/24,130.211.0.0/22,35.191.0.0/16
auto=add
# 事前共有キーの設定
$ sudo vi /etc/ipsec.secrets

設定完了後、以下のようにトンネルが確立できたら OK です。

$ sudo ipsec restart
$ sudo ipsec up gcp
...省略...
connection 'gcp' established successfully

Cloud VPN 側も接続できていることも確認します。以下のように「VPN トンネルのステータス」が確立済みとなっていれば大丈夫です。

2. オンプレミス側でのサンプルアプリケーションのデプロイ

次にオンプレミスにある Anthos cluster 上で Anthos!!! と叫ぶだけのアプリケーションをデプロイしてみます。

# マニフェストの作成
$ cat << EOF > echo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: echoserver
spec:
replicas: 3
selector:
matchLabels:
app: echoserver
template:
metadata:
labels:
app: echoserver
spec:
containers:
- name: echoserver
image: hashicorp/http-echo
args:
- -listen=:8080
- -text="Anthos!!!"
---
apiVersion: v1
kind: Service
metadata:
name: echo-svc
spec:
type: LoadBalancer
selector:
app: echoserver
ports:
- protocol: TCP
port: 80
targetPort: 8080
loadBalancerIP: 10.0.10.30
EOF
# アプリケーションのデプロイ
$ kubectl apply -f echo.yaml
# Pod / Service がちゃんと作成されていることを確認
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
echoserver-865484cd65-99md5 1/1 Running 0 4d8h
echoserver-865484cd65-9mc49 1/1 Running 0 4d8h
echoserver-865484cd65-rwwx6 1/1 Running 0 4d8h
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo-svc LoadBalancer 10.96.1.237 10.0.10.30 80:32561/TCP 4d8h

作成した Kubernetes Service の External IP アドレスは後々利用するのでメモしておきます。

3. ハイブリッド負荷分散の設定

Cloud Load Balancing のヘルスチェックが通るように VPC ファイアウォールを設定します。(今回の検証環境にはオンプレミス側にファイアウォールが無いので、Google Cloud 側のみ許可設定を入れます)

$ gcloud compute firewall-rules create fw-allow-health-check-vpc01 \
--network=vpc01 \
--action=allow \
--direction=ingress \
--source-ranges=130.211.0.0/22,35.191.0.0/16 \
--rules=tcp:80,tcp:8080

asia-northeast1-a に anthos-tokyo という Hybrid NEG (type: NON_GCP_PRIVATE_IP_PORT) を作成します。

$ gcloud compute network-endpoint-groups create anthos-tokyo \
--network-endpoint-type=NON_GCP_PRIVATE_IP_PORT \
--zone=asia-northeast1-a \
--network=vpc01

Hybrid NEG に先ほど作成したオンプレミス側のサービスをエンドポイントとして追加します。

$ gcloud compute network-endpoint-groups update anthos-tokyo \
--zone=asia-northeast1-a \
--add-endpoint="ip=10.0.10.30,port=80"

続いて、ヘルスチェックとバックエンドサービスを作成します。今回は External HTTP(S) Load Balancing を利用するため load-balancing-scheme として EXTERNAL を指定します。また、Balancing Mode として RATE を指定します。

# ヘルスチェックの作成
$ gcloud compute health-checks create http hybrid-hc \
--use-serving-port
# オンプレミス用バックエンドサービスの作成
$ gcloud compute backend-services create onprem-bs \
--health-checks=hybrid-hc \
--load-balancing-scheme=EXTERNAL \
--global
# オンプレミス用バックエンドサービスに Hybrid NEG を追加
$ gcloud compute backend-services add-backend onprem-bs \
--global \
--network-endpoint-group=anthos-tokyo \
--network-endpoint-group-zone=asia-northeast1-a \
--balancing-mode RATE \
--max-rate-per-endpoint=5

続いて URL マップ、ターゲット HTTP プロキシ、フォワーディングルールを作成します。

# URL マップを作成しオンプレミス用バックエンドサービスを Default Service として追加
$ gcloud compute url-maps create hybrid-um \
--default-service onprem-bs

# ターゲット HTTP プロキシを作成し、先ほど作成した URL マップを指定
$ gcloud compute target-http-proxies create hybrid-proxy \
--url-map=hybrid-um
# サービス公開用 IP アドレスの予約
$ gcloud compute addresses create hybrid-lb \
--global
# フォワーディングルールを作成し、予約した IP アドレスや HTTP プロキシを紐付け
$ gcloud compute forwarding-rules create hybrid-fr \
--address=hybrid-lb \
--target-http-proxy=hybrid-proxy \
--global \
--ports=80

Cloud Shell や自宅端末から予約した IP アドレス向けにアクセスし、想定通りオンプレミス側のサービスにアクセスできることを確認します。

# External IP アドレスの取得
$ export EXTERNAL_IP="$( gcloud compute forwarding-rules describe hybrid-fr --global --format='value(IPAddress)' )"
# オンプレミス側のサービスにアクセスできることを確認
$ curl http://${EXTERNAL_IP}
"Anthos!!!"

無事 Cloud Load Balancing 経由でオンプレミス上のアプリケーションにアクセスできました。

4. オンプレミス / Google Cloud 間でのトラフィック分散を試す

次は Cloud Load Balancing で Google Cloud 上のアプリケーションとオンプレミス上のアプリケーション間のパスベースルーティングを試してみたいと思います。

GKE クラスタに GKE!!! と叫ぶだけのアプリケーションをデプロイしてみます。アプリケーションは gke-tokyo という名前の Standalone NEG として公開します。

# マニフェストの作成
$ cat << EOF > echo-gke.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: echoserver
spec:
replicas: 3
selector:
matchLabels:
app: echoserver
template:
metadata:
labels:
app: echoserver
spec:
containers:
- name: echoserver
image: hashicorp/http-echo
args:
- -listen=:8080
- -text="GKE!!!"
---
apiVersion: v1
kind: Service
metadata:
name: echo-svc
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "gke-tokyo"}}}'
spec:
type: ClusterIP
selector:
app: echoserver
ports:
- protocol: TCP
port: 80
targetPort: 8080
EOF
# サンプルアプリケーションのデプロイ
$ kubectl apply -f echo-gke.yaml
deployment.apps/echoserver created
service/echo-svc created
# Pod / Service がちゃんと作成されていることを確認
$ kubectl get pods
NAME READY STATUS RESTARTS
echoserver-64f897b98c-5c9qc 1/1 Running 0 65m
echoserver-64f897b98c-6hfz5 1/1 Running 0 65m
echoserver-64f897b98c-w7bm5 1/1 Running 0 65m
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
echo-svc ClusterIP 10.248.0.125 <none> 80/TCP 65m

GKE 用のバックエンドサービスを作成し、Standalone NEG をバックエンドとして追加します。

# GKE用バックエンドサービスの作成
$ gcloud compute backend-services create gcp-bs \
--health-checks=hybrid-hc \
--load-balancing-scheme=EXTERNAL \
--global

# gke-tokyo NEG をバックエンドとして追加
$ gcloud compute backend-services add-backend gcp-bs \
--global \
--network-endpoint-group=gke-tokyo \
--network-endpoint-group-zone=asia-northeast1-a \
--balancing-mode RATE \
--max-rate-per-endpoint=5
# /gke にアクセスすると GKE 側にルーティングされるよう URL マップを更新
$ gcloud compute url-maps add-path-matcher hybrid-um \
--default-service onprem-bs \
--path-matcher-name gke \
--path-rules="/gke=gcp-bs"

Cloud Shell や自宅端末から再度アクセスをしてみます。/gke にアクセスしたときのみ GKE!!! と表示されることを確認します。

# Anthos にアクセス
$ curl http://${EXTERNAL_IP}
"Anthos!!!"
# GKE にアクセス
$ curl http://${EXTERNAL_IP}/gke
"GKE!!!"

これでオンプレミス / Google Cloud 環境間でトラフィックを分散させることができました。

5. Cloud Armor セキュリティポリシーの有効化

最後に Cloud Armor を利用しオンプレミス側のサービスも保護できるか試してみます。今回は Cloud Armor のセキュリティポリシーで特定の IP アドレスレンジからのみアクセスができるように構成してみます。

# Cloud Armor セキュリティポリシーを作成
$ gcloud compute security-policies create external-clients-policy \
--description "policy for external clients"
# セキュリティポリシーのデフォルトルールを更新し、すべてのトラフィックを拒否
$ gcloud compute security-policies rules update 2147483647 \
--security-policy external-clients-policy \
--action "deny-404"
# 自分の端末のグローバル IP アドレスを取得
$ export MY_IP=`curl -s http://httpbin.org/ip | jq -r .origin`
# IP アドレスの確認
$ echo ${MY_IP}
34.xx.xx.xx
# 自分の端末の IP アドレスからのトラフィックを許可する Allow Rule を追加
$ gcloud compute security-policies rules create 1000 \
--security-policy external-clients-policy \
--description "allow traffic from My Client IP Range" \
--src-ip-ranges ${MY_IP} \
--action "allow"
# 作成したセキュリティポリシーを各バックエンドサービスに適用
$ gcloud compute backend-services update onprem-bs \
--security-policy external-clients-policy --global
$ gcloud compute backend-services update gcp-bs \
--security-policy external-clients-policy --global

許可された端末からは変わらずアクセスができます。

$ echo ${MY_IP}
34.xx.xx.xx
# Anthos にアクセス
$ curl http://${EXTERNAL_IP}
"Anthos!!!"
# GKE にアクセス
$ curl http://${EXTERNAL_IP}/gke
"GKE!!!"

一方、それ以外の端末からはアクセス不可となります。

$ echo ${MY_IP}
104.yy.yy.yy
# Anthos にアクセス
$ curl http://${EXTERNAL_IP}
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>404</title>404 Not Found%
# GKE にアクセス
$ curl http://${EXTERNAL_IP}/gke
<!doctype html><meta charset="utf-8"><meta name=viewport content="width=device-width, initial-scale=1"><title>404</title>404 Not Found%

これで Google Cloud 側だけでなくオンプレミス側も Cloud Armor で保護ができることが確認できました。

まとめ

Hybrid NEG が利用可能となり、単一の IP アドレスを入り口として、Google Cloud 上のアプリケーションとオンプレミスや他クラウド上にあるアプリケーション間での負荷分散 / パスベースルーティング等を構成できるようになりました。

これによりアーキテクチャの選択肢も広がり、ハイブリッド・マルチクラウドな構成もより現実的になってきたのではないかと思います。

気になった方はぜひお試しください!

参考資料

--

--

Kazuki Uchima
google-cloud-jp

Application Modernization Specialist at Google Cloud. All views and opinions are my own.