Tanzu Application Platform Tanzu アプリケーションのモダナイゼーション

Tanzu Application Platform の API ゲートウェイ機能 – Spring Cloud Gateway for Kubernetes のご紹介

VMware Tanzu Application Platform (以降 TAP )のバージョン 1.5 から Spring Cloud Gateway for Kubernetes が同梱されました。この機能は、これまで TAP に不足していた API ゲートウェイ機能を補完するものです。このブログでは、Spring Cloud Gateway for Kubernetes を紹介します。

その Source2URL の URL 大丈夫?

TAP の一つの主要な機能、それが Source2URL であり、ソースコード( Source )を TAP がうけつけ、アクセス可能なエンドポイント( URL )を自動的に提供するというものです。これにより、開発者が Kubernetes やコンテナの技術習得をせずとも、高速にかつ高品質にサーバーに展開できるようになるものです。

しかしながら、ここで一つの疑問を投げかけます。本当にその URL はインターネットにやみくもに公開していいものなのでしょうか?その URL には本来付与されるべきな認証の設定、ドキュメントの作成、アクセス制限などの非機能要件が正しく実装されていないかもしれません。こういった不安を払拭するための一般的な構成が API にまつわる非機能要件、API の緩衝材の役割として、API ゲートウェイを前段に配置する方法です。

事実 TAP を利用している多くのお客様で、Source2URL でデプロイされた URL はあくまで内部向けのものとして利用、前段にAPI ゲートウェイを配置し、エンドユーザーに公開しているケースがみられました。これ自体に問題があるわけではないのですが、TAP 外の管理コンポーネントに依存してしまうため、せっかくのガバナンスや開発速度のスピードを削ぐものでした。この課題のひとつの解決策となりうるのが TAP 1.5 から API ゲートウェイ機能、それがこのブログで紹介する Spring Cloud Gateway for Kubernetes です。

Spring Cloud Gateway for Kubernetes とは?

Spring Cloud Gateway for Kubernetes (以降 SCG4K8s とも表記)がどういったものか取り上げます 。似た名前のものが多いので一度整理すると以下のように分類されます。

  • Spring Cloud Gateway :
    Java 開発フレームワークである Spring のライブラリとして提供されているものです。ライブラリですので、Spring を使って開発したアプリケーションで利用されるものです。オープンソース化もされており、利用のためには特定のライセンス購入は不要です。( VMware Spring Runtime 経由での商用サポートを提供することも可能です)
  • Spring Cloud Gateway for VMware Tanzu :
    Tanzu Application Service 上で利用が可能な Spring Cloud Gateway をさらに利用しやすくするためのパッケージ製品です。ソースコードを使った開発が不必要であり、API経由でデプロイや構成変更が可能です。
  • Spring Cloud Gateway for Kubernetes (TAP 1.5 より同梱):
    Spring Cloud Gateway for VMware Tanzu と同じ方針のまま  Kubernetes で利用可能にしたものです。Kubernetes で利用可能になったことにより、プライベートクラウドやパブリッククラウド、Kubernetesさえインストールされていれば、どこでも Spring Cloud Gateway の機能を利用することができます。デプロイや構成方法も Kubernetes の YAML ファイルベースで行うことができます。いままでは、VMware Spring Runtime を購入したお客様のみが利用できるものでしたが、この度 TAP を利用しているお客様でも利用が可能となりました。

SCG4K8s をインストールすることで、HTTP エンドポイントで構成されたバックエンドサービスの API に対し Rate Limit 、サーキットブレイキング、SSO 認証などのさまざまな機能を提供することができます。(なお “Spring” という言葉が誤解を生むかもしれませんが、決して Spring アプリケーション専用の API ゲートウェイではなく、バックエンドのサービスの開発言語は問いません)

SCG4K8s のもう一つ大きな特徴が API ゲートウェイの主導権を開発者に委ねているところです。一般的な旧来方式の API ゲートウェイは、開発者から直接アクセスできるものではなく、申請ベースで変更を依頼するというケースが多いです。また、API ゲートウェイサービス自体が SaaS  サービスの形態をとることが多く、連携の過程でサービスを外部公開する必要があり、セキュリティとして望ましくない設定になりうることがありました。これに対し SCG4K8s は開発者が管理できるような API / Kubernetes なので YAML ファイルとして管理することができます。それらは、CI/CD などとの連携も容易にします。さらに SaaS との連携もないのでセキュリティを高く設定することができます。

 

さまざなな事柄が期待されますが、次の章では実例で試していきます。

Spring Cloud Gateway for Kubernetes を試す

この章からは SCG4K8s を試していきます。
(※このデモでは汎用性を優先して、HTTP の暗号化なしでエンドポイントを公開するため、本番環境での実施やインターネットに直接公開しないようご注意ください。

作業環境の前提としては、このブログで紹介したような極力シンプルなパラメータで構成した TAP 環境を想定しています。利用するソースコードは以下に配置されています。

https://github.com/mhoshi-vm/scg-demo

手元にコードをダウンロードしてください。

git clone https://github.com/mhoshi-vm/scg-demo
cd scg-demo

1. Spring Cloud Gateway のインストール

マニュアルに従い、SCG4K8s をインストールします。(以降の手順では、デフォルトのパラメーターでのインストールを想定)正しくインストールされていれば、以下のコマンドで確認ができます。

% tanzu package installed list -n tap-install | grep spring-cloud-gateway.tanzu.vmware.com
  scg                                 spring-cloud-gateway.tanzu.vmware.com                2.0.0-tap.5       Reconcile succeeded

2. 作業ネームスペースの作成

次に作業ネームスペースを作成します。TAP 1.5 では、以下のコマンドで作成できます。

kubectl create ns demo
kubectl label namespaces demo apps.tanzu.vmware.com/tap-ns=""

合わせて、kubeconfig のターゲットのネームスペースを切り替えします。

kubectl config set-context --current --namespace demo

3. 環境の準備

ここから基本的なコンポーネントをデプロイします。後続の手順で必要になるので、まず AppSSO のコンポーネントをインストールします。以下のコマンドを実行します。

cd k8s/appsso
ytt -f . -v domain=demo.<domain_name> | kubectl apply -f-

デプロイ後、以下のコマンドで、”STATUS” が Ready もしくは、Reconcile succeeded になっていることを確認します。

% kubectl get authserver,rsakey,clientregistration
NAME REPLICAS ISSUER URI CLIENTS STATUS
authserver.sso.apps.tanzu.vmware.com/basic-authserver 1 http://basic-authserver.demo.10.220.46.38.sslip.io 1 Ready

NAME DESCRIPTION AGE
rsakey.secretgen.k14s.io/authserver-signing-key Reconcile succeeded 27s

NAME STATUS
clientregistration.sso.apps.tanzu.vmware.com/basic-client-registration Ready

続いて SCG4K8s のコンポーネントのデプロイを行います。

cd k8s/scg-base
ytt -f . -v domain=demo.<domain_name> | kubectl apply -f-

実行後以下のコマンドで SCG4K8s のコンポーネントのステータスが “READY” が “True” になったことを確認します。

% kubectl get springcloudgateway
NAME READY REASON
demo-gateway True Created

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

以下のコマンドでデプロイします。

tanzu apps workload create --build-env BP_JVM_VERSION=17 \
  --git-repo https://github.com/mhoshi-vm/scg-demo \
  --git-branch main \
  --type server demo

しばらくして、以下の通り、workload が起動したことを確認します。

% tanzu apps workload list
NAME TYPE APP READY AGE
demo server <empty> Ready 14m

以下のコマンドを使いエンドポイントから “Hello World” が帰ってくることを確認します。なお、この応答はこの時点で SCG4K8s が応答しています。

% SCG_URL=`kubectl get ingress demo-ingress -o jsonpath='{.spec.rules[0].host}'`
% curl ${SCG_URL}/api/get
Hello World

この API エンドポイントの挙動を SCG を使いアップデートしていきます。

機能1. Rate Limit によるアクセス制御

まず、以下のコマンドを実行して、SCG4K8sの情報を更新します。

cd k8s/scg-demo1
kubectl apply -f route.yaml

この中の route.yamlがポイントであり、展開すると以下のような内容になっています。

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: demo-route
spec:
...
  routes:
    - predicates:
        - Path=/**
      filters:
...
        - RateLimit=1,10s

ポイントが”RateLimit=1,10s” API に対するアクセス制限を設定しています。この例だと、10s(秒)というタイムフレームに1回までのアクセスを許可しています。

この状態で、以下のコマンドを実行してみます。

curl -i ${SCG_URL}/api/get ; curl -i ${SCG_URL}/api/get

すると、出力の中から正常の実行できたものとあわせて、以下のようなエラーが確認できるとおもいます。これはこの設定が有効になり、短期間に複数回アクセスしたために起きた事象です。このようにしながら、 API への接続回数の制限などをコードから独立して設定ができます。

HTTP/1.1 429 Too Many Requests

機能2. CircuitBreakerによる Sorry Server の実装

ここでは、仮にバックエンドサービスが正しくない挙動をした場合にサーキットブレイキング、つまり一時的な代替 URL へと案内する方法をご紹介します。以下のコマンドを実行して、SCG4K8s の情報を更新します。

cd k8s/scg-demo2
kubectl apply -f route.yaml

この中の route.yaml がポイントであり、展開すると以下のような内容になっています。

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: demo-route
spec:
...
  routes:
    - predicates:
        - Path=/api/**
      filters:
...
        - CircuitBreaker=myCircuitBreaker,forward:/sorry
    - predicates:
        - Path=/sorry
      filters:
        - RedirectTo=302, https://tanzu.vmware.com/tanzu

ポイントが “CircutBreaker=myCircutBreaker…” によるエラー制御をおこなっている点です。この例では “/api/” の URL で何らかエラーが発生した場合に、すべて /sorry, そしてさらにそこから、弊社の Tanzu のホームページへリダイレクトするようになっています。まず正常な状態で以下のコマンドを実行すると、”Hello World” の出力が返ってきます。

% curl ${SCG_URL}/api/get
Hello World

では、ここで、サービスを一度停止してみます。

tanzu apps workload delete demo

以下のコマンドで必要な URL を取得します。

echo ${SCG_URL}/api/get

上で出現した URL を Web ブラウザで入力すると以下のように弊社のホームページへリダイレクトされると思います。つまり API が停止していることによる代替の URL が参照されている状態です。

この状態で再度アプリケーションを起動します。

tanzu apps workload create --build-env BP_JVM_VERSION=17 \
  --git-repo https://github.com/mhoshi-vm/scg-demo \
  --git-branch main \
  --type server demo

上がりきるまで待機すれば(およそ5分)自動的に、以下のように、元の API の応答が復旧するはずです。

以上のようにこれまたソースコードから独立して、エラー時の挙動を定義することができました。

機能3. SSO との連携

ここでは、API への認証を SCG4K8s 経由で設定します。以下のコマンドを実行します。

cd k8s/scg-demo3
kubectl apply -f route.yaml

route.yaml を見ると以下のようになっています。

apiVersion: "tanzu.vmware.com/v1"
kind: SpringCloudGatewayRouteConfig
metadata:
  name: demo-route
spec:
...
  routes:
    - predicates:
        - Path=/**
...
      ssoEnabled: true

ポイントは、”ssoEnabled: true” の値であり、これにより準備の時に設定を行った AppSSO との連携を行います。以下のコマンドで必要なURLを取得します。

echo ${SCG_URL}/api/get

上で出現した URL を Web ブラウザで入力すると以下のような画面になるかと思います。

この画面で user / password と入力して “Submit” を実行します。すると、以下のように Hello World が出現するようになるかと思います(一度ログインしてしまうと以後は特に認証は聞かれなくなります)

このようにソースコードから独立して特定の URL に対して、認証画面をつけることができました。なお、ここでの認証の仕組み AppSSO を使っていますので、詳細はこちらのブログを参照してください。

なお、この章に紹介したように Spring Cloud Gateway が TAP の機能群とも合わせて利用することもできます。例えば以下のユースケースが考えれらます。

その他、ここで取り上げた以外のさらなる設定については、マニュアルをご参照ください。

まとめ

このブログでは、TAP 1.5 から追加された Spring Cloud Gateway for Kubernetes の機能をご紹介しました。VMware ブログでは引き続き Tanzu Application Platform の機能をご紹介しますのでご期待ください。