WebSocket は、クライアントとサーバー間の永続的で低レイテンシーの双方向通信を可能にします。Kubernetes クラスターの外部から WebSocket サービスにアクセスすると、MSE クラウドネイティブゲートウェイはリクエストを受信し、ルーティングルールに基づいて適切なバックエンドサービスに転送します。このトピックでは、Container Service for Kubernetes (ACK) クラスターに WebSocket アプリケーションをデプロイし、MSE クラウドネイティブゲートウェイを介してトラフィックをルーティングする方法について説明します。
前提条件
-
ACK マネージドクラスターを作成済みであること。
-
MSE クラウドネイティブゲートウェイの通常インスタンス (Professional Edition または Standard Edition) を作成済みであること。サーバーレス MSE クラウドネイティブゲートウェイは WebSocket プロトコルをサポートしていません。
ステップ 1: WebSocket アプリケーションのデプロイ
詳細については、「Deployment を使用したステートレスワークロードの作成」をご参照ください。
このチュートリアルでは、Kubernetes ネイティブのサービスディスカバリを使用します。Service リソースはバックエンドを CoreDNS に登録します。サンプルバックエンドは、複数の WebSocket エンドポイントを提供します。ACK クラスターに次の YAML 設定を適用します。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sockbin
name: sockbin-app
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: sockbin
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: sockbin
spec:
containers:
- image: therebelrobot/sockbin
imagePullPolicy: Always
name: sockbin
ports:
- containerPort: 4080
protocol: TCP
resources:
limits:
cpu: 500m
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
labels:
app: sockbin
name: sockbin-service
namespace: default
spec:
ports:
- name: http
port: 4080
protocol: TCP
targetPort: 4080
selector:
app: sockbin
sessionAffinity: None
type: NodePort
ステップ 2: WebSocket トラフィックのルーティング
ゲートウェイのサービスソースとして ACK クラスターを追加し、次に Sockbin サービスを追加します。
クラウドネイティブゲートウェイは、デフォルトで WebSocket プロトコルをサポートしています。ゲートウェイは HTTP Upgrade ヘッダーに基づいて WebSocket リクエストを自動的に識別するため、追加のプロトコル設定は不要です。WebSocket サービスと HTTP API が同じ IP アドレスとポートを共有している場合、ルートにパスのマッチングルールを設定するだけで済みます。
サービスソースの追加
MSE コンソールにログオンし、上部のナビゲーションバーでリージョンを選択します。
左側のナビゲーション ウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。 [ゲートウェイ] ページで、ゲートウェイの名前をクリックします。
左側のナビゲーションウィンドウで、Routes をクリックします。表示されるページで、[ソース] タブをクリックします。
-
ソースの作成 をクリックし、次のパラメーターを設定してから OK をクリックします。
パラメーター
説明
[ソースタイプ]
コンテナサービス を選択します。
ACK/ACK Serverless Cluster
バックエンドサービスがデプロイされているクラスターを選択します。
[K8s Ingress リスナー]
このオプションを有効にすると、MSE クラウドネイティブゲートウェイは Ingress リソースの変更を自動的に監視し、それらのリソースで定義されたドメイン名とルート設定を適用します。
このオプションを無効にすると、ゲートウェイは Ingress リソースの監視を停止し、それらのリソースから以前に適用された設定は無効になります。
説明MSE コンソールで手動で設定したドメイン名とルートは、Ingress リソースからの設定より優先されます。
サービスの追加
MSE コンソールにログオンし、上部のナビゲーションバーでリージョンを選択します。
左側のナビゲーション ウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。 [ゲートウェイ] ページで、ゲートウェイの名前をクリックします。
左側のナビゲーションウィンドウで、Routes をクリックします。表示されるページで、[サービス] タブをクリックします。
-
Create Service をクリックし、次のパラメーターを設定してから OK をクリックします。
パラメーター
説明
[サービスソース]
コンテナサービス を選択します。
[名前空間]
対象クラスターの名前空間を選択します。
[サービス一覧]
リストからサービスを選択します。
Sockbin ルートの追加
MSE コンソールにログオンし、上部のナビゲーションバーでリージョンを選択します。
左側のナビゲーション ウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。 [ゲートウェイ] ページで、ゲートウェイの名前をクリックします。
左側のナビゲーションウィンドウで、Routes をクリックし、[ルート] タブをクリックします。
-
ルーティングの作成 をクリックし、次のパラメーターを設定してから 保存・公開 をクリックします。
パラメーター
説明
[ルーティング名]
sockbin-routeを入力します。[ドメイン名]
デフォルトのドメイン名
*を選択します。[パス (Path)]
マッチング条件として プレフィックスは を選択します。 パスには
/を入力します。[使用シナリオ]
単一サービス を選択します。
[バックエンドサービス]
対象の Service と サービスポート を選択します。
結果の検証
次のいずれかの方法で、WebSocket サービスが利用できることを確認します。
方法 1: Sockbin UI でのテスト
MSE コンソールにログオンし、上部のナビゲーションバーでリージョンを選択します。
左側のナビゲーション ウィンドウで、Cloud-Native Gateway > ゲートウェイリスト を選択します。 [ゲートウェイ] ページで、ゲートウェイの名前をクリックします。
-
ゲートウェイの 基本概要 ページで、 ゲートウェイ入口 タブに移動します。 関連付けられた Server Load Balancer (SLB) インスタンスのパブリックエンドポイントを見つけ、ブラウザーで開きます。
ゲートウェイは、WebSocket ハンドシェイクのドメイン名とパスに基づいて、リクエストを Sockbin サービス UI にルーティングします。
出力: CONNECTING to / ... CONNECTED to / SENT: Hello Sockbin! RESPONSE: { "timestamp": "Tue May 31 2022 07:49:41 GMT+0000 (UTC)", "url": "http://sockb.in/", "reqData": "Hello Sockbin!" }
方法 2: WebSocket クライアントでのテスト
Python WebSocket クライアントを使用することもできます。 次の例では、1 秒の遅延でサーバーの応答を受信します。
#!/usr/bin/env python
import asyncio
import websockets
async def hello():
async with websockets.connect("ws://ip_addr/delay/1000") as websocket:
await websocket.send("Hello Test")
text = await websocket.recv()
print(text)
asyncio.run(hello())
トラブルシューティング
WebSocket または WSS 接続の失敗
-
ゲートウェイのインスタンスタイプを確認します。サーバーレスゲートウェイは WebSocket プロトコルをサポートしていません。代わりに、通常インスタンス (Professional Edition または Standard Edition) を使用してください。
-
バックエンドサービスがデプロイされ、WebSocket プロトコルをサポートしていることを確認します。
-
ゲートウェイをバイパスして、バックエンドサービスへの接続を直接テストしてください。
-
ルートに設定されたドメイン名とパスが、WebSocket ハンドシェイクリクエストのドメイン名とパスと一致するかどうかを確認してください。