Architecture de référence¶
Vue d'ensemble¶
L'architecture de référence deploie Keycloak en mode haute disponibilité avec un clustering Infinispan, un backend PostgreSQL et un reverse proxy TLS en frontal.
graph TD
Clients["Clients<br/>(navigateurs, services)"] -->|HTTPS 443| Proxy["Reverse Proxy<br/>(HAProxy / Traefik)<br/>TLS termination"]
Proxy -->|HTTP 8080| KC1["Keycloak #1<br/>(Quarkus)<br/>Infinispan"]
Proxy -->|HTTP 8080| KC2["Keycloak #2<br/>(Quarkus)<br/>Infinispan"]
Proxy -->|HTTP 8080| KC3["Keycloak #3<br/>(Quarkus)<br/>Infinispan"]
KC1 <--> KC2 <--> KC3
KC1 -->|TCP 5432| PGp["PostgreSQL<br/>(primaire)"]
KC2 --> PGp
KC3 --> PGp
PGp -->|replication| PGr["PostgreSQL<br/>(replica)"] Composants¶
Keycloak (Quarkus)¶
Depuis la version 17, Keycloak utilise Quarkus comme runtime (remplacement de WildFly). Chaque instance est stateless du point de vue applicatif — l'état de session est partage via Infinispan.
| Parametre | Valeur recommandee |
|---|---|
| Runtime | Quarkus (distribution par defaut) |
| Image | quay.io/keycloak/keycloak:25.x |
| Port HTTP | 8080 (interne, derriere le proxy) |
| Port management | 9000 (health checks) |
| Mode | start (production, pas start-dev) |
Infinispan (clustering)¶
Infinispan est embarque dans Keycloak et gère le cache distribue des sessions, tokens et realms. Le clustering se configure via la découverte de pairs.
| Mode de découverte | Environnement | Configuration |
|---|---|---|
| JDBC_PING | Podman / VM | Utilise la base PostgreSQL pour la découverte |
| DNS_PING | Kubernetes | Utilise les DNS headless services |
| TCPPING | Réseau fixe | Liste statique d'adresses IP |
JDBC_PING est le plus polyvalent
JDBC_PING fonctionne dans tous les environnements sans configuration réseau spécifique. Il utilise une table dans PostgreSQL pour que les nœuds Keycloak se decouvrent mutuellement.
PostgreSQL¶
Backend de persistance pour les realms, utilisateurs, clients, rôles et événements.
| Parametre | Valeur recommandee |
|---|---|
| Version | PostgreSQL 15+ |
| Connexions max | 100 par instance Keycloak |
| Extensions | pg_stat_statements (monitoring) |
| Chiffrement | TLS pour les connexions, chiffrement at-rest du volume |
| Backup | pg_basebackup + WAL archiving continu |
Reverse proxy¶
Le reverse proxy termine le TLS et distribue le trafic entre les instances Keycloak.
| Solution | Avantage | Configuration cle |
|---|---|---|
| HAProxy | Performance, stabilité | balance roundrobin, sticky sessions optionnelles |
| Traefik | Découverte automatique, Let's Encrypt | Labels Docker/Podman, middleware headers |
| Nginx | Largement déployé | proxy_set_header X-Forwarded-* |
Headers X-Forwarded obligatoires
Keycloak a besoin des headers X-Forwarded-For, X-Forwarded-Proto et X-Forwarded-Host pour générer correctement les URLs de redirection OIDC. Sans ces headers, les flux d'authentification échouent.
Dimensionnement¶
Estimation des ressources¶
| Profil | Utilisateurs | Sessions concurrentes | Instances Keycloak | CPU / instance | RAM / instance | PostgreSQL |
|---|---|---|---|---|---|---|
| Petit | < 500 | < 100 | 2 | 1 vCPU | 512 Mo | 1 vCPU, 1 Go |
| Moyen | 500 - 5 000 | 100 - 1 000 | 3 | 2 vCPU | 1 Go | 2 vCPU, 4 Go |
| Grand | 5 000 - 50 000 | 1 000 - 10 000 | 5+ | 4 vCPU | 2 Go | 4 vCPU, 8 Go |
Regles de dimensionnement¶
- 1 instance Keycloak supporte environ 500 authentifications/seconde en mode OIDC
- La mémoire JVM doit etre ajustee :
-Xmset-Xmxa 70% de la RAM allouee au conteneur - Le nombre de connexions PostgreSQL = nombre d'instances Keycloak x 20 (pool par defaut)
- Le cache Infinispan consomme environ 100 Mo supplémentaires par 10 000 sessions actives
# Exemple de configuration JVM pour un profil moyen
KC_JAVA_OPTS: >-
-Xms512m
-Xmx768m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-Djgroups.dns.query=keycloak-headless
Déploiement sur Podman¶
Architecture Podman Compose¶
graph TD
subgraph Podman["Hote Podman"]
KC1["Keycloak #1"] --> Net["Podman Network<br/>(keycloak-net)"]
KC2["Keycloak #2"] --> Net
Net --> PG["PostgreSQL"]
Net --> Traefik["Traefik :443"]
end Architecture Kubernetes¶
# Composants Kubernetes
Namespace: keycloak-system
├── Deployment: keycloak (replicas: 3)
├── Service: keycloak (ClusterIP)
├── Service: keycloak-headless (headless, pour DNS_PING)
├── Ingress: keycloak (TLS termination)
├── ConfigMap: keycloak-config
├── Secret: keycloak-credentials
├── Secret: keycloak-db-credentials
├── PodDisruptionBudget: keycloak (minAvailable: 2)
└── HorizontalPodAutoscaler: keycloak (optional)
Namespace: keycloak-db
├── StatefulSet: postgresql (replicas: 2)
├── Service: postgresql (ClusterIP)
├── PersistentVolumeClaim: postgresql-data
└── Secret: postgresql-credentials
Sécurité réseau¶
Segment dedie¶
Keycloak est déployé dans un segment réseau dedie au sein de la zone Entreprise :
| Parametre | Valeur |
|---|---|
| CIDR | 10.20.1.0/24 (segment IAM) |
| VLAN | 201 |
| Accès entrant | HTTPS (443) depuis toutes les zones |
| Accès sortant | LDAPS (636) vers l'annuaire, SMTP (587) pour les emails |
| Accès admin | Port 9000 depuis le segment management uniquement |
Network policies (Kubernetes)¶
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: keycloak-ingress
namespace: keycloak-system
spec:
podSelector:
matchLabels:
app: keycloak
policyTypes:
- Ingress
ingress:
- from: [] # Toutes les zones doivent pouvoir s'authentifier
ports:
- protocol: TCP
port: 8080
- from:
- namespaceSelector:
matchLabels:
name: management
ports:
- protocol: TCP
port: 9000 # Health checks et metriques
Points d'attention¶
Single Point of Failure
Keycloak est un SPOF pour tous les services. Si l'IAM est indisponible, aucun utilisateur ne peut s'authentifier. Le déploiement HA avec minimum 2 instances est obligatoire en production.
Cache distribue vs sessions sticky
Avec Infinispan correctement configure, les sessions sont partagees entre toutes les instances. Les sticky sessions au niveau du reverse proxy ne sont pas nécessaires mais peuvent améliorer les performances en evitant les lectures cache distantes.