Aller au contenu

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 : -Xms et -Xmx a 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.