2019年5月10日 张立强 (liqiang@fit2cloud.com) 著
この記事では、様々なシナリオ(例:クロスDC、Dockerクロスホスト、Kubernetes)でKeycloakクラスタをセットアップするためのソリューションをいくつか紹介します。
Keycloakクラスタのセットアップに関心がある場合、このブログが参考になるかもしれません。
2つのCLIスクリプトファイルが、Keycloakイメージに、ガイドに従って追加されています。
Dockerfileは以下の通りです。そして、これらの2つのファイルがこのブログで最も重要な内容です。これらのファイルは、TCPPING.cli および JDBC_PING.cli から入手できます。
FROM jboss/keycloak:latest ADD cli/TCPPING.cli /opt/jboss/tools/cli/jgroups/discovery/ ADD cli/JDBC_PING.cli /opt/jboss/tools/cli/jgroups/discovery/
まず、Keycloakクラスタでは、すべてのKeycloakインスタンスが同じデータベースを使用する必要があることを知っておくべきです。これは非常に単純です。もう1つの点はキャッシュについてです(一般的にKeycloakには2種類のキャッシュがあります。1つ目は、realm/client/userのようなパフォーマンスを向上させるためにデータベースから読み込まれる永続データキャッシュ、2つ目は、sessions/clientSessionsのような非永続データキャッシュです。2つ目のキャッシュはクラスタにとって非常に重要です)。キャッシュの設定は少し複雑で、クラスタビューでのキャッシュの一貫性を確保する必要があります。
クラスタリングには合計3つのソリューションがあり、すべてのソリューションはJGroupsのディスカバリプロトコルに基づいています(KeycloakはInfinispanキャッシュを使用し、Infinispanはノードを検出するためにJGroupsを使用します)。
PINGは、Keycloakのデフォルトで有効になっているクラスタリングソリューションで、UDPプロトコルを使用します。これに関する設定は不要です。
ただし、PINGはマルチキャストネットワークが有効で、ポート55200が公開されている場合にのみ利用可能です。例えば、ベアメタル、VM、同じホスト内のDockerコンテナなどです。
同じホスト内の2つのKeycloakコンテナでこれをテストしました。
ログから、2つのKeycloakインスタンスが互いを検出し、クラスタ化されたことがわかります。
TCPPINGは、TCPプロトコルと7600ポートを使用します。これは、マルチキャストが利用できない場合、例えば、クロスDCのデプロイメントやクロスホストのコンテナなどで使用できます。
クロスホストの2つのKeycloakコンテナでこれをテストしました。
このソリューションでは、コンテナに対して以下の3つの環境変数を設定する必要があります。
#IP address of this host, please make sure this IP can be accessed by the other Keycloak instances JGROUPS_DISCOVERY_EXTERNAL_IP=172.21.48.39 #protocol JGROUPS_DISCOVERY_PROTOCOL=TCPPING #IP and Port of all host JGROUPS_DISCOVERY_PROPERTIES=initial_hosts="172.21.48.4[7600],172.21.48.39[7600]"
ログから、2つのKeycloakインスタンスが互いを検出し、クラスタ化されたことがわかります。
JDBC_PINGは、TCPプロトコルと7600ポートを使用し、TCPPINGと似ていますが、違いは、TCPPINGはすべてのインスタンスのIPとポートを設定する必要があるのに対し、JDBC_PINGは現在のインスタンスのIPとポートを設定するだけでよい点です。これは、JDBC_PINGソリューションでは、各インスタンスが自身の情報をデータベースに挿入し、インスタンスがデータベースから読み取ったpingデータによってピアを検出するためです。
クロスホストの2つのKeycloakコンテナでこれをテストしました。
このソリューションでは、コンテナに対して以下の2つの環境変数を設定する必要があります。
#IP address of this host, please make sure this IP can be accessed by the other Keycloak instances JGROUPS_DISCOVERY_EXTERNAL_IP=172.21.48.39 #protocol JGROUPS_DISCOVERY_PROTOCOL=JDBC_PING
すべてのインスタンスのpingデータは、インスタンス開始後にデータベースに保存されています。
ログから、2つのKeycloakインスタンスが互いを検出し、クラスタ化されたことがわかります。
上記のソリューションはほとんどのシナリオで利用できますが、Kubernetesなどの一部のシナリオではまだ十分ではありません。
Kubernetesでの一般的なデプロイメントは、1つのDeployment/ReplicateSet/StatefulSetが複数のKeycloak Podを含む構成です。Podはスケールアップ/ダウンしたり、別のノードにフェイルオーバーしたりする可能性があるため、動的であり、クラスタはこれらの動的なメンバーを検出および削除する必要があります。
Kubernetesでは、DNS_PINGまたはKUBE_PINGを使用できます。これらは実環境で非常にうまく機能します。
DNS_PINGとKUBE_PINGに加えて、JDBC_PINGもKubernetesの別のオプションです。
Kubernetesでは、マルチキャストは同じノード内のコンテナに対してのみ利用可能であり、PodにはTCPPINGまたはJDBC_PINGを設定するために使用できる静的IPがありません。しかし、上記のJDBC_PING.cliではこれに対処しており、JGROUPS_DISCOVERY_EXTERNAL_IP環境変数を設定しない場合、Pod IPが使用されます。つまり、Kubernetesでは、JGROUPS_DISCOVERY_PROTOCOL=JDBC_PINGを設定するだけで、Keycloakクラスタは正常に動作します。
提案やコメントは、Keycloak User Mail List または このGitHubリポジトリ を通じて議論できます。