4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Red HatAdvent Calendar 2023

Day 15

Red Hat Service InterconnectによるCloud Bursting

Last updated at Posted at 2023-12-14

これはRed Hat Advent Calendar 2023の15日目の記事です。

概要

この記事では、Red Hat Service Interconnect(RHSI)という、環境やプラットフォームに関係なくアプリケーションやサービスが相互に通信できるようにするソフトウェアを使って、アプリケーションのCloud Burstingを試みます。

※内容自体は、おおまかにはこちらを日本語に翻訳したものとなります。

そもそもRed Hat Service Interconnectとは

世の中には既にRed Hat Service Interconnect、およびそのUpstreamであるSkupperに関する優れた記事が沢山存在するため、細かい話は割愛しますが、Siteという概念をLinkというものでセキュアにつないだVirtual Application Network(VAN)というものを作ることができる、というソフトウェアです。

以下の記事などを参照することで、より詳しい情報を得ることができます。

また、色々読み漁っていると、SkupperはIstioと一部類似しているというかオーバーラップしている部分がある気がするけど、何が違うのだろうと感じることもあるかと思いますが、RHSIとRed Hat OpenShit Service Mesh(OSSM、IstioのRed Hat製品版。正確にはMaistraがこの記事投稿時点のOSSM 2.xのアップストリームで、MaistraはIstioに基づいています。)の比較の話がこのへんにあったりしますので、製品版の話で恐縮ですがこちらも参考にしていただければと思います。

本題

RHSIのユースケースの一つとして、Cloud Burstingがあります。
Cloud Burstingは、例えば現在アプリケーションが動作している基盤のリソースが足りなくなった時に、一時的にクラウド側のリソースを使ってアプリケーションをスケールする、という、昔からよく聞くような話です。

RHSIは、これを後付けで比較的容易に実現させることができる可能性を持っています。

RHSIでは、複数の場所(この場所をSiteと呼びます)に跨って仮想的なService(KubernetesのServiceのことだと思ってもらって構いません)を容易に作成できますが、それぞれのSiteで、その仮想的なServiceに様々なバックエンドをバインドすることができます。

RHSIはVAN anycastDynamic Load Balancingといった機能を持っていて、これらの機能に基づき

  • ある仮想Serviceにアクセスすると、そのServiceにバインドされたバックエンドのうち、RHSIの備えるLinkState Routing Protocolに基づき、最小コストの経路のSiteにあるものにトラフィックをルーティングする
  • Serviceにはキャパシティ(リクエスト数やOpen Connection数などに対する閾値だと思ってもらえると良いと思います)があり、そのキャパシティを超える場合、次にコストの低い経路のSiteのものにトラフィックをルーティングする
    • ローカル(アクセス元とServiceが同一のSite)の場合はコストが0であるため、まずはローカルのバックエンドにルーティングし、キャパシティを超えた場合は他のSiteのバックエンドにルーティングする

という振る舞いをします。

わかりにくいですが要するに、同じServiceにアクセスが続いた時、あるSiteで捌けなくなったら他のSiteに転送し始めます。
※このキャパシティはprotocolなどによって違ったりするようですが、2023/12/15現在、ドキュメントを見ても何が閾値として使われているのかは明言されおらず、細かく調整するパラメータも存在せず、滲み出やすさはLink Costに依存しているようです。

この記事では、これらの機能を活用してアプリケーションのCloud Burstingを試みます。

使うアプリケーション

今回は、Quarkusで作られたマイクロサービス群がイベントで連携して業務を処理する、イベント駆動アーキテクチャで構成された Quarkus Coffeeshop アプリケーション使用します。

Quarkus Coffeesgop

元々のQuarkus Coffeeshopのソースコードはこちらになりますが、この記事では、元がイベント駆動アーキテクチャを実現するためにApache Kafkaに直接接続していたところについて、OpenShift ServerlessEventingで連携するように改変したものを使用しています。この改変版アプリケーションのイメージは事前にQuay.ioにアップロード済みで、アプリケーションを展開するための必要なマニフェストはこのリポジトリに入っています。

構成の全体図と補足、および前提

全体的な構成は以下のようになります。cluster1Somewhereがオンプレミス、cluster2がクラウドで、黄色い部分がVAN、点線でつながったServiceが仮想的なServiceだと思っていただけると良いかと思います。
なお後述しますが、今回の構成だとknative-eventing内で色々操作できる権限が必要であるため、一般ユーザだけで同じ事をする場合はbroker-ingressへの参照を工夫するなどの手段をとります。

0.png

処理の流れは大体以下のようになっています。

  1. Web UIやAPIでコーヒーや食べ物をオーダーすると、Web UIはオーダーがきたイベントを流す
  2. オーダーがきたイベントがcounterに流れることでcounterがオーダーを受け付け、受け付けた事をDBに書き込み、状態更新イベント(受け付けた)と、コーヒーや食べ物のオーダーイベントを流す
  3. オーダーを受け付けたイベントはWeb UIに流れ、画面を更新する
  4. コーヒーのオーダーイベントは、いずれかのbaristaに流れ、コーヒーを作り始める
  5. 食べ物のオーダーイベントは、いずれかのkitchenに流れ、食べ物を作り始める
  6. コーヒーや食べ物を作り終わったbaristakitchenは、作り終えたイベントを流す
  7. 作り終えたイベントはcounterに流れ、DBのステータスを更新し、状態更新イベント(オーダーされたものが出来上がった)イベントを流す
  8. 状態更新イベント(オーダーされたものが出来上がった)イベントはWeb UIに流れ、画面を更新する
    ※イベントを流すのは、OpenShift ServerlessのEventingがTriggerを使って行います。

補足

  • 今回利用しているGatewayはRHSIの機能の一つで、VAN内から特定のServiceにアクセスしたときにクラスタの外部にあるIP:Portへのアクセスに変換したり、逆にVAN外から特定のIP:Portにアクセスしたときにクラスタ内のServiceへのアクセスに変換するような役割を持っています。

  • 先述のとおり、今回はknative-eventingにあるbroker-ingressを直接exposeしてしまいましたが、例えば以下のようにbroker-ingress.knative-eventing.svc.cluster.localへのExternalNameをexposeして参照するなどの手段によって、一般ユーザ権限だけで動作させることができるのを確認済みです。

    • OpenShift Serverless Operator自体は、管理者によって利用可能にしておいてもらう必要があります。
[lab-user@bastion ~]$ oc get service/broker-ingress -n cbcs
NAME             TYPE           CLUSTER-IP   EXTERNAL-IP                                         PORT(S)   AGE
broker-ingress   ExternalName   <none>       broker-ingress.knative-eventing.svc.cluster.local   80/TCP    117m

[lab-user@bastion ~]$ skupper service status
Services exposed through Skupper:
├─ quarkuscoffeeshop-counter (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-counter name=quarkuscoffeeshop-counter 
├─ quarkuscoffeeshop-kitchen (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-kitchen name=quarkuscoffeeshop-kitchen 
├─ broker-ingress (tcp port 80)
│  ╰─ Targets:
│     ╰─ broker-ingress name=broker-ingress 
╰─ quarkuscoffeeshop-barista (http port 80)
   ╰─ Targets:
      ╰─ app=quarkuscoffeeshop-barista name=quarkuscoffeeshop-barista 

baristaなどの各Deploymentは環境変数でbroker-ingressへの参照を変更できるため、本当に動くのか気になる方は是非試してみてください。

前提

  • 2つの Red Hat OpenShift クラスタとして、cluster1cluster2があるとします

    • この2つのクラスタにあるSite間でCloud Burstingします
  • DB用のRHELサーバがあるとします

    • Gatewayが動作することも確認したかったため、今回DBはクラスタの外のどこかのRHELサーバに置いて、Gatewayで通信させることにします
    • また、今回GatewayはDBと同一のサーバで起動することにします
  • RHSIのバージョンは1.4.3を利用します

  • 作業するマシンには https://gitlab.com/m-muraki/skupper-cloud-bursting-demogit cloneされているとします

    • ブランチはocp-rhsiです
  • 今回の記事ではサブスクリプション関係の操作は省略していますが、実際は正しく処理する必要があります

作業

ここから実際の作業に入りますが、前提を揃えるのが大変だったり手順がそこそこ長いため、とりあえず動いているところが見たい、という方は以下のGifアニメーションをご覧いただければと思います。

quarkuscoffeeshop_cloud_bursting.gif

Quarkus Coffeeshopの各マイクロサービスをcluster1Siteにデプロイ

  • 作業を行う前に、context(ocコマンドの接続先)をcluster1に切り替えておきます
  • skupper-cloud-bursting-demo/cluster1/appディレクトリで作業します
  • アプリケーションのURL(Route.spec.host)はwww.example.comであるとします
    • この部分は、実際の設定に合わせて読み替えてください

Quarkus CoffeeshopのDB以外を動かすSite用に、cbcsという名前のprojectを作成

$ oc new-project cbcs
Now using project "cbcs" on server "https://api.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

Quarkus CoffeeshopのDBServiceを置く用のSiteとして、cbcs-dbという名前のprojectを作成

$ oc new-project cbcs-db
Now using project "cbcs-db" on server "https://api.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

Quarkus Coffeeshopが使うSecretConfigMapを作成

$ oc create secret generic \
  --from-literal POSTGRES_USER=coffeeshopuser \
  --from-literal POSTGRES_PASSWORD=redhat-21 \
  secret-quarkuscoffeeshop -n cbcs

secret/secret-quarkuscoffeeshop created
$ oc create secret generic \
  --from-literal POSTGRES_USER=coffeeshopuser \
  --from-literal POSTGRES_PASSWORD=redhat-21 \
  secret-quarkuscoffeeshop -n cbcs-db

secret/secret-quarkuscoffeeshop created

Web UIのManifest内のホスト名は、環境に合わせて置換します。

$ oc create configmap \
 --from-literal CORS_ORIGINS=http://www.example.com/dashboard/ \
 --from-literal LOYALTY_STREAM_URL=http://www.example.com/dashboard/loyaltystream \
 --from-literal POSTGRES_DB=coffeeshopdb \
 --from-literal POSTGRES_URL=jdbc:postgresql://quarkuscoffeeshop-postgresql.cbcs-db.svc.cluster.local:5432/coffeeshopdb?currentSchema=coffeeshop \
 --from-literal QUARKUS_LOG_LEVEL=INFO \
 --from-literal STORE_ID=RALEIGH \
 --from-literal STREAM_URL=http://www.example.com/dashboard/stream \
 --from-literal SITE=Site1 \
 configmap-quarkuscoffeeshop -n cbcs

configmap/configmap-quarkuscoffeeshop created
$ oc create configmap \
 --from-literal POSTGRES_DB=coffeeshopdb \
 configmap-quarkuscoffeeshop -n cbcs-db

configmap/configmap-quarkuscoffeeshop created

Quarkus Coffeeshopをデプロイ

$ oc apply -f .
deployment.apps/quarkuscoffeeshop-web created
service/quarkuscoffeeshop-web created
route.route.openshift.io/quarkuscoffeeshop-web created
deployment.apps/quarkuscoffeeshop-counter created
service/quarkuscoffeeshop-counter created
deployment.apps/quarkuscoffeeshop-barista created
service/quarkuscoffeeshop-barista created
deployment.apps/quarkuscoffeeshop-kitchen created
service/quarkuscoffeeshop-kitchen created

Quarkus Coffeeshopがデプロイされていることを確認

この段階ではcounterはレプリカ数が0になっていますが、後で起動するため、このままで問題ありません。

$ oc get deployment -n cbcs
NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
quarkuscoffeeshop-barista   3/3     3            3           45s
quarkuscoffeeshop-counter   0/0     0            0           45s
quarkuscoffeeshop-kitchen   3/3     3            3           45s
quarkuscoffeeshop-web       1/1     1            1           45s
$ oc get pod -n cbcs
NAME                                         READY   STATUS    RESTARTS   AGE
quarkuscoffeeshop-barista-65ff59d99f-7rjh4   1/1     Running   0          66s
quarkuscoffeeshop-barista-65ff59d99f-ggsn7   1/1     Running   0          66s
quarkuscoffeeshop-barista-65ff59d99f-xkrtk   1/1     Running   0          66s
quarkuscoffeeshop-kitchen-79bc8745c-6tnkq    1/1     Running   0          66s
quarkuscoffeeshop-kitchen-79bc8745c-fnjnf    1/1     Running   0          66s
quarkuscoffeeshop-kitchen-79bc8745c-vlphm    1/1     Running   0          66s
quarkuscoffeeshop-web-9fc5675cb-rjtkg        1/1     Running   0          66s
$ oc get service -n cbcs
NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
quarkuscoffeeshop-barista   ClusterIP   172.30.133.48    <none>        80/TCP    83s
quarkuscoffeeshop-counter   ClusterIP   172.30.12.100    <none>        80/TCP    83s
quarkuscoffeeshop-kitchen   ClusterIP   172.30.28.125    <none>        80/TCP    83s
quarkuscoffeeshop-web       ClusterIP   172.30.111.217   <none>        80/TCP    83s
$ oc get route -n cbcs
NAME                    HOST/PORT                                                                     PATH   SERVICES                PORT   TERMINATION     WILDCARD
quarkuscoffeeshop-web   quarkuscoffeeshop-web-cbcs.apps.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com          quarkuscoffeeshop-web   8080   edge/Redirect   None
$ oc get all -n cbcs-db
No resources found in cbcs-db namespace.

OpenShift Serverlessのoperatorをインストールし、関連するリソースを作成

  • 作業を行う前に、context(ocコマンドの接続先)をcluster1に切り替えておきます
  • skupper-cloud-bursting-demo/cluster1/opensift-serverlessディレクトリで作業します

OpenShift Serverlessのoperatorをインストールし、関連するリソースを作成します

$ oc apply -f 01_subs_openshift_serverless.yaml 
subscription.operators.coreos.com/serverless-operator created
$ oc apply -f 02_knative_serving.yaml
knativeserving.operator.knative.dev/knative-serving created
$ oc apply -f 03_knative_eventing.yaml 
knativeeventing.operator.knative.dev/knative-eventing created
$ oc apply -f 04_configmap_cbcs_mt_channel_based_broker_config.yaml 
configmap/cbcs-mt-channel-based-broker-config created
$ oc apply -f 05_broker_cbcs_mt_channel_based_broker.yaml 
broker.eventing.knative.dev/cbcs-mt-channel-based-broker created
$ oc apply -f 06_trigger_cbcs_kafka_broker_web.yaml 
trigger.eventing.knative.dev/cbcs-mt-channel-based-broker-web-web-updates created
$ oc apply -f 07_trigger_cbcs_kafka_broker_counter.yaml 
trigger.eventing.knative.dev/cbcs-mt-channel-based-broker-counter-orders-in created
trigger.eventing.knative.dev/cbcs-mt-channel-based-broker-counter-orders-up created
$ oc apply -f 08_trigger_cbcs_kafka_broker_barista.yaml 
trigger.eventing.knative.dev/cbcs-mt-channel-based-broker-barista-barista-in created
$ oc apply -f 09_trigger_cbcs_kafka_broker_kitchen.yaml 
trigger.eventing.knative.dev/cbcs-mt-channel-based-broker-kitchen-kitchen-in created

brokertriggerが作成されていることを確認します

$ oc get broker -n cbcs
NAME                           URL                                                                                          AGE   READY   REASON
cbcs-mt-channel-based-broker   http://broker-ingress.knative-eventing.svc.cluster.local/cbcs/cbcs-mt-channel-based-broker   81s   True    
$ oc get trigger -n cbcs
NAME                                              BROKER                         SUBSCRIBER_URI                                                       AGE   READY   REASON
cbcs-mt-channel-based-broker-barista-barista-in   cbcs-mt-channel-based-broker   http://quarkuscoffeeshop-barista.cbcs.svc.cluster.local/barista-in   90s   True    
cbcs-mt-channel-based-broker-counter-orders-in    cbcs-mt-channel-based-broker   http://quarkuscoffeeshop-counter.cbcs.svc.cluster.local/orders-in    93s   True    
cbcs-mt-channel-based-broker-counter-orders-up    cbcs-mt-channel-based-broker   http://quarkuscoffeeshop-counter.cbcs.svc.cluster.local/orders-up    93s   True    
cbcs-mt-channel-based-broker-kitchen-kitchen-in   cbcs-mt-channel-based-broker   http://quarkuscoffeeshop-kitchen.cbcs.svc.cluster.local/kitchen-in   87s   True    
cbcs-mt-channel-based-broker-web-web-updates      cbcs-mt-channel-based-broker   http://quarkuscoffeeshop-web.cbcs.svc.cluster.local/web-updates      96s   True    

ここからは、このQuarkus Coffeeshopがもう1つのクラスタのSiteにCloud Burstingできるようにするための準備を行います。

もう1つのクラスタ側にQuarkus Coffeeshopをデプロイ

  • 作業を行う前に、context(ocコマンドの接続先)をcluster2に切り替えておきます
  • skupper-cloud-bursting-demo/cluster2/appディレクトリで作業します

Cloud Burstingに向けたSite用に、それぞれprojectを作ります

$ oc new-project cbcs
Now using project "cbcs" on server "https://api.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname
$ oc new-project cbcs-db
Now using project "cbcs-db" on server "https://api.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname
$ oc new-project knative-eventing
Now using project "knative-eventing" on server "https://api.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app rails-postgresql-example

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=k8s.gcr.io/e2e-test-images/agnhost:2.33 -- /agnhost serve-hostname

Quarkus Coffeeshopが使うSecretConfigMapを作成します

今回は手動でSecretConfigMapの同期相当の作業を行います。

$ oc create secret generic \
  --from-literal POSTGRES_USER=coffeeshopuser \
  --from-literal POSTGRES_PASSWORD=redhat-21 \
  secret-quarkuscoffeeshop -n cbcs

secret/secret-quarkuscoffeeshop created
$ oc create configmap \
 --from-literal POSTGRES_URL=jdbc:postgresql://quarkuscoffeeshop-postgresql.cbcs-db.svc.cluster.local:5432/coffeeshopdb?currentSchema=coffeeshop \
 --from-literal QUARKUS_LOG_LEVEL=INFO \
 --from-literal SITE=Site2 \
 configmap-quarkuscoffeeshop -n cbcs

configmap/configmap-quarkuscoffeeshop created

Quarkus Coffeeshopをデプロイします

$ oc apply -f .
deployment.apps/quarkuscoffeeshop-counter created
deployment.apps/quarkuscoffeeshop-barista created
deployment.apps/quarkuscoffeeshop-kitchen created

Quarkus Coffeeshopがデプロイされていることを確認します

$ oc get all -n cbcs
NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/quarkuscoffeeshop-barista   0/0     0            0           116s
deployment.apps/quarkuscoffeeshop-counter   0/0     0            0           116s
deployment.apps/quarkuscoffeeshop-kitchen   0/0     0            0           116s

NAME                                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/quarkuscoffeeshop-barista-58778897c9   0         0         0       116s
replicaset.apps/quarkuscoffeeshop-counter-6b8554bb95   0         0         0       116s
replicaset.apps/quarkuscoffeeshop-kitchen-84cc77dcc7   0         0         0       116s
$ oc get all -n cbcs-db
No resources found in cbcs-db namespace.
$ oc get all -n knative-eventing
No resources found in knative-eventing namespace.

Siteの初期化とLinkの作成

ここからはRHSIのVANを作っていきます。

cluster1Siteの初期化を行い、Linkを作成するためのTokenを作成します

  • 作業を行う前に、context(ocコマンドの接続先)をcluster1に切り替えておきます
  • skupper-cloud-bursting-demo/cluster1/service-interconnectディレクトリで作業します
$ skupper version
client version                 1.4.3
transport version              not-found
controller version             not-found
config-sync version            not-found
flow-collector version         not-found
$ oc apply -f 01_subs_service_interconnect.yaml 
subscription.operators.coreos.com/skupper-operator created
$ oc apply -f 02_configmap_cbcs-site1.yaml -n cbcs
configmap/skupper-site created
$ skupper status -n cbcs
Skupper is enabled for namespace "cbcs" with site name "cbcs-site1" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-cbcs.apps.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f 03_configmap_cbcs-db-site1.yaml -n cbcs-db
configmap/skupper-site created
$ skupper status -n cbcs-db
Skupper is enabled for namespace "cbcs-db" with site name "cbcs-db-site1" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-cbcs-db.apps.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f 04_configmap_knative-eventing-site1.yaml -n knative-eventing
configmap/skupper-site created
$ skupper status -n knative-eventing
Skupper is enabled for namespace "knative-eventing" with site name "knative-eventing-site1" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-knative-eventing.apps.cluster-pbpbp.pbpbp.sandbox3038.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f 05_secret_tokenrequest-cbcs-site2-to-site1.yaml -n cbcs
secret/tokenrequest-cbcs-site2-to-site1 created
$ oc get secret/tokenrequest-cbcs-site2-to-site1 -o yaml -n cbcs | grep -v "namespace:" > /tmp/secret_token-cbcs-site2-to-site1.yaml
$ oc apply -f 06_secret_tokenrequest-cbcs-db-site2-to-site1.yaml -n cbcs-db
secret/tokenrequest-cbcs-db-site2-to-site1 created
$ oc get secret/tokenrequest-cbcs-db-site2-to-site1 -o yaml -n cbcs-db | grep -v "namespace:" > /tmp/secret_token-cbcs-db-site2-to-site1.yaml
$ oc apply -f 07_secret_tokenrequest-knative-eventing-site2-to-site1.yaml -n knative-eventing
secret/tokenrequest-knative-eventing-site2-to-site1 created
$ oc get secret/tokenrequest-knative-eventing-site2-to-site1 -o yaml -n knative-eventing | grep -v "namespace:" > /tmp/secret_token-knative-eventing-site2-to-site1.yaml

cluster2Siteの初期化を行い、先程cluster1Siteで作ったTokenを使ってLinkを作成します

  • 作業を行う前に、context(ocコマンドの接続先)をcluster2に切り替えておきます
  • skupper-cloud-bursting-demo/cluster2/service-interconnectディレクトリで作業します
$ skupper version
client version                 1.4.3
transport version              not-found
controller version             not-found
config-sync version            not-found
flow-collector version         not-found
$ oc apply -f 01_subs_service_interconnect.yaml 
subscription.operators.coreos.com/skupper-operator created
$ oc apply -f 02_configmap_cbcs-site2.yaml -n cbcs
configmap/skupper-site created
$ skupper status -n cbcs
Skupper is enabled for namespace "cbcs" with site name "cbcs-site2" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-cbcs.apps.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f 03_configmap_cbcs-db-site2.yaml -n cbcs-db
configmap/skupper-site created
$ skupper status -n cbcs-db
Skupper is enabled for namespace "cbcs-db" with site name "cbcs-db-site2" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-cbcs-db.apps.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f 04_configmap_knative-eventing-site2.yaml -n knative-eventing
configmap/skupper-site created
$ skupper status -n knative-eventing
Skupper is enabled for namespace "knative-eventing" with site name "knative-eventing-site2" in interior mode. Status pending... It has no exposed services.
The site console url is:  https://skupper-knative-eventing.apps.azure-pbpbp-1.pbpbp-1.sandbox2180.opentlc.com
The credentials for internal console-auth mode are held in secret: 'skupper-console-users'
$ oc apply -f /tmp/secret_token-cbcs-site2-to-site1.yaml -n cbcs
secret/tokenrequest-cbcs-site2-to-site1 created
$ oc apply -f /tmp/secret_token-cbcs-db-site2-to-site1.yaml -n cbcs-db
secret/tokenrequest-cbcs-db-site2-to-site1 created
$ oc apply -f /tmp/secret_token-knative-eventing-site2-to-site1.yaml -n knative-eventing
secret/tokenrequest-knative-eventing-site2-to-site1 created

Site間でLinkが作成され、connectedになっていることを確認します

$ skupper link status -n cbcs

Links created from this site:

	 Link tokenrequest-cbcs-site2-to-site1 is connected
$ skupper link status -n cbcs-db

Links created from this site:

	 Link tokenrequest-cbcs-db-site2-to-site1 is connected
$ skupper link status -n knative-eventing

Links created from this site:

	 Link tokenrequest-knative-eventing-site2-to-site1 is connected

Serviceはまだexposeされていないことを確認します

$ skupper service status -n cbcs
No services defined
$ skupper service status -n cbcs-db
No services defined
$ skupper service status -n knative-eventing
No services defined

RHELサーバでDBを起動して、Gatewayを起動し、cbcs-dbでDBのServiceをexpose

DBを起動し、RHSIを通して接続可能な状態にします。

  • 作業を行う前に、context(ocコマンドの接続先)をcluster1に切り替えておきます
  • skupper-cloud-bursting-demo/gateway_dbディレクトリで作業します

RHELサーバでDBを起動します

[lab-user@bastion gateway_db]$ podman run -d --rm --name postgresql -p 5432:5432 -e POSTGRES_USER=coffeeshopuser -e POSTGRES_PASSWORD=redhat-21 -e POSTGRES_DB=coffeeshopdb -v ./init-postgresql.sql:/docker-entrypoint-initdb.d/init-postgresql.sql:Z postgres:11
7601886d56198be7c6eea1471b1eccd5ce365b83014a11d0d0de8062ee99f227
$ podman ps
CONTAINER ID  IMAGE                                                                 COMMAND     CREATED         STATUS             PORTS                   NAMES
7601886d5619  docker.io/library/postgres:11                                         postgres    52 seconds ago  Up 52 seconds ago  0.0.0.0:5432->5432/tcp  postgresql

RHELサーバでGatewayを初期化して、cbcs-dbでDBのserviceをexposeします

$ skupper gateway init --type podman -n cbcs-db
Skupper gateway: 'bastion.example.com-lab-user'. Use 'skupper gateway status' to get more information.
$ skupper service create quarkuscoffeeshop-postgresql --protocol tcp 5432 -n cbcs-db
$ skupper gateway bind quarkuscoffeeshop-postgresql 127.0.0.1 5432 -n cbcs-db
2023/11/16 15:25:24 CREATE io.skupper.router.tcpConnector quarkuscoffeeshop-postgresql:5432 map[address:quarkuscoffeeshop-postgresql:5432 host:127.0.0.1 name:quarkuscoffeeshop-postgresql:5432 port:5432 siteId:544d21d1-81eb-4c91-add8-88adcf47123b]

※上記のinitコマンド・createコマンド・bindコマンドのセットは、exposeコマンドだけでも同じ事ができます。

$ podman ps
CONTAINER ID  IMAGE                                                                 COMMAND               CREATED             STATUS                 PORTS                   NAMES
7601886d5619  docker.io/library/postgres:11                                         postgres              About a minute ago  Up About a minute ago  0.0.0.0:5432->5432/tcp  postgresql
5ce212f754be  quay.io/skupper/skupper-router:2.4.3                                  /home/skrouterd/b...  28 seconds ago      Up 28 seconds ago                              bastion.example.com-lab-user
$ skupper gateway status -n cbcs-db
Gateway Definition:
╰─ bastion.example.com-lab-user type:podman version:2.4.3
   ╰─ Bindings:
      ╰─ quarkuscoffeeshop-postgresql:5432 tcp quarkuscoffeeshop-postgresql:5432 127.0.0.1 5432
$ skupper service status -n cbcs-db
Services exposed through Skupper:
╰─ quarkuscoffeeshop-postgresql (tcp port 5432)

cluster1で、DB以外のServiceもexpose

DB以外にも仮想Serviceを作り、この後のcluster2Siteでのバックエンドのバインドに備えます。

  • 作業を行う前に、context(ocコマンドの接続先)をcluster1に切り替えておきます

まず、Serviceがexposeされていないことを確認します

$ skupper service status -n cbcs
No services defined
$ skupper service status -n cbcs-db
No services defined
$ skupper service status -n knative-eventing
No services defined

既存のServiceにannotationを付与することでServiceをexposeします

$ oc annotate service quarkuscoffeeshop-barista skupper.io/proxy=http -n cbcs

service/quarkuscoffeeshop-barista annotated
$ oc annotate service quarkuscoffeeshop-kitchen skupper.io/proxy=http -n cbcs

service/quarkuscoffeeshop-kitchen annotated
$ oc annotate service quarkuscoffeeshop-counter skupper.io/proxy=http -n cbcs

service/quarkuscoffeeshop-counter annotated
$ oc annotate service broker-ingress skupper.io/proxy=http -n knative-eventing

service/broker-ingress annotated

Serviceがexposeされていることを確認します

$ skupper service status -n cbcs
Services exposed through Skupper:
├─ quarkuscoffeeshop-barista (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-barista name=quarkuscoffeeshop-barista 
├─ quarkuscoffeeshop-counter (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-counter name=quarkuscoffeeshop-counter 
╰─ quarkuscoffeeshop-kitchen (http port 80)
   ╰─ Targets:
      ╰─ app=quarkuscoffeeshop-kitchen name=quarkuscoffeeshop-kitchen 
$ skupper service status -n cbcs-db
Services exposed through Skupper:
╰─ quarkuscoffeeshop-postgresql (tcp port 5432)
$ skupper service status -n knative-eventing
Services exposed through Skupper:
╰─ broker-ingress (http ports 80 9092)
   ╰─ Targets:
      ╰─ eventing.knative.dev/brokerRole=ingress name=broker-ingress 

このSiteにはquarkuscoffeeshop-postgresqlにはTargetsは存在せず、少し前の手順で設定したGatewayを通してRHELサーバのDBにアクセスすることになります。(Gateway側にはquarkuscoffeeshop-postgresqlに対するBindingsが表示されています。)

Quarkus Coffeeshopcounterをスケールアップします

counterはDBへアクセスしますが、上記の手順が終わるまではDBが起動していなかったり、Serviceも見えなかったりするため、接続不能で少なからずエラーが発生してしまいます。そのため、今回は上記の手順によるDB起動とGatewayによるServiceのexposeの後でcounterが起動するようにしています。

$ oc scale deployment/quarkuscoffeeshop-counter --replicas=3 -n cbcs
deployment.apps/quarkuscoffeeshop-counter scaled
oc get pods -n cbcs
NAME                                          READY   STATUS    RESTARTS   AGE
quarkuscoffeeshop-barista-65ff59d99f-7rjh4    1/1     Running   0          75m
quarkuscoffeeshop-barista-65ff59d99f-ggsn7    1/1     Running   0          75m
quarkuscoffeeshop-barista-65ff59d99f-xkrtk    1/1     Running   0          75m
quarkuscoffeeshop-counter-66fbdc8f5b-56f7t    1/1     Running   0          12s
quarkuscoffeeshop-counter-66fbdc8f5b-fjnpv    1/1     Running   0          12s
quarkuscoffeeshop-counter-66fbdc8f5b-ww6n8    1/1     Running   0          12s
quarkuscoffeeshop-kitchen-79bc8745c-6tnkq     1/1     Running   0          75m
quarkuscoffeeshop-kitchen-79bc8745c-fnjnf     1/1     Running   0          75m
quarkuscoffeeshop-kitchen-79bc8745c-vlphm     1/1     Running   0          75m
quarkuscoffeeshop-web-9fc5675cb-rjtkg         1/1     Running   0          75m
skupper-prometheus-9d89c8fcb-6tprt            1/1     Running   0          22m
skupper-router-7f5df585f-td8rd                2/2     Running   0          22m
skupper-service-controller-5dd798bb94-twxhq   2/2     Running   0          22m

exposeされたServiceに対して、cluster2cbcsにあるDeploymentをバインド

先程作られた仮想Serviceに対して、cluster2Siteにあるバックエンドもバインドします。これが完了すると、同じServiceに対して複数のSiteにあるバックエンドが紐付いた状態になり、捌けなくなったときの転送先ができることになります。

  • 作業を行う前に、context(ocコマンドの接続先)をcluster2に切り替えておきます

cluster2cbcsServiceが見えることと、そこではまだ何もバインドされていないことを確認します

$ skupper service status -n cbcs
Services exposed through Skupper:
├─ quarkuscoffeeshop-barista (http port 80)
├─ quarkuscoffeeshop-counter (http port 80)
╰─ quarkuscoffeeshop-kitchen (http port 80)
$ skupper service status -n cbcs-db
Services exposed through Skupper:
╰─ quarkuscoffeeshop-postgresql (tcp port 5432)
$ skupper service status -n knative-eventing
Services exposed through Skupper:
╰─ broker-ingress (http ports 80 443 9092)

ServiceDeploymentをバインドします

$ skupper service bind quarkuscoffeeshop-barista deployment quarkuscoffeeshop-barista --target-port 8080 -n cbcs
$ skupper service bind quarkuscoffeeshop-kitchen deployment quarkuscoffeeshop-kitchen --target-port 8080 -n cbcs
$ skupper service bind quarkuscoffeeshop-counter deployment quarkuscoffeeshop-counter --target-port 8090 -n cbcs

ServiceDeploymentをバインドされたことを確認します

バインドするのはcbcsのものだけで、それ以外は他のSiteにあるバックエンドへのアクセスを行わせるため、ここでは何もしません。

$ skupper service status -n cbcs
Services exposed through Skupper:
├─ quarkuscoffeeshop-kitchen (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-kitchen name=quarkuscoffeeshop-kitchen namespace=cbcs
├─ quarkuscoffeeshop-barista (http port 80)
│  ╰─ Targets:
│     ╰─ app=quarkuscoffeeshop-barista name=quarkuscoffeeshop-barista namespace=cbcs
╰─ quarkuscoffeeshop-counter (http port 80)
   ╰─ Targets:
      ╰─ app=quarkuscoffeeshop-counter name=quarkuscoffeeshop-counter namespace=cbcs
$ skupper service status -n cbcs-db
Services exposed through Skupper:
╰─ quarkuscoffeeshop-postgresql (tcp port 5432)
$ skupper service status -n knative-eventing
Services exposed through Skupper:
╰─ broker-ingress (http ports 80 9092)

cbcsDeploymentをスケールして、cluster1側からくるトラフィックに対応できるようにします

  • 作業を行う前に、context(ocコマンドの接続先)をcluster2に切り替えておきます
$ oc scale deployment/quarkuscoffeeshop-barista --replicas=10 -n cbcs
deployment.apps/quarkuscoffeeshop-barista scaled
$ oc scale deployment/quarkuscoffeeshop-kitchen --replicas=10 -n cbcs
deployment.apps/quarkuscoffeeshop-kitchen scaled
$ oc scale deployment/quarkuscoffeeshop-counter --replicas=10 -n cbcs
deployment.apps/quarkuscoffeeshop-counter scaled

cbcsでそれぞれスケールしたPodが動作していることを確認します

$ oc get pods -n cbcs
NAME                                          READY   STATUS    RESTARTS   AGE
quarkuscoffeeshop-barista-58778897c9-2jwlt    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-2wf2n    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-9vr2j    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-jlmsb    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-prvw4    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-q2qvz    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-s2khk    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-v9dbg    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-vbkm9    1/1     Running   0          29s
quarkuscoffeeshop-barista-58778897c9-zjzlt    1/1     Running   0          30s
quarkuscoffeeshop-counter-6b8554bb95-5tghj    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-dcmzm    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-hggfp    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-lnlxx    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-ltbsx    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-pxkw7    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-vf7px    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-w5nxg    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-x7s4s    1/1     Running   0          11s
quarkuscoffeeshop-counter-6b8554bb95-zlzl8    1/1     Running   0          11s
quarkuscoffeeshop-kitchen-84cc77dcc7-29lkh    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-5s65v    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-9qvbt    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-b47ms    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-c99dm    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-cpldx    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-pptvd    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-rpbnq    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-thgrj    1/1     Running   0          19s
quarkuscoffeeshop-kitchen-84cc77dcc7-wr8fg    1/1     Running   0          19s
skupper-prometheus-687bc6955c-5ppt8           1/1     Running   0          17m
skupper-router-6964dcc694-x4fn6               2/2     Running   0          17m
skupper-service-controller-6886cb8465-twwv5   2/2     Running   0          17m

cluster1cluster2両方のcbcsにあるcounterpodは、cbcs-dbServiceであるquarkuscoffeeshop-postgresqlにアクセスしますが、その際は先述のとおりGatewayを通してRHELサーバにあるDBにアクセスする形になります。

ここまでで、Quarkus Coffeeshopcluster1clsuter2にあるSiteをまたいでBurstingすることが可能になりました。

Quarkus Coffeeshopに大量のオーダーを入れてみて、実際にどのような動作をするか確認

  • アプリケーションのURL(Route.spec.host)はwww.example.comであるとします
    • この部分は、実際の設定に合わせて読み替えてください

オーダーを大量に投入します

$ for x in `seq 1 100`; do curl -i -X POST -H 'Content-Type: application/json' -d '{"commandType":"PLACE_ORDER","id":"'$(uuidgen)'","orderSource":"WEB","storeId":"RALEIGH","rewardsId":"","baristaItems":[{"name":"customer'$(printf "%03d" ${x})'","item":"CAPPUCCINO","price":"3.75"}],"kitchenItems":[{"item":"CROISSANT","price":3.00,"name":"customer'$(printf "%03d" ${x})'"}]}' http://www.example.com/order; done
HTTP/1.1 202 Accepted
content-length: 286
content-type: application/json
set-cookie: 377d16b6ad7e93d35752ce1b8a45cd37=b44bc865c92313a8273a503a442108da; path=/; HttpOnly

{"commandType":"PLACE_ORDER","baristaItems":[{"item":"CAPPUCCINO","price":3.75,"name":"customer001"}],"kitchenItems":[{"item":"CROISSANT","price":3.00,"name":"customer001"}],"id":"5b7ffd8f-e37a-44b4-b6f2-91bf81fdb373","storeId":"RALEIGH","orderSource":"WEB","rewardsId":"","total":null}HTTP/1.1 202 Accepted
content-length: 286
content-type: application/json
set-cookie: 377d16b6ad7e93d35752ce1b8a45cd37=b44bc865c92313a8273a503a442108da; path=/; HttpOnly

...

{"commandType":"PLACE_ORDER","baristaItems":[{"item":"CAPPUCCINO","price":3.75,"name":"customer099"}],"kitchenItems":[{"item":"CROISSANT","price":3.00,"name":"customer099"}],"id":"cfac0925-7432-4682-abf5-95c3fe282876","storeId":"RALEIGH","orderSource":"WEB","rewardsId":"","total":null}HTTP/1.1 202 Accepted
content-length: 286
content-type: application/json
set-cookie: 377d16b6ad7e93d35752ce1b8a45cd37=b44bc865c92313a8273a503a442108da; path=/; HttpOnly

{"commandType":"PLACE_ORDER","baristaItems":[{"item":"CAPPUCCINO","price":3.75,"name":"customer100"}],"kitchenItems":[{"item":"CROISSANT","price":3.00,"name":"customer100"}],"id":"187b7e13-7a41-4293-8efc-ca7db2a09163","storeId":"RALEIGH","orderSource":"WEB","rewardsId":"","total":null}$ 

オーダーを投入したら、どのSiteでオーダーが処理されたかをQuarkus CoffeeshopのWeb UIで確認すると、受付(counterが設定します)や作業完了(baristakitchenが設定します)がSite1Site2に分散し、多くはSite2で処理されるのが確認できます。

Quarkus Coffeeshop Web UI

RHSIのWebコンソールで実際のトラフィックがどうなっているかを確認します

Skupper console
Skupper console
Skupper console

まとめ

Red Hat Service Interconnectを使用することで、後付けで比較的容易にアプリケーションのCloud Burstingできるようになる可能性があるようでした。

とはいえ、例えば今回のようなcluster2から離れた位置にあるDBにアクセスする際には大きな遅延が発生するなど、常用には向いていない部分があります。counterだけはBurstingしないとしても、やはりその他でそれなりの遅延が発生します。
そのため、こういった利用方法は、サービスレベルが一部低下する可能性があっても、止まるよりましなので迅速に一時的な拡張を行いたい場合であったり、現行システムを騙しながら段階的に移行したい場合など、何かのトレードオフを受け入れた上での一時的な目的達成に絞って適用するほうが現実的であるとも考えられます。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?