高可用性IAM
InterSystemsテクノロジーを本番環境にデプロイする際の推奨事項の1つは、高可用性を設定することです。 これらのInterSystemsテクノロジーにお勧めのAPI Managerは、InterSystems API Manager(IAM)です。 IAM(特にKong Gateway)には複数のデプロイトポロジーがあります。
高可用性を重視する場合は、以下を利用できます。
a) Kong Traditionalモード:複数ノードクラスタ
b) Hybridモード
c) DB-lessモード
それぞれ詳しく説明する前に、最初にInterSystemsが提供するすぐに利用可能なデプロイを理解しましょう(IAMバージョン3.10のインストール)。
Kong Traditionalモード
Kong Traditionalモードは単一ノードクラスタです。 まだお読みでない場合は、@Guillaume.Rongier7183による素晴らしい記事、 IAM (InterSystems API Manager), Zero to Hero をお読みください。IAMの設定してInterSystems IRISで作業する方法についてついて非常に分かりやすく説明しています。
現在、Kong Traditionalモードの単一ノードクラスタは、IKO経由でのIAMデプロイオプションでのみサポートされています。デプロイについてのドキュメントはこちらからご覧になれます。
Guillaumeの記事(記事のセクション2.4.4、または添付されたOpenExchangeアプリケーションのGitHubレポジトリにあるREADMEの3.4.4) のYAMLには、3つのコンテナがあります。
- iam-migrations(空のpostgresデータベースの初期化)
- iam(IAM自体)
- db(postgresデータベース)
Traditionalモードでは、すべての構成はIAMコンテナ経由で行われ、すべてのリクエストもこのコンテナに送信されます。
スケールアップすることで、単一のIAMコンテナへの依存を減らすことができます。
非常にシンプルで、別のIAMセクションに追加するだけです! 1つのYAMLのみで作業している場合、次のように設定できます。
- iam-migrations
- iam1
- iam2
- db
1つのYAMLのみで作業している場合、IAM1にIAM2とは異なるポートを指定する必要があります。
Spoiler (Traditional)
services:
iam-migrations:
image: containers.intersystems.com/intersystems/iam:3.10
command: bash -c "kong migrations bootstrap; kong migrations up; kong migrations finish"
depends_on:
- db
environment:
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_CASSANDRA_CONTACT_POINTS: db
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
restart: on-failure
links:
- db:db
iam1:
image: containers.intersystems.com/intersystems/iam:3.10
depends_on:
- db
environment:
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: '0.0.0.0:8001'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_CASSANDRA_CONTACT_POINTS: db
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: 'on'
KONG_PORTAL_GUI_PROTOCOL: http
KONG_PORTAL_GUI_HOST: '127.0.0.1:8003'
KONG_ADMIN_GUI_URL: http://localhost:8002
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
links:
- db:db
ports:
- target: 8000
published: 8000
protocol: tcp
- target: 8001
published: 8001
protocol: tcp
- target: 8002
published: 8002
protocol: tcp
- target: 8003
published: 8003
protocol: tcp
- target: 8004
published: 8004
protocol: tcp
restart: on-failure
iam2:
image: containers.intersystems.com/intersystems/iam:3.10
depends_on:
- db
environment:
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: '0.0.0.0:8011'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_CASSANDRA_CONTACT_POINTS: db
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: 'on'
KONG_PORTAL_GUI_PROTOCOL: http
KONG_PORTAL_GUI_HOST: '127.0.0.1:8003'
KONG_ADMIN_GUI_URL: http://localhost:8012
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
links:
- db:db
ports:
- target: 8000
published: 8010
protocol: tcp
- target: 8011 # kong admin listen
published: 8011
protocol: tcp
- target: 8002
published: 8012
protocol: tcp
- target: 8003
published: 8013
protocol: tcp
- target: 8004
published: 8014
protocol: tcp
restart: on-failure
db:
image: postgres
environment:
POSTGRES_DB: ${KONG_PG_DATABASE:-iam}
POSTGRES_PASSWORD: ${KONG_PG_PASSWORD:-iam}
POSTGRES_USER: ${KONG_PG_USER:-iam}
volumes:
- 'pgdata:/var/lib/postgresql/data'
healthcheck:
test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-iam}"]
interval: 30s
timeout: 30s
retries: 3
restart: on-failure
stdin_open: true
volumes:
pgdata:
理想的には、データベース(移行のブートストラップを含む)と各Kongノードを、それぞれ独立したサーバー上で稼働させることが望ましいです。 このケースではポートは問題になりませんが、KONG_PG_HOST環境変数をデータベースが稼働しているホストにポイントするよう変更する必要があります。
これで高可用性を設定できましたが、これはIRIS/HealthConnectのアクティブ/パッシブミラーリングとは異なり、アクティブ/アクティブになります。 IAM1またはIAM2のどちらで設定しても大丈夫です。データベースを共有しているため、もう一方にも更新が反映され、同じ情報が保存されます。
.png)
独立したデータベースを使用したい場合は、2つの個別のシングルノードクラスタを構成する必要があります。 KongにはIRISなどのデータベースを「ミラー」するオプションがないため、構成を自動化するにはパイプラインを作成する必要があります(またはすべてを2度構成するか、DBを完全に削除します。詳細についてはDB-lessモードをご覧ください)。 Kongが提供している上記の図で、2つのIAMの代わりに3つのIAMのみを使用していることが分かります。 環境関数、KONG_STATUS_LISTEN: 0.0.0.0:8100を使用して、各IAMノードにロードバランサーやヘルスチェックプローブを追加することをお勧めします。
Traditionalモードの大きな利点は次のとおりです(Kongドキュメントによる情報です)。
Traditionalモードは、データベースを必要とするプラグイン(例:クラスタ戦略でのレート制限やOAuth2)をサポートする唯一のデプロイトポロジです。
しかし、欠点もあります(Kongドキュメントによる情報です)。
- Traditionalモードで稼働する場合、すべてのKong Gatewayノードは、コントロールプレーン(CP)とデータプレーン(DP)の両方として動作します。 つまり、どのノードが侵害されても、稼働中のゲートウェイ全体の構成が影響を受けます。
- Kong ManagerでKong Gateway Enterpriseを稼働している場合、Kong Managerが動作しているノードでは、分析データやグラフをレンダリングするために負荷の高い計算が行われるため、リクエストスループットが低下する可能性があります。
以下のモードはこれらの問題を解決します。
Kong Hybridモード
Hybridモードは、IAMコンテナとして前述したものをコントロールプレーン(CP)とデータプレーン(DP)の2つに分割します。
CPは、Kong Manager(デフォルトではポート8002または8445でアクセスされるKong の「管理ポータル」)など、Kong の管理を担当する部分です。 コントロールプレーンはデータベースに接続され、その構成をDPに送信します。 DPはKongの管理は一切行わず、設定の反映だけを担当します。 Kong経由のすべてのクライアントAPIリクエストは、CPを経由することなくDPに直接送信されます(これはルートで、デフォルトではポート8000または8443です)。 これは、Traditionalモードの複数ノードクラスタにより生じる欠点を解決します。 HybridモードをInterSystemsでたとえると、ECPのようなイメージです。 クライアントはアプリケーション専用の高速DPとやり取りしますが、管理およびデータやグラフのレンダリングなどはすべてCPが担当します。
.png)
コントロールプレーンとデータプレーンのYAMLの例を見てみましょう。
ネタバレ(コントロールプレーン)
# Hybrid mode example: Control plane.
services:
iam-migrations:
image: containers.intersystems.com/intersystems/iam:3.10
command: bash -c "kong migrations bootstrap; kong migrations up; kong migrations finish"
depends_on:
- db
environment:
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_CASSANDRA_CONTACT_POINTS: db
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
restart: on-failure
links:
- db:db
iam:
image: containers.intersystems.com/intersystems/iam:3.10
depends_on:
- db
environment:
KONG_LOG_LEVEL: debug
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: '0.0.0.0:8001'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_CASSANDRA_CONTACT_POINTS: db
KONG_DATABASE: postgres
KONG_PG_DATABASE: ${KONG_PG_DATABASE:-iam}
KONG_PG_HOST: db
KONG_PG_PASSWORD: ${KONG_PG_PASSWORD:-iam}
KONG_PG_USER: ${KONG_PG_USER:-iam}
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: 'on'
KONG_PORTAL_GUI_PROTOCOL: http
KONG_PORTAL_GUI_HOST: 'localhost:8003'
KONG_ADMIN_GUI_URL: http://localhost:8002
KONG_VITALS: 'on'
KONG_ADMIN_GUI_HIDE_KONNECT_CTA: 'on'
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
KONG_ROLE: control_plane
KONG_CLUSTER_SERVER_NAME: 'kong_clustering'
KONG_CLUSTER_LISTEN: '0.0.0.0:8005 ssl'
KONG_CLUSTER_TELEMETRY_LISTEN: '0.0.0.0:8006 ssl'
KONG_CLUSTER_MTLS: 'shared'
KONG_CLUSTER_CERT: /etc/kong/admin.crt
KONG_CLUSTER_CERT_KEY: /etc/kong/admin.key
KONG_LUA_SSL_TRUSTED_CERTIFICATE: /etc/kong/admin.crt
# This IP needs to be changed to point at the docker host.
extra_hosts:
- "kong_clustering:host-gateway"
links:
- db:db
ports:
- target: 8001
published: 8001
protocol: tcp
- target: 8002
published: 8002
protocol: tcp
- target: 8003
published: 8003
protocol: tcp
- target: 8004
published: 8004
protocol: tcp
- target: 8005
published: 8105
protocol: tcp
- target: 8006
published: 8006
protocol: tcp
restart: on-failure
volumes:
- ./Certificates/admin.crt:/etc/kong/admin.crt
- ./Certificates/admin.key:/etc/kong/admin.key
db:
image: postgres
environment:
POSTGRES_DB: ${KONG_PG_DATABASE:-iam}
POSTGRES_PASSWORD: ${KONG_PG_PASSWORD:-iam}
POSTGRES_USER: ${KONG_PG_USER:-iam}
volumes:
- 'pgdata:/var/lib/postgresql/data'
healthcheck:
test: ["CMD", "pg_isready", "-U", "${KONG_PG_USER:-iam}"]
interval: 30s
timeout: 30s
retries: 3
restart: on-failure
stdin_open: true
volumes:
pgdata:
今回初めて、証明書や鍵を追加したことに注意してください。 分かりやすくするために、この記事では証明書や鍵については触れず、次回の記事で 安全な通信の設定方法について説明します。 とはいえ、HybridモードではCPとDPがmTLSで通信する必要があるため、 必要でした。
ネタバレ(データプレーン)
# Hybrid mode example: Data plane.
services:
iam-data1:
image: containers.intersystems.com/intersystems/iam:3.10
environment:
KONG_LOG_LEVEL: debug
KONG_DATABASE: 'off'
KONG_PROXY_LISTEN: '0.0.0.0:8000'
KONG_ADMIN_LISTEN: 'off'
KONG_ADMIN_GUI_LISTEN: 'off'
KONG_PORTAL_GUI_LISTEN: 'off'
KONG_PORTAL_API_LISTEN: 'off'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: 'off'
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
KONG_ROLE: data_plane
KONG_CLUSTER_MTLS: 'shared'
KONG_CLUSTER_CERT: /etc/kong/admin.crt
KONG_CLUSTER_CERT_KEY: /etc/kong/admin.key
KONG_LUA_SSL_TRUSTED_CERTIFICATE: /etc/kong/admin.crt
KONG_CLUSTER_CONTROL_PLANE: kong_clustering:8105
KONG_CLUSTER_TELEMETRY_ENDPOINT: kong_clustering:8006
KONG_CLUSTER_SERVER_NAME: "kong.clustering"
KONG_CLUSTER_TELEMETRY_SERVER_NAME: "kong.clustering"
KONG_STATUS_LISTEN: 0.0.0.0:8100
# This IP needs to be changed to point at the docker host.
extra_hosts:
- "kong_clustering:host-gateway"
ports:
- target: 8000
published: 8000
protocol: tcp
- target: 8100
published: 8101
protocol: tcp
restart: on-failure
# This directory should be changed to point at your cert files on the host OS.
volumes:
- ./Certificates/admin.crt:/etc/kong/admin.crt
- ./Certificates/admin.key:/etc/kong/admin.key
iam-data2:
image: containers.intersystems.com/intersystems/iam:3.10
environment:
KONG_LOG_LEVEL: debug
KONG_DATABASE: 'off'
KONG_PROXY_LISTEN: '0.0.0.0:8000'
KONG_ADMIN_LISTEN: 'off'
KONG_ADMIN_GUI_LISTEN: 'off'
KONG_PORTAL_GUI_LISTEN: 'off'
KONG_PORTAL_API_LISTEN: 'off'
KONG_ANONYMOUS_REPORTS: 'off'
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_PORTAL: 'off'
ISC_IRIS_URL: IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license
KONG_ROLE: data_plane
KONG_CLUSTER_MTLS: 'shared'
KONG_CLUSTER_CERT: /etc/kong/admin.crt
KONG_CLUSTER_CERT_KEY: /etc/kong/admin.key
KONG_LUA_SSL_TRUSTED_CERTIFICATE: /etc/kong/admin.crt
KONG_CLUSTER_CONTROL_PLANE: kong_clustering:8105
KONG_CLUSTER_TELEMETRY_ENDPOINT: kong_clustering:8006
KONG_CLUSTER_SERVER_NAME: "kong.clustering"
KONG_CLUSTER_TELEMETRY_SERVER_NAME: "kong.clustering"
KONG_STATUS_LISTEN: 0.0.0.0:8100
# This IP needs to be changed to point at the docker host.
extra_hosts:
- "kong_clustering:host-gateway"
ports:
- target: 8000
published: 8100
protocol: tcp
- target: 8100
published: 8102
protocol: tcp
restart: on-failure
# This directory should be changed to point at your cert files on the host OS.
volumes:
- ./Certificates/admin.crt:/etc/kong/admin.crt
- ./Certificates/admin.key:/etc/kong/admin.key
前回と同じように、ロードバランサーを必ず設定しておきましょう 私はGUI操作が好きで、管理はコントロールプレーン、クライアントやアプリケーションはデータプレーンに接続するという区分けも気に入っているため、これは私が好むIAM高可用性 デプロイメントトポロジです。 このモードの 他の利点を見てみましょう(Kongドキュメントによる情報です)。
デプロイの柔軟性: ユーザーは、各DPグループにローカルのクラスタ化データベースをを必要とせずに、さまざまなデータセンター、地域、またはゾーンにデータプレーンのグループをデプロイできます。
信頼性の向上: データベースの稼働状況がデータプレーンの稼働に影響することはありません。 各DPは、コントロールプレーンから受け取った最新の設定をローカルディスクにキャッシュするため、CPノードがダウンしてもDPノードは稼働し続けます。
- CPが停止している間、DPノードは常に通信の再確立を試みます。
- CPがダウンしている間でも、DPノードを再起動でき、通常通りトラフィックをプロキシできます。
トラフィックの削減: データベースとのやり取りを大幅に削減できます。直接接続が必要なのはCPノードのみであるためです。
セキュリティの向上: DPノードのいずれかが侵害されても、攻撃者がKong Gatewayクラスタ内の他のノードに影響を与えることはできません。
管理が簡単: 管理者はCPノードにアクセスするだけで、Kong Gatewayクラスタ全体を管理・モニタリングできます。
DB-lessモード
3つ目で最後のKong GatewayデプロイトポロジはDB-lessモードです。 このモードではデータベースは不要で、すべての設定がYAMLで宣言的に行われ、アプリケーションは一時的に(永続ストレージなしで)実行されます。
.png)
これには以下の欠点があります(Kongドキュメントによる情報です)。
- 管理API は読み取り専用です。
- レート制限(クラスタモード)など、データベースに情報を保存するプラグインは、完全に機能しません。
しかし、利点もあります(Kongドキュメントによる情報です)。
- 依存関係数の削減:使用ケース全体がメモリ内で収まる場合、データベースのインストールを管理する必要はありません。
- 設定は常に既知の状態です。 管理APIでサービスとルートを作成する処理の間に、中間的な状態が発生することはありません。
- DB-lessモードは、CI/CDシナリオでの自動化に最適です。 エンティティの構成は、Gitリポジトリで管理される信頼できる唯一の情報源として保持できます。
今回、YAMLにデータベースが含まれていないため、iam-migrationsもありません。
ネタバレ(DB-less)
services:
iam1:
image: containers.intersystems.com/intersystems/iam:3.10
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ANONYMOUS_REPORTS: "off"
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
ISC_IRIS_URL: "IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license"
volumes:
- ./kong.yml:/etc/kong/kong.yml
ports:
- target: 8000
published: 8000
protocol: tcp
- target: 8001
published: 8001
protocol: tcp
restart: on-failure
iam2:
image: containers.intersystems.com/intersystems/iam:3.10
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ANONYMOUS_REPORTS: "off"
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
ISC_IRIS_URL: "IAM:${IRIS_PASSWORD}@host.docker.internal:80/api/iam/license"
volumes:
- ./kong.yml:/etc/kong/kong.yml
ports:
- target: 8000
published: 8010
protocol: tcp
- target: 8001
published: 8011
protocol: tcp
restart: on-failure
もちろん、Kongの宣言的な設定も必要です。 このYAMLの例については、以下をご覧ください。
ネタバレ(kong.yml)
_format_version: "3.0"
services:
- name: test-api
protocol: http
host: host.docker.internal # If Kong runs *on your host*.
port: 80
path: /api/atelier
routes:
- name: test-api
paths:
- /somepath
strip_path: true # /somepath is removed before proxying
まとめると、HAを実現するためにIAMが使用できるデプロイトポロジーは3種類あり、それぞれに長所と短所があります。 添付のOpen Exchangeアプリケーションをぜひご覧ください。これらのトポロジーを1つずつデプロイする手順を確認できます。