この記事は、ニフクラブログで2023-10-17に公開された記事を移転したものです。
こんにちは、CRE部 技術支援チームです。
今回で最終回です。
第1回、第2回、第3回で構築したマルチクラウド環境のマルチクラスタメッシュ(他社サイトリンク)構成にしたKubernetesクラスタで負荷分散を確認する検証を実施します。
第1回. Anthos on bare metalクラスタインストール・作成編
第2回. マルチクラウド環境構築_VPN接続編
第3回. マルチクラスタメッシュ構成_East-WestGateway作成編
第4回. マルチクラスタメッシュ構成_疎通確認編
- はじめに
- 前提条件
- 利用リソース
- ①マルチクラスタメッシュ構成の疎通確認
- ②環境構築:外部インターネット、マルチクラウド環境間のアクセス設定
- ②検証実施:外部インターネット環境からマルチクラウド環境疎通確認
- ➂アクティブ・アクティブ構成を想定した冗長化確認
- まとめ
- 注意事項
はじめに
今回は以下の検証を実施して、Kubernetesクラスタ負荷分散と可用性の確認としてKubernetesクラスタの冗長化を確認します。
①. マルチクラスタメッシュのロードバランシングが稼働してニフクラとGoogleCloudのKubernetesクラスタ間で負荷分散されているかを確認します。
②. マルチクラスタメッシュの環境にインターネットからアクセスするために外部ロードバランサーとしてMultiClusterIngress・MultiClusterService(他社サイトリンク)をGoogleCloud環境に作成してGoogleCloudのKubernetesクラスタ間で負荷分散されているかを確認します。
③. 上記②. の環境でニフクラ側(Anthos on bare metalクラスタ)が停止した場合、 GoogleCloud側(GKEクラスタ)が稼働して冗長化が担保されていることを確認します。(アクティブ・アクティブ構成)
全体構成イメージ
前提条件
- ニフクラの基本的なコントロールパネルの操作、サービスを利用する知識
- GoogleCloudの基本的なコントロールパネルの操作、サービスを利用する知識
- Kubernetesの基本的な知識、利用経験
- Google Kubernetes Engine(GKE)クラスタの基本的な知識、利用経験
- Istio(他社サイトリンク)等のサービスメッシュの基本的な知識、利用経験
- GoogleCloudのアカウントを取得済み
- GoogleCloudにプロジェクトが作成済み
利用リソース
前回までにニフクラとGoogleCloudで作成したリソースを利用します。
①マルチクラスタメッシュ構成の疎通確認
マルチクラスタメッシュになっているニフクラとGoogleCloud間の疎通確認を実施します。 ASMパッケージのサンプルpod、service(他社サイトリンク)を各クラスタにデプロイします。 今回は以下のサンプルを使用します。
- sleep(他社サイトリンク)。疑似的なアクセス実行に使用します。curl がインストールされた ubuntu コンテナのpod、serviceを作成します。
- helloworld(他社サイトリンク)。呼び出されたときにhelloの文字列、バージョン、インスタンス (ホスト名) を返却するWEBアプリのpod、serviceを作成します。
個別コマンドを実行して作成しても良いのですが、今回は以下の内容でシェルを作成します。
- ニフクラ環境、GoogleCloud環境にsampleという名前空間を作成します。
- ニフクラ環境、GoogleCloud環境の名前空間sampleにサイドカー プロキシ インジェクション有効ラベルを作成します。名前空間sample上のpod、serviceがASMの各種機能が有効になります。詳細はサイドカー プロキシ インジェクションのガイド(他社サイトリンク)を参照してください。
- ニフクラ環境、GoogleCloud環境の名前空間sampleにsleepのpod、serviceを作成します。
- ニフクラ環境、GoogleCloud環境の名前空間sampleにhelloworldのpod、serviceを作成します。
- helloworldの応答が判別できるようにニフクラAnthosクラスタ(v1)、GKEクラスタ(v2)のラベルタグを付与します。
$ ./set_sample.sh namespace/sample created label "istio-injection" not found. namespace/sample labeled serviceaccount/sleep created service/sleep created ---------省略---------
set_sample.sh
#!/bin/bash
for CTX in ${CTX_CLUSTER1} ${CTX_CLUSTER2}
do
#ニフクラ環境、GoogleCloud環境にsample名前空間作成
kubectl create --context=${CTX} namespace sample
#ニフクラ環境、GoogleCloud環境にサイドカー プロキシ インジェクション設定
kubectl label --context=${CTX} namespace sample \
istio-injection- istio.io/rev=asm-1175-9 --overwrite
#ニフクラ環境、GoogleCloud環境の名前空間sampleにsleepのpod、serviceを作成
kubectl apply --context=${CTX} \
-f asm_output/istio-1.17.5-asm.9/samples/sleep/sleep.yaml -n sample
done
#ニフクラ環境の名前空間sampleにhelloworldのserviceを作成
kubectl create --context=${CTX_CLUSTER1} \
-f asm_output/istio-1.17.5-asm.9/samples/helloworld/helloworld.yaml \
-l service=helloworld -n sample
#ニフクラ環境の名前空間sampleにhelloworldのpod(v1ラベルタグ付与)を作成
kubectl create --context=${CTX_CLUSTER1} \
-f asm_output/istio-1.17.5-asm.9/samples/helloworld/helloworld.yaml \
-l version=v1 -n sample
#GoogleCloud環境の名前空間sampleにhelloworldのserviceを作成
kubectl create --context=${CTX_CLUSTER2} \
-f asm_output/istio-1.17.5-asm.9/samples/helloworld/helloworld.yaml \
-l service=helloworld -n sample
#GoogleCloud環境の名前空間sampleにhelloworldのpod(v2ラベルタグ付与)を作成
kubectl create --context=${CTX_CLUSTER2} \
-f asm_output/istio-1.17.5-asm.9/samples/helloworld/helloworld.yaml \
-l version=v2 -n sample
以下のコマンドでニフクラAnthosクラスタから擬似的なcurlコマンドのアクセスを実施するsleepのpodを実行します。
$ kubectl exec --context="${CTX_CLUSTER1}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_CLUSTER1}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
v1(ニフクラ環境)とv2(GoogleCloud環境)が出力されて両方にアクセスしていることが確認できます。ネットワーク間で分散アクセスしていることが確認できます。
以下のコマンドでGKEクラスタから擬似的なcurlコマンドのアクセスを実施するsleepのpodを実行します。
kubectl exec --context="${CTX_CLUSTER2}" -n sample -c sleep \ "$(kubectl get pod --context="${CTX_CLUSTER2}" -n sample -l \ app=sleep -o jsonpath='{.items[0].metadata.name}')" \ -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
こちらも、v1(ニフクラ環境)とv2(GoogleCloud環境)が出力されて両方にアクセスして、ネットワーク間で分散アクセスしていることが確認できます。
以上で疎通確認は完了です。
②環境構築:外部インターネット、マルチクラウド環境間のアクセス設定
インターネットからマルチクラウド環境にアクセスするために以下の設定をおこないます。
マルチクラスタメッシュ外からアクセスするためにIstio-IngressGateway・MeshIngress(他社サイトリンク)を作成します。
インターネットからアクセスするために外部ロードバランサーとしてMultiClusterIngress・MultiClusterService(他社サイトリンク)をGoogleCloud環境に作成します。
Istio-IngressGatewayからアプリケーション(pod、service)にアクセスするためにVirtualService(他社サイトリンク)を作成します。
マルチクラスタIngress機能を有効化
gcloudコマンドを実行してGKEクラスタのマルチクラスタIngress機能を有効化します。 ※以下の場合はGKEクラスタの「2」を選択します。
$ gcloud container hub ingress enable Please specify a membership: [1] global/nifc-anthosbm-cls [2] us-central1/nifc-anthosgke-cls [3] cancel Please enter your numeric choice: 2
名前空間作成
以下のコマンドを実行して各クラスタにIstio-IngressGateway用の名前空間(isito-gateway)を作成します。 ASM機能を有効にするために「istio-injection- istio.io/rev=asm-ASMのバージョン」でラベルを作成します。
for CTX in ${CTX_CLUSTER1} ${CTX_CLUSTER2} do kubectl create --context=${CTX} namespace nifc-istio-gateway kubectl label --context=${CTX} namespace nifc-istio-gateway istio-injection- istio.io/rev=asm-1175-9 --overwrite done
Istio-IngressGateway編集
ASMパッケージのIstio-IngressGateway構成を利用してIstio-IngressGateway、MultiClusterServiceを作成します。
cpコマンドでIstio-IngressGatewayサンプル定義ファイル群のディレクトリをnifc-istio-ingressgatewayとしてコピーします。
$ cp -r asm_output/samples/gateways/istio-ingressgateway nifc-istio-ingressgateway
mkdirコマンドでMultiClusterIngress定義ファイルを格納するディレクトリを作成します。
$ mkdir -p nifc-istio-ingressgateway/multicluster
mvコマンドでMultiClusterServiceファイルに置き換えます。
$ mv nifc-istio-ingressgateway/service.yaml nifc-istio-ingressgateway/multicluster/multiclusterservice.yaml
viコマンドでMultiClusterService用のmulticlusterservice.yamlの編集します。
※編集項目の詳細はMultiClusterServiceリソース(他社サイトリンク)
$ vi nifc-istio-ingressgateway/multicluster/multiclusterservice.yaml
内容は以下です。
multiclusterservice.yaml
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# apiVersion: v1
# kind: Service
# metadata:
# name: istio-ingressgateway
# labels:
# app: istio-ingressgateway
# istio: ingressgateway
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: istio-ingressgateway
annotations:
cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}'
labels:
app: istio-ingressgateway
istio: ingressgateway
#spec:
# ports:
# # status-port exposes a /healthz/ready endpoint that can be used with GKE Ingress health checks
# - name: status-port
# port: 15021
# protocol: TCP
# targetPort: 15021
# # Any ports exposed in Gateway resources should be exposed here.
# - name: http2
# port: 80
# - name: https
# port: 443
# selector:
# istio: ingressgateway
# app: istio-ingressgateway
# type: LoadBalancer
spec:
template:
spec:
ports:
# status-port exposes a /healthz/ready endpoint that can be used with GKE Ingress health checks
- name: status-port
port: 15021
protocol: TCP
targetPort: 15021
# Any ports exposed in Gateway resources should be exposed here.
- name: http2
port: 80
- name: https
port: 443
selector:
istio: ingressgateway
app: istio-ingressgateway
viコマンドでMultiClusterIngress用にmulticlusteringress.yamlを作成します。
※編集項目の詳細はMultiClusterIngressリソース(他社サイトリンク)を参照してください。
$ vi nifc-istio-ingressgateway/multicluster/multiclusteringress.yaml
内容は以下です。
multiclusteringress.yaml
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: istio-ingressgateway
labels:
app: istio-ingressgateway
istio: ingressgateway
spec:
template:
spec:
backend:
serviceName: istio-ingressgateway
servicePort: 80
viコマンドでヘルスチェック用のbackendconfig.yamlを作成します。
※編集項目の詳細はBackendConfigの構成(他社サイトリンク)を参照してください。
$ vi nifc-istio-ingressgateway/multicluster/backendconfig.yaml
内容は以下です。
backendconfig.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: ingress-backendconfig
spec:
healthCheck:
requestPath: /healthz/ready
port: 15021
type: HTTP
Istio-IngressGateway作成
マルチクラスタメッシュ外からアクセスするためにIstio-IngressGatewayを作成します。
以下のコマンドを実行してIstio-IngressGatewayを作成します。
for CTX in ${CTX_CLUSTER1} ${CTX_CLUSTER2} do kubectl apply --context=${CTX} \ -f nifc-istio-ingressgateway -n nifc-istio-gateway done horizontalpodautoscaler.autoscaling/istio-ingressgateway created deployment.apps/istio-ingressgateway created ---------省略---------
VirtualService作成
Istio-IngressGatewayからアプリケーション(pod、service)にアクセスするためにVirtualServiceを作成します。
ASMパッケージのhelloworld-gatewayサンプルを、そのまま利用します。
以下のコマンドを実行してsample空間にVirtualServiceを作成します。
for CTX in ${CTX_CLUSTER1} ${CTX_CLUSTER2} do kubectl apply --context=${CTX} \ -f asm_output/istio-1.17.5-asm.9/samples/helloworld/helloworld-gateway.yaml -n sample done gateway.networking.istio.io/helloworld-gateway created virtualservice.networking.istio.io/helloworld created gateway.networking.istio.io/helloworld-gateway created virtualservice.networking.istio.io/helloworld created
MultiClusterIngress、MultiClusterService作成
インターネットからアクセスするためにGoogleCloud環境のGKEクラスタにMultiClusterIngress、MultiClusterServiceを作成します。 kubectl コマンドを実行してGoogleCloud環境のGKEクラスタにMultiClusterIngress、MultiClusterServiceを作成します。
$ kubectl apply -f nifc-istio-ingressgateway/multicluster -n nifc-istio-gateway --context=${CTX_CLUSTER2} backendconfig.cloud.google.com/ingress-backendconfig created multiclusteringress.networking.gke.io/istio-ingressgateway created multiclusterservice.networking.gke.io/istio-ingressgateway created
kubectl コマンドを実行して発行されたMultiClusterIngressのグローバルIPを確認します。
$ kubectl get MultiClusterIngress -o custom-columns=VIP:status.VIP --no-headers --context=${CTX_CLUSTER2} -n nifc-istio-gateway xxx.xxx.xxx.xxx(発行されたグローバルIP)
以上でメッシュ環境への外部アクセス設定は完了です。
②検証実施:外部インターネット環境からマルチクラウド環境疎通確認
発行されたMultiClusterIngressのグローバルIPにcurlコマンドを実行して外部からアクセスできることを確認します。
curlコマンドを複数回実行します。
$ for x in `seq 1 10`; do curl http://xxx.xxx.xxx.xxx(発行されたグローバルIP)/hello; done
ネットワーク間で分散アクセスしていることが確認できます。
ブラウザでF5ボタンを連打してアクセスすることで分散して切り替わりすることが確認できます。
以上で外部からマルチクラスタメッシュ環境への疎通確認は完了です。
➂アクティブ・アクティブ構成を想定した冗長化確認
ニフクラ環境のAnthosクラスタが停止した場合、GoogleCloud環境のGKEクラスタが稼働してサービスが継続することを確認します。
kubectl コマンドでレプリカ設定を変更してAnthosクラスタのアプリケーションを停止します。 Anthosクラスタのアプリケーション名を取得します。
$ kubectl -n sample get deploy --context=${CTX_CLUSTER1} NAME READY UP-TO-DATE AVAILABLE AGE helloworld-v1 1/1 1 1 4h59m sleep 1/1 1 1 4h59m
kubectl コマンドでレプリカ設定を「0」に変更してAnthosクラスタのアプリケーションを停止します。
kubectl scale deployments helloworld-v1 --replicas=0 -n sample --context=${CTX_CLUSTER1}
再度curlコマンドを複数回実行します。
$ for x in `seq 1 10`; do curl http://xxx.xxx.xxx.xxx(発行されたグローバルIP)/hello; done
GoogleCloud環境のGKEクラスタが動いてサービスが継続していることを確認できます。
まとめ
今回はニフクラでKubernetesサービスを利用したいが、できないという課題をGoogleCloudのAnthos on bare metalを利用することで解決しました。 そこから、アイデアを広げてKubernetesクラスタの負荷分散システムを構築するまで紹介することができました。
今回の検証アイデア以下の考えがもとになっています。
ニフクラで 「存在しない・提供していない」 サービスでも他社クラウド連携・マルチクラウドを利用すればニフクラ上で実現可能という事がご理解いただけたと思います。 他社クラウドの知識も必要なので慣れていないと構築作業も大変ですが、ニフクラにないサービスが使えるのは大きなメリットです。
今後、もしニフクラで提供されていないサービスが必要になった場合に、 他社クラウド連携 、 マルチクラウド というキーワードを思い出していただければ解決の糸口になると思います。
最後までお読みくださいましてありがとうございました。
注意事項
- 本記事に記載されている会社名、製品名等の固有名詞は各社の商号、登録商標または商標です。
- 本記事の他社サイトへのリンクにつきまして、リンク切れの際はご容赦ください。
- 本記事は、2023年10月時点の情報です。