<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/links.adoc" as links>
<#import "/templates/profile.adoc" as profile>

<@tmpl.guide
title="Single-cluster deployments"
summary="Deploy a single Keycloak cluster, optionally across multiple availability-zones" >

== When to use a single-cluster setup

The {project_name} single-cluster setup is targeted at use cases that:

* Deploy to an infrastructure with transparent networking, like for example a single {kubernetes} cluster.
* Desire all healthy {project_name} instances to handle user requests.
* Are constrained to a single
<@profile.ifProduct>
region (e.g. a single AWS region)
</@profile.ifProduct>
<@profile.ifCommunity>
AWS Region or an equivalent low-latency setup.
</@profile.ifCommunity>
* Permit planned outages for maintenance.
* Fit within a defined user and request count.
* Can accept the impact of periodic outages.
* Deployed in data centers with the required network latency and database configuration

[#single-cluster-tested-configuration]
== Tested Configuration

We regularly test {project_name} with the following configuration:

* An OpenShift cluster deployed across three AWS availability zones in the same region.
** Provisioned with https://www.redhat.com/en/technologies/cloud-computing/openshift/aws[Red Hat OpenShift Service on AWS] (ROSA),
using ROSA HCP.

** At least one worker node for each availability-zone
** OpenShift version 4.17.

* Amazon Aurora PostgreSQL database
** High availability with a primary DB instance in one availability zone, and synchronously replicated readers in the other availability zones
** Version ${properties["aurora-postgresql.version"]}

<@profile.ifProduct>
* Support for {project_name} in these configurations may require replicating issues in this tested set up.
</@profile.ifProduct>

[#single-cluster-configuration]
== Configuration

<@profile.ifProduct>

* {project_name} deployed on an OpenShift cluster version 4.17 or later
** For cloud setups, Pods can be scheduled across up to three availability zones within the same region
if OpenShift supports spanning multiple availability zones in that environment and {project_name}'s latency requirements are met.
** For on-premise setups, Pods can be scheduled across up to three datacenters
if OpenShift supports spanning multiple datacenters in that environment and {project_name}'s latency requirements are met.

</@profile.ifProduct>

<@profile.ifCommunity>

* {project_name} deployed on a {kubernetes} cluster
** For cloud setups, Pods can be scheduled across multiple availability zones within the same region
if {project_name}'s latency requirements are met.
** For on-premise setups, Pods can be scheduled across multiple datacenters
if {project_name}'s latency requirements are met.
* {project_name} deployed on virtual machines or bare metal
** Instances can be scheduled across multiple availability zones within the same cloud-provider region or multiple datacenters if {project_name}'s latency requirements are met.

</@profile.ifCommunity>

* Deployments require a round-trip latency of less than 10 ms between {project_name} instances.

* Database
** For a list of supported databases, see <@links.server id="db"/>.
** Deployments spanning multiple availability zones must utilize a database that can tolerate zone failures
and synchronously replicates data between replicas.

<#include "/high-availability/partials/configuration-disclaimer.adoc" />

Read more on each item in the <@links.ha id="single-cluster-building-blocks" /> {section}.

[#single-cluster-load]
<#include "/high-availability/partials/tested-load.adoc" />

<@profile.ifCommunity>

We have successfully scaled to the following load:

* 100,000 users
* 1,000 logins, with 20,000 token refreshes per second.

We used the following setup for this:

* Single-cluster setup consisting of 6 Pods, spread across 3 availability zones in a single AWS region.
** Each Pod with limits of 40 vCPU and 8 GB memory
* Amazon Aurora PostgreSQL multi-az database deployed in two availability zones
** Instance type: `db.r8g.16xlarge` for both reader and writer instance

As the load increased, the CPU usage increased linearly.

</@profile.ifCommunity>

See the <@links.ha id="single-cluster-concepts-memory-and-cpu-sizing" /> {section} for more information.

[#single-cluster-limitations]
== Limitations

<@profile.ifCommunity>
Even with the additional redundancy of three availability-zones, downtime can still occur when:
</@profile.ifCommunity>

* Simultaneous node failures occur
* Rolling out {project_name} upgrades
* Infrastructure fails, for example the {kubernetes} cluster

For more details on limitations see the <@links.ha id="single-cluster-concepts" /> {section}.

== Next steps

The different {sections} introduce the necessary concepts and building blocks.
For each building block, a blueprint shows how to deploy a fully functional example.
Additional performance tuning and security hardening are still recommended when preparing a production setup.

<@profile.ifCommunity>
== Concept and building block overview

* <@links.ha id="single-cluster-concepts" />
* <@links.ha id="single-cluster-building-blocks" />
* <@links.ha id="single-cluster-concepts-database-connections" />
* <@links.ha id="single-cluster-concepts-threads" />
* <@links.ha id="single-cluster-concepts-memory-and-cpu-sizing" />

== Blueprints for building blocks
* <@links.ha id="single-cluster-deploy-aurora" />
* <@links.ha id="single-cluster-deploy-keycloak" />
</@profile.ifCommunity>

</@tmpl.guide>
