投稿者

インターシステムズジャパン
記事 Toshihiko Minamoto · 3月 10 17m read

高可用性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のどちらで設定しても大丈夫です。データベースを共有しているため、もう一方にも更新が反映され、同じ情報が保存されます。 

独立したデータベースを使用したい場合は、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が担当します。

 

コントロールプレーンとデータプレーンの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で宣言的に行われ、アプリケーションは一時的に(永続ストレージなしで)実行されます。 

これには以下の欠点があります(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つずつデプロイする手順を確認できます。

元の記事へ さんが書いた @Ariel Glikman