Mega Guide: How to Deploy Keycloak in a Cluster with Nginx in 10 Minutes!
Overview of Keycloak and its clustering
Keycloak is a powerful access management system that provides Single Sign-On (SSO), integration with various authentication providers, and role-based access management. By using protocols such as OpenID Connect, OAuth 2.0, and SAML 2.0, Keycloak simplifies the user authentication process in web applications and services.
A standard standalone Keycloak installation is suitable for small deployments, but as the load increases or high availability requirements arise, scaling becomes necessary. In this case, Keycloak needs to be launched in clustered mode, where multiple nodes work together to ensure load balancing and seamless system operation even in case of a node failure.
Clustering Options
There are several ways to organize a Keycloak cluster. One of the most common is Standalone Clustered Mode, where nodes exchange data via JGroups using TCP or auto-discovery mechanisms such as DNS. Another popular approach is deploying Keycloak in Kubernetes, where the cluster is managed using orchestration tools.
For high-load systems, not only fault tolerance but also high speed of operation is important. Infinispan helps here, being used as a distributed cache. It allows accelerating request processing by reducing database load through caching of user sessions and other frequently requested data.
The choice of clustering method depends on the infrastructure and system requirements. If deployment occurs on separate servers or virtual machines, JGroups is more convenient, whereas in a cloud environment, Kubernetes becomes the preferred solution. To achieve maximum performance and minimize delays, caching based on Infinispan is useful.
Why use Nginx as a load balancer
When deploying Keycloak in clustered mode, it is necessary to ensure even load distribution between nodes and reliable access to the service in case of a node failure. In this scenario, a critically important component is the load balancer, which manages incoming requests and directs them to available Keycloak instances. One of the most popular solutions for this purpose is Nginx due to its performance, flexibility, and ease of configuration.
Performance Benefits
- Low resource consumption and high performance
- Handles thousands of simultaneous connections
- Easy deployment on any server
Security & Reliability
- Reverse proxying to hide internal cluster structure
- Automatic failover to available nodes
- SSL/TLS termination for secure communication
Another important advantage is Nginx's support for reverse proxying, which allows hiding the internal structure of the Keycloak cluster from users. Nginx receives HTTP requests from clients and forwards them to one of the Keycloak nodes, while the client only interacts with the balancer without knowing the number or location of the servers in the cluster. This simplifies administration and enhances system security.
Additionally, Nginx provides automatic failover to available nodes in case one of the servers goes down. This is implemented through health check mechanisms that monitor the status of each Keycloak instance and exclude temporarily unavailable nodes from load balancing. This approach ensures uninterrupted system operation even when failures occur on individual servers.
Furthermore, Nginx offers extensive configuration options for optimizing traffic flows, limiting request rates, and protecting against DDoS attacks. It also supports caching mechanisms, which can reduce the load on Keycloak by speeding up the processing of repeated requests.
Different clustering modes (JGroups, Kubernetes)
When deploying Keycloak in clustered mode, it is important to choose the right method for data exchange between nodes. The main task here is to synchronize user sessions, cache data, and properly distribute the load. Keycloak supports two main clustering methods: JGroups and Kubernetes-native clustering.
Clustering via JGroups
JGroups is a Java library that allows cluster nodes to interact with each other in a distributed environment. In the context of Keycloak, it is used for automatic node discovery and data exchange, such as cache synchronization and session replication.
JGroups supports several different node discovery mechanisms:
- TCP — used for reliable connections between known servers, suitable for small private clusters.
- UDP — allows nodes to automatically find each other within the same subnet, which is useful for dynamic environments.
- TCPPING — requires explicitly specifying a list of all nodes, used in static clusters.
- DNS_PING — searches for other nodes through DNS records, which is useful in cloud environments.
JGroups Limitations
JGroups requires detailed network configuration and auto-discovery parameters. Additionally, when using a large number of nodes in a cluster, JGroups efficiency may decrease due to network latency.
Clustering via Kubernetes
In a Kubernetes environment, Keycloak uses built-in auto-discovery mechanisms, replacing JGroups with KUBE_PING. Instead of broadcast messages, Kubernetes provides services for cluster management, significantly simplifying scaling and administration.
Key benefits of Kubernetes clustering:
- Automatic node discovery via the Kubernetes Service API.
- Simplified scaling — new nodes are automatically added to the cluster without the need for manual configuration.
- Enhanced fault tolerance — Kubernetes monitors the state of pods and automatically restarts failed nodes.
- Easy integration with cloud services such as AWS, Google Cloud, and Azure.
To work with Kubernetes, it is necessary to use a StatefulSet or Deployment with a ClusterIP-type service. This allows Keycloak nodes to see each other through Kubernetes' internal DNS.
Which method to choose?
The choice of clustering method depends on the infrastructure and fault tolerance requirements.
- If Keycloak is deployed in a traditional environment (on virtual machines or physical servers), it is better to use JGroups with TCP or DNS_PING.
- If Keycloak operates in a cloud environment or Kubernetes, it is preferable to use KUBE_PING, as it simplifies management and scaling.
What is service discovery and why is it needed?
Service discovery is a mechanism that allows Keycloak nodes to automatically find and identify each other in a clustered environment. In a distributed architecture, this is especially important because nodes must be aware of the existence of other instances for proper data synchronization and fault tolerance.
Dynamic Scaling
- Nodes can be dynamically added or removed in cloud environments
- New nodes automatically register in the cluster
- No manual configuration required for scaling
Fault Tolerance
- Quick adjustment of cluster topology when nodes fail
- Continuous operation despite node failures
- Automatic exclusion of unavailable nodes
How does service discovery work?
When a new Keycloak node starts, it follows several steps:
- It checks the deployment environment and selects the appropriate discovery mechanism (JGroups, Kubernetes API, DNS, etc.).
- It initiates a request to discover other nodes (e.g., via UDP, TCP, a database, or DNS).
- It retrieves a list of active nodes and establishes connections for data exchange.
- It periodically checks the availability of other nodes and removes unavailable instances from the list.
Benefits of Service Discovery
Service discovery enables session data sharing across nodes, ensuring users can switch between nodes while maintaining active sessions. It also significantly reduces administrative overhead by eliminating the need to manually specify node IP addresses in the configuration.
What discovery mechanisms does Keycloak support?
Keycloak uses JGroups, a clustering library for Java applications, and several discovery mechanisms:
Supported Discovery Mechanisms
- TCPPING — Fixed IP addresses of nodes (suitable for static environments).
- UDP PING — Broadcast node discovery within a local network.
- JDBC_PING — Discovery via a shared database (used in Docker, OpenStack).
- KUBE_PING — Integration with the Kubernetes API for automatic discovery of Keycloak pods.
- DNS_PING — Uses DNS queries to determine nodes in cloud environments (AWS, GCP, Azure).
Choosing the right method based on the environment:
- In traditional deployments (bare-metal, VMs), TCPPING or JDBC_PING is used.
- In containerized environments (Docker, OpenShift), JDBC_PING is convenient.
- In Kubernetes, KUBE_PING is the preferred option.
- In cloud services (AWS, GCP, Azure), DNS_PING is the best choice.
Load Balancing Configuration for Keycloak
Load balancing in a Keycloak cluster plays a key role in ensuring even distribution of requests among nodes, system fault tolerance, and scalability. The primary task of the load balancer is to direct incoming requests to active Keycloak nodes, monitor their status, and exclude faulty servers from the traffic flow.
Choosing a Load Balancing Strategy
When configuring load balancing for Keycloak, several request distribution strategies can be used:
- Round Robin — Requests are evenly distributed among all nodes in a circular manner.
- Least Connections — Requests are sent to the server with the fewest active connections, reducing the load on overloaded nodes.
- IP Hash — Users are bound to a specific server based on their IP address to minimize session interruptions.
The most commonly used strategies are Round Robin or Least Connections, but IP Hash can be useful when dealing with distributed sessions.
Nginx as a Reverse Proxy
Nginx acts as a reverse proxy and load balancer for Keycloak, receiving HTTP(S) requests from clients and directing them to available nodes. The Nginx configuration should consider defining the list of Keycloak nodes, setting the load balancing algorithm, and handling node failures.
Configuring Nginx as a Load Balancer
Here's an example Nginx configuration for Keycloak load balancing:
1events {
2 worker_connections 1024;
3}
4
5http {
6 resolver 127.0.0.11 valid=30s ipv6=off;
7
8 upstream keycloak_cluster {
9 zone keycloak_cluster 64k;
10 server keycloak:8080 resolve;
11 }
12
13 upstream keycloak_cluster_ssl {
14 zone keycloak_cluster_ssl 64k;
15 server keycloak:8443 resolve;
16 }
17
18 server {
19 listen 80;
20 server_name _;
21
22 return 301 https://$host$request_uri;
23 }
24
25 server {
26 listen 443 ssl;
27 server_name _;
28
29 ssl_certificate /etc/nginx/certs/tls.crt;
30 ssl_certificate_key /etc/nginx/certs/tls.key;
31
32 ssl_protocols TLSv1.2 TLSv1.3;
33 ssl_ciphers HIGH:!aNULL:!MD5;
34
35 location / {
36 proxy_pass https://keycloak_cluster_ssl;
37 proxy_http_version 1.1;
38
39 proxy_set_header Host $host;
40 proxy_set_header X-Real-IP $remote_addr;
41 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
42 proxy_set_header X-Forwarded-Proto https;
43 }
44 }
45}
Configuration Explanation
The Nginx configuration is based on two upstream blocks:
- keycloak_cluster — Proxies HTTP requests to Keycloak nodes on port 8080.
- keycloak_cluster_ssl — Balances HTTPS requests to port 8443.
Nginx uses dynamic DNS resolution (resolve), allowing it to automatically detect changes in Keycloak node IP addresses. This is especially useful in containerized environments like Docker and Kubernetes.
Additionally, automatic HTTP to HTTPS redirection is configured to ensure that all connections are encrypted.
For security, only modern TLS versions (1.2 and 1.3) are enabled, and weak encryption algorithms are excluded.
Main Reverse Proxy
The primary reverse proxy forwards incoming HTTPS requests to Keycloak:
1proxy_pass https://keycloak_cluster_ssl;
At the same time, headers are passed to ensure correct processing of client requests:
- Host — Forwards the original host so that Keycloak can correctly route requests.
- X-Real-IP and X-Forwarded-For — Preserve the client's IP address.
- X-Forwarded-Proto — Informs Keycloak that the connection was established over HTTPS.
Monitoring and Failure Handling
To improve fault tolerance, a health-check can be configured to check the availability of Keycloak nodes before adding them to the load balancer. This can be done by adding a location check for /realms/master/health:
1location /health {
2 proxy_pass http://keycloak_cluster/realms/master/health;
3 proxy_set_header Host $host;
4}
If Keycloak stops responding, Nginx will automatically remove it from the list of active nodes.
Benefits of Nginx Load Balancing
Using Nginx for Keycloak load balancing ensures high availability, scalability, and security. This configuration automatically redirects HTTP traffic to HTTPS, supports dynamic node discovery, and reduces the load on Keycloak through SSL termination.
In the future, monitoring of node status and protection against overload can be added by implementing request rate limits and response caching.