ronwdavis.com

Setting Up a Keycloak Cluster with JDBC-PING for Caching

Written on

Chapter 1: Introduction to Keycloak Clustering

In this guide, we will walk through the process of establishing a Keycloak Cluster utilizing JDBC-PING for distributed caching. This cluster will consist of two Keycloak instances deployed as Docker containers, with Postgres serving as the database to manage and share cached data across these instances.

To visualize our objective, here’s a project diagram outlining the architecture we aim to implement.

Let's dive in!

Additional Readings: Distributed Caching in Keycloak

Keycloak is an open-source tool designed for identity and access management (IAM). It facilitates the management of user identities, authentication, and authorization for various applications.

Keycloak's current distributed cache system is built on Infinispan, an open-source, distributed, in-memory key-value data store known for its scalability, availability, and fault tolerance.

When Keycloak is initiated in development mode with the "start-dev" command, distributed caching is entirely disabled. Conversely, when launched in production mode with the "start" command, caching becomes active, allowing all Keycloak instances within your network to be identified. By default, the caching system employs a UDP transport layer for instance discovery via IP multicast.

However, there are superior alternatives to UDP for discovery, such as JDBC-PING. This method enables Keycloak to facilitate distributed caching by utilizing a JDBC-compatible database for sharing and storing cached data among multiple instances.

In the following sections, we’ll explore how to set this up.

Section 1.1: Configuring JDBC-PING in Infinispan

As previously mentioned, the distributed cache relies on Infinispan. Let’s examine how to configure it.

To initiate, execute the following command in your terminal. This command will launch a Docker container featuring the Keycloak image in interactive mode, display the contents of the cache-ispn.xml file using the cat command, and subsequently remove the container once it stops running.

docker run -it --rm --entrypoint=cat

quay.io/keycloak/keycloak:22.0.1 opt/keycloak/conf/cache-ispn.xml

You should observe XML content resembling the following.

<!-- XML content goes here -->

To implement JDBC-PING, we need to adjust the Infinispan configuration. Let's create a new file named cache-ispn-jdbc-ping.xml and replicate the content from cache-ispn.xml into it.

Next, we will incorporate the JDBC-PING configuration. In this scenario, we will be utilizing a Postgres database. Insert the highlighted lines within the <jgroups> element and modify the <stack> element to reflect the postgres-jdbc-ping-tcp stack.

<jgroups>

<stack="postgres-jdbc-ping-tcp"/>

</jgroups>

In this configuration, the <jgroups> tag sets up the reliable group communication library for distributed systems. The <stack> tag defines a stack named postgres-jdbc-ping-tcp, which builds upon the TCP stack for node communication.

Inside the <tcp> tag, two further tags configure the JGroups behavior for this stack:

  • The <bind> tag specifies the external IP address for the JGroups discovery process. If the JGROUPS_DISCOVERY_EXTERNAL_IP environment variable is defined, it will be utilized; otherwise, it defaults to 127.0.0.1.
  • The <jdbc-ping> tag employs a JDBC-based discovery protocol to identify other nodes in the cluster. It outlines the required JDBC connection parameters, including the driver, username, password, and connection URL, alongside SQL commands for initializing the schema and managing ping data.

Section 1.2: Launching the Keycloak Cluster

Let’s create a Docker network named keycloak-net. Execute the following command in your terminal:

docker network create keycloak-net

Next, we will start a Postgres Docker container. The command below initializes a new Docker container in detached mode (-d) with the name postgres.

docker run -d --rm --name postgres

-e POSTGRES_DB=keycloak

-e POSTGRES_USER=keycloak

-e POSTGRES_PASSWORD=password

--network keycloak-net

postgres:15.3

Below are the commands necessary to launch the Keycloak instances. Ensure you're in the directory where the cache-ispn-jdbc-ping.xml file is stored before executing the following commands.

To start the first Keycloak instance, run:

docker run --rm --name keycloak-1 -p 8080:8080

-e KEYCLOAK_ADMIN=admin

-e KEYCLOAK_ADMIN_PASSWORD=admin

-e KC_DB=postgres

-e KC_DB_URL_HOST=postgres

-e KC_DB_URL_DATABASE=keycloak

-e KC_DB_USERNAME=keycloak

-e KC_DB_PASSWORD=password

-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-1

-e KC_CACHE_CONFIG_FILE=cache-ispn-jdbc-ping.xml

-v ${PWD}/cache-ispn-jdbc-ping.xml:/opt/keycloak/conf/cache-ispn-jdbc-ping.xml

--network keycloak-net

quay.io/keycloak/keycloak:22.0.1 start-dev

In a separate terminal, execute the following command to start the second Keycloak instance:

docker run --rm --name keycloak-2 -p 8081:8080

-e KEYCLOAK_ADMIN=admin

-e KEYCLOAK_ADMIN_PASSWORD=admin

-e KC_DB=postgres

-e KC_DB_URL_HOST=postgres

-e KC_DB_URL_DATABASE=keycloak

-e KC_DB_USERNAME=keycloak

-e KC_DB_PASSWORD=password

-e JGROUPS_DISCOVERY_EXTERNAL_IP=keycloak-2

-e KC_CACHE_CONFIG_FILE=cache-ispn-jdbc-ping.xml

-v ${PWD}/cache-ispn-jdbc-ping.xml:/opt/keycloak/conf/cache-ispn-jdbc-ping.xml

--network keycloak-net

quay.io/keycloak/keycloak:22.0.1 start-dev

Notice that the Docker container name is specified for the JGROUPS_DISCOVERY_EXTERNAL_IP environment variable. We also set up a volume connection between the host and the Docker containers, allowing the cache-ispn-jdbc-ping.xml file to be accessible inside the containers.

After starting the instances, you can monitor the logs for messages indicating that the Infinispan cluster is operational.

Section 1.3: Verifying Distributed Caching via Keycloak UI

To check the setup, open two different browsers—such as Chrome and Safari or Chrome and Incognito Chrome.

In one browser, navigate to http://localhost:8080/admin/, and in the other, go to http://localhost:8081/admin/.

Log in using admin for both the username and password. Click on "Sessions" in the left menu, where you should see two active sessions for the admin user.

Checking the JGROUPSPING Table

Next, let’s inspect the JGROUPSPING table in Postgres where the ping data is recorded. Access the Postgres shell by executing the following command:

docker exec -it postgres psql -U keycloak -d keycloak

Once inside the Postgres shell, run this SQL command:

SELECT * FROM JGROUPSPING;

You should be able to view the entries stored in the JGROUPSPING table.

Section 1.4: Shutting Down the Keycloak Cluster

To terminate the Keycloak Cluster, return to the terminals running the Keycloak instances and press Ctrl+C. Then, execute the following commands to stop the Postgres Docker container and remove the keycloak-net network:

docker rm -fv postgres

docker network rm keycloak-net

Conclusion

In summary, we have successfully set up a Keycloak Cluster utilizing JDBC-PING for distributed caching in this tutorial, using Postgres as the database. Keycloak, however, also supports other databases like MySQL, MariaDB, and Microsoft SQL Server.

Additionally, I maintain a Docker image called keycloak-clustered on Docker Hub, providing out-of-the-box clustering for Keycloak instances using JDBC-PING for all supported databases. You can find the code in the keycloak-clustered GitHub repository.

Support and Engagement

If you found this article helpful and would like to show your support, consider the following actions:

  • Engage by clapping, highlighting, and replying to my story. I'm happy to answer any questions you may have.
  • Share this article on social media.
  • Follow me on Medium, LinkedIn, and Twitter.
  • Subscribe to my newsletter to stay updated on my latest posts.

This video titled "KEYCLOAK Cluster - Up and Running in Seconds" by Niko Köbler provides a quick overview of setting up a Keycloak cluster efficiently.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Transformative Insights from Founder-Led Sales for Entrepreneurs

Discover five key reasons why embracing founder-led sales can enhance your entrepreneurial journey and improve your skills.

Innovative AI Solutions to Combat Mass Shootings Effectively

Exploring AI integration in technology to enhance public safety and prevent mass shootings.

Unlocking Income Potential: Websites That Pay for Your Words

Discover unique websites that offer lucrative writing opportunities for aspiring writers.

My Essential Time Management Framework: Four Key Books

Explore four influential books that shaped my approach to effective time management and personal productivity.

Finding Balance: Beyond Financial Metrics in Life Choices

Explore how life decisions can transcend financial measurements, emphasizing the importance of personal fulfillment over monetary value.

Stay Alert: The Rising Threat of

Discover the alarming rise of

Mastering Promise Chaining for Asynchronous Operations in JavaScript

Explore how to use promise chaining in JavaScript for efficient management of asynchronous operations.

Finding True Happiness in a Fast-Paced World

Discover the paradox of happiness and how slowing down can enrich your life.