メインコンテンツまでスキップ

SPN Hub

SPN Hub では SPN エンドポイントからの QUIC での接続を受け付けて、仮想的で閉じたネットワークを提供します。

SPN エンドポイント

SPN エンドポイントは QUIC で SPN Hub に接続するクライアントです。SPNエンドポイントは SPN create を使用して rust で開発することが可能です。 また、SPN エージェントを利用して、TCPのクライアント/サーバにも接続できます。

SPN セッション

SPN セッションは QUIC のコネクションと同義ですが、SPNのコネクションとの混同を避けるためにあえて、SPN セッションと呼びます。 この他に Chip-in では HTTP のセッションやコネクションも登場しますが、それらとも区別してください。

QUIC コネクション確立後、最初に SPN エンドポイントから SPN Hub に向かって制御ストリームを開始します。制御ストリームの最初の通信として SPN エンドポイントはSPN hub に SPN セッション確立要求を送信します。 SPN Hub は、セッション確立要求が SPN 内のサービス定義に照らし合わせて許容されていれば SPN エンドポイントにACKを返すとともに SPN セッションオブジェクトをメモリ上に作成します。 セッション確立後も制御ストリームは接続した状態となり、さまざまな制御パケットの通信に使用されます。

SPN セッションオブジェクトには以下が保持されます。

項目名説明
startAtセッション開始時刻
spnSessionIdセッションID(QUIC のサーバ側コネクションIDを使用する)
spnEndPointQUICコネクションの確立に使用されたクライアント証明書の Subject の値
endPointType"serviceProvider", "serviceConsumer" のいずれか
serviceUrnセッションのサービスのエンドポイントのURN
totalConnectionCountこのセッション上で作成された SPNコネクションの総数

SPN セッションはセッションの開設時と終了時にログを出力します。ログの項目は以下の通り。

項目名説明
timestampイベント発生時刻(ログの出力時刻と異なる場合があるのでイベント発生時の時刻を記録する)
spnSessionIdセッションID(QUIC のサーバ側コネクションIDを使用する)
spnEndPointQUICコネクションの確立に使用されたクライアント証明書の Subject の値
eventType"startSpnSession", "endSpnSession" のいずれか
endPointType"serviceProvider", "serviceConsumer" のいずれか
serviceUrnセッションのサービスのURN
totalConnectionCountこのセッション上で作成された SPNコネクションの総数。endSpnSession のときのみ出力される
elapsedTimeセッション開設時からの経過時間。endSpnSession のときのみ出力される
terminateReasonセッションの終了理由。"shutdown", "terminatedByPeer", "error" のいずれか。endSpnSession のときのみ出力される

エンドポイント側セッション管理

エンドポイント側のSPN セッションは以下のように状態遷移します。

SNP Hub のマルチインスタンス

SPN Hub は複数稼働させることができます。ただし、それぞれの SPN Hub は異なるグローバルIPを持ちます。 DNS上では SPN Hub の1個のFQDNに対して起動中のグローバルIPアドレスをすべて返すようにします。 エンドポイント側では、起動時に SPN Hub の FQDN を解決し、得られたグローバルIPアドレスの全てに対してセッションを確立します。 また、定期的に SPN Hub の FQDN を解決し、得られたグローバルIPアドレスの変化を監視します。グローバルIPが削除された場合は、内包するコネクションを中断してセッションを終了し別の SPN Hub に接続し直してコネクションを再開します。

エンドポイント側で複数の SPN セッションがある状態で新しいコネクションが必要となった場合はどれか一つのセッションを選択してコネクションを確立します。

SPN コネクション

SPN コネクションは QUIC のコネクションと異なり、serviceConsumer エンドポイントから SPN Hub を経由して serviceProvider エンドポイントに接続するストリームです。 SPN コネクションは以下の構成要素からなります。

  • serviceConsumer エンドポイントと SPN Hub の間の双方向 QUIC ストリーム
  • SPN Hub と serviceProvider エンドポイントの間の双方向 QUIC ストリーム
  • SPN コネクション管理オブジェクト

SPNコネクションの確立は

  1. serviceConsumer エンドポイントは SPN Hub との間の双方向 QUIC ストリーム上に最初のパケットを送る
  2. SPN Hub は serviceProvider エンドポイントとの間の双方向 QUIC ストリーム上にそのパケットを転送する SPN コネクションオブジェクトには以下が保持されます。
項目名説明
startAtコネクション開始時刻
spnConnectionIdSPNコネクションID(QUIC のストリームIDを serviceConsumer側、serviceProvider側の順に連結したものを使用する)
consumerSideSpnSessionIdserviceConsumer側 SPN セッションのID
providerSideSpnSessionIdserviceProvider側 SPN セッションのID
totalSentBytesこのストリーム上で serviceConsumerからserviceProviderに送信したデータの累計バイト数
totalReceiveBytesこのストリーム上で serviceConsumer がserviceProviderから受信したデータの累計バイト数

SPN セッションはセッションの開設時と終了時にログを出力します。ログの項目は以下の通り。

項目名説明
timestampイベント発生時刻(ログの出力時刻と異なる場合があるのでイベント発生時の時刻を記録する)
spnConnectionIdSPNコネクションID(QUIC のストリームIDを serviceConsumer側、serviceProvider側の順に連結したものを使用する)
eventType"startSpnConnection", "endSpnConnection" のいずれか
consumerSideSpnSessionIdserviceConsumer側 SPN セッションのID
providerSideSpnSessionIdserviceProvider側 SPN セッションのID
totalSentBytesこのストリーム上で serviceConsumerからserviceProviderに送信したデータの累計バイト数。 endSpnConnection のときのみ出力される
totalReceiveBytesこのストリーム上で serviceConsumer がserviceProviderから受信したデータの累計バイト数。 endSpnConnection のときのみ出力される
elapsedTimeコネクション開設時からの経過時間。 endSpnConnection のときのみ出力される
disconnectReasonコネクションの切断理由。"closedByPeer", "closed", "error" のいずれか。 endSpnConnection のときのみ出力される

コネクションの終了

コネクションは SPN エンドポイント側からの終了要求により終了します。

Close Flow

上記は Consumer 側からのコネクション終了要求のフローですが、Provider 側からの終了要求も同様に行われます。

コネクションの中断と再開

コネクションは SPN Hub 側からの中断要求により中断されます。これは、 SPN Hub がサービスのメンテナンスや再起動を行う場合に発生します。

Close Flow

コネクションはエンドポイント側からの再開要求により再開されます。

Close Flow

SPN Hub の再開可能なシャットダウンにおけるエンドポイントととのフローは以下の通りです。

SPN Hub が複数インスタンスの状態で1個の SPN Hub を停止する場合は全てのエンドポイントに再開可能なシャットダウンを通知します。 エンドポイントはコネクションを中断しますが、すぐに別の SPN Hub に接続し直すことができます。 SPN Hub のローリングアップデートやサーバ再起動のためのマイグレーションの場合は、一旦新しいSPN Hub を起動してから、古い SPN Hub に再開可能なシャットダウンをかけることでエンドポイント間の通信は継続されます。

SPN Hub の計画停止については、エンドポイントを Consumer -> Provider の順にシャットダウンし、その後、 SPN Hub を停止します。 それ以外の全てのケースではエンドポイント側でエラーが発生します。

エンドポイント状態遷移

エンドポイントのコネクションの状態遷移は以下の通り。

Provider のマルチインスタンスについて

Providerから複数のセッション接続がある場合、デフォルトでは冗長負荷分散で動作します。 インベントリのサービス定義にそのサービスがシングルトンであるかどうかを示すフラグ singleton があり、これがtrue の場合、サービスはシングルトンであり、SPN Hub は2個目のサービスの接続を受け付けず、単一のインスタンスでの動作のみとなります。

false の場合、SPN Hub は複数のセッションを受け付け、コネクションごとに付加分散して接続します。 Consumer から接続があった際に最も接続数の少ないサービスに接続します。 Provider は分散重み付を変更することができます。重み付値のデフォルトは 100 であり、SPN Hub は接続されているすべての Provider インスタンスの重み付を合計して、インスタンスごとの按分値を算出します。コネクション接続時に按分値と現在の接続数を比較して、接続数の少ないインスタンスに接続します。 ローリングアップデート時は重み付を0に変更してからグレースフルシャットダウンを行うことで、無停止でのアップデートが可能となります。

Provider の重み付が 0 に設定された後、Consumer からの新しい接続別の Provider インスタンスに接続されます。

Consumer と Provider 間のコネクションのグレースフルシャットダウンについてはアプリケーション層で実装する必要があります。例えば、 HTTP の場合は Provider 側から Keep-Alive ヘッダを使用して、コネクションの終了を通知することができます。また、Consumer 側では Keep Alive のタイムアウトで接続をやり直すので、コネクションは破棄されます。

すべてのコネクションが新しい Provider インスタンスに接続されると、古い Provider インスタンスとのセッションは切断され、インスタンスは終了します。

spnhub コマンド

spnhub コマンドは SPN Hub を実装します。spnhub コマンドのパラメータはコマンドラインオプションと環境変数のいずれかで指定できます。 パラメータには以下のものがあります。

オプション環境変数名説明デフォルト
-cSPNHUB_INVENTORY_URLSPN Hub の構成情報を提供するインベントリのURL。http://localhost:8080

spnhubコマンドは起動時とリロードシグナル受信時に構成情報をインベントリ から読み込みます。具体的には以下の順に読み込みます。リロードシグナルは SIGUSR1 です。

1. レルムの読み込み

全てのレルムを読み込みます。 SPN Hub はレルムごとに内部が分離されており、マルチテナントのシステムを容易に実装できます。

name
required
string^[a-z0-9][a-z0-9-]*$

レルムの名前。URN の一部として使用される。 文字列は小文字英字、数字、ハイフンのみを含むことができる。 ただし、ハイフンで始まることはできない。 名称 "master" は予約されており、使用できない。

title
required
string

レルムの日本語名称です。

description
string

レルムの説明文です。

urn
string <urn>

レルムのURN。形式は urn:chip-in:realm:{realm-name} である。

cacert
required
string

realm 配下の SPN hub で mTLSにおけるクライアント証明書を発行したCA局の証明書(PEM形式)の文字列

signingKey
required
string >= 24 characters

realm 配下のAPI Gateway でセッショントークンの署名に使用されるパスワード。 使用できる文字は英字、数字、ハイフン、アンダースコアのみである。

sessionTimeout
integer

セッショントークンの有効期限。単位は秒で、デフォルトは 2592000 秒 (30日)。

administrators
Array of strings

レルムの管理者のユーザID。ユーザの管理はインベントリでは行わない。認証サービス内でのみ管理され、ここではそのIDのみを参照する。

expiredAt
string <date-time>

レルムの有効期限。ISO8601形式で指定する。 この日時を過ぎると、レルムの disabled フラグは true となり、関連するリソースへのアクセスが制限される。

disabled
required
boolean

レルムが無効化されているかどうかを示すフラグ。 true の場合、レルムは無効化されており、関連するリソースへのアクセスが制限される。 false の場合、レルムは有効であり、通常の操作が可能である。

  • disabled が True のものは無視します。
  • リロードにおいては、一覧の前後を比較し、追加削除を行います。

2. SPN Hub の構築

レルムごとに SPN Hub を構築します。

name
required
string

SPN Hub の名前。URN の一部として使用される。 文字列は小文字英字、数字、ハイフン、アンダースコアのみを含むことができる。

realm
string <urn>

SPN Hub が属する realm の URN。

urn
string

SPN Hub のURN。URNは、SPN Hubを一意に識別するための文字列で、以下の形式で構成される。 urn:chip-in:network:{realm}:{name}

title
required
string

SPN Hub の日本語名称です。

description
string

SPN Hub の説明文です。

fqdn
required
string

SPN Hub のサーバのFQDN

serverPort
integer

SPN Hub のサーバのポート番号。デフォルトは 443

serverCert
required
string

mTLSにおけるサーバ証明書(PEM形式)の文字列。 SPN Hub のサーバは、この証明書を使用してクライアントとの通信を暗号化する。

serverCertKey
required
string

mTLSにおけるサーバ証明書の秘密鍵(PEM形式)の文字列。 SPN Hub のサーバは、この秘密鍵を使用してクライアントとの通信を暗号化する。

3. サービスの構築

SPN Hub ごとにサービスの定義を読み込みます。

name
required
string

サービスの名前。URN の一部として使用される。 ただし、先頭がハイフンであってはならない。

hub
string <urn>

サービスが接続される SPN Hub のURN。

urn
required
string

サービスのURN。URNは、サービスを一意に識別するための文字列で、以下の形式で構成される。
urn:chip-in:service:{realm}:{hubName}:{name}

title
required
string

サービスの日本語名称です。URN の一部として使用される。 文字列は日本語を含むことができる。

description
string

サービスの説明文です。URN の一部として使用される。 文字列は日本語を含むことができる。

realm
required
string

サービスが属するレルムの名前。

object

コンテナクラスタ内でマイクロサービスのスケジュール起動、オンデマンド起動を行うためのパラメータ

singleton
boolean
provider
required
string
consumers
required
Array of arrays

availabilityManagement が指定されていて、かつ ondemandStart が false のサービスについてはクラスタマネージャを呼び出してサービスを起動する。 サービス定義の読み込みが終わった時点で、SPN Hub での QUIC パケットの受信を開始します。