ニフクラ ブログ

ニフクラ/FJ Cloud-Vやクラウドの技術について、エンジニアが語るブログです。

ニフクラでKubernetesを使う方法(第4回. マルチクラスタメッシュ構成_疎通確認編 )

こんにちは、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環境)が出力されて両方にアクセスして、ネットワーク間で分散アクセスしていることが確認できます。

以上で疎通確認は完了です。

②環境構築:外部インターネット、マルチクラウド環境間のアクセス設定

インターネットからマルチクラウド環境にアクセスするために以下の設定をおこないます。

マルチクラスタ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月時点の情報です。