Varnish : Cache HTTP, routage VCL et WordPress

par

dans

Cet article documente le service de cache HTTP Varnish : le routage VCL entre les backends WordPress, la strategie de cache, les probes et le workflow de mise a jour VCL.

Position dans l architecture

flowchart LR
    Internet((Internet)) --> HAProxy["HAProxy TLS"]
    HAProxy --> Traefik["Traefik Ingress"]
    Traefik --> Varnish["Varnish Cache"]
    Varnish -->|"MISS"| WP["WordPress Pod"]
    Varnish -->|"HIT"| Client["Reponse directe"]

Varnish intercepte les requetes apres Traefik et avant WordPress. Les pages en cache sont servies directement sans toucher PHP/MySQL.

Backends VCL

Le VCL definit deux backends WordPress :

backend jbsky {
    .host = "jbsky-fr-production-wordpress.svc";
    .port = "80";
    .probe = {
        .url = "/healthcheck";
        .timeout = 2s;
        .interval = 30s;
        .window = 3;
        .threshold = 2;
    }
}

backend integ {
    .host = "integ-jbsky-fr-wordpress.svc";
    .port = "80";
    .probe = { ... }
}

Le routage se fait sur le header Host :

  • jbsky.fr et www.jbsky.fr vers le backend prod
  • integ.jbsky.fr vers le backend integ

Probe healthcheck

Le endpoint de probe doit etre /healthcheck (pas /). WordPress retourne un 301 (redirect) sur /, ce qui fait echouer le probe et marque le backend comme sick.

Strategie de cache

  • Les pages HTML sont cachees (TTL configurable par le backend via les headers Cache-Control)
  • Les requetes avec cookie wordpress_logged_in byppassent le cache (utilisateurs connectes)
  • Les requetes POST ne sont jamais cachees
  • L admin WordPress (/wp-admin/, /wp-login.php) n est jamais cache
  • Les assets statiques (JS, CSS, images) sont caches avec un TTL long

Purge du cache

La purge se fait via varnishadm depuis le container :

kubectl exec -n varnish statefulset/varnish -c varnish -- 
  varnishadm -n /var/lib/varnish 'ban req.url ~ .'

Cette commande invalide toutes les entrees du cache. Pour une purge selective :

varnishadm 'ban req.url ~ /mon-article'

Sidecar vcl-reload

Un sidecar busybox surveille les changements du ConfigMap VCL. Quand le VCL est modifie, le sidecar declenche un varnishadm vcl.load suivi de vcl.use pour appliquer la nouvelle configuration sans interruption de service.

StatefulSet vs Deployment

Varnish utilise un StatefulSet car :

  • Le workspace VCL compile (shared objects) est stocke dans /var/lib/varnish
  • Un nom de pod stable facilite le debug et les metriques
  • Le cache en memoire est perdu au restart de toute facon (c est de la memoire, pas du disque)

Metriques

Varnish expose des metriques via varnishstat :

  • Hit rate (pourcentage de requetes servies depuis le cache)
  • Backend health (nombre de backends sains)
  • Memory usage
  • Connections actives

Scale horizontal : shard director

L architecture est concue pour le scale horizontal natif via un shard director Varnish.

flowchart TB
    Traefik["Traefik Ingress"] --> V0["varnish-0"]
    Traefik --> V1["varnish-1"]
    Traefik --> V2["varnish-2"]
    V0 -.->|"forward si pas owner"| V1
    V0 -.->|"forward si pas owner"| V2
    V1 -.->|"forward si pas owner"| V0
    V1 -.->|"forward si pas owner"| V2
    V2 -.->|"forward si pas owner"| V0
    V2 -.->|"forward si pas owner"| V1
    V0 --> WP["WordPress backend"]
    V1 --> WP
    V2 --> WP

Principe du shard director

Le directors.shard() de Varnish distribue les URLs entre les pods via un hash SHA256. Chaque URL n est cachee que par un seul pod (le "shard owner"). Cela evite la duplication de cache et maximise le hit rate global.

Flux d une requete

  • La requete arrive sur n importe quel pod (round-robin via le Service K3s)
  • Le VCL calcule le shard owner pour cette URL
  • Si le pod courant EST le owner : il cache et sert la reponse localement
  • Sinon : il forward au peer owner (header X-Varnish-Peer)
  • Le peer owner cache et retourne la reponse

Decouverte des peers

Les pods se decouvrent via un headless Service K3s (varnish-peers). Les backends peer dans le VCL pointent vers les DNS du StatefulSet :

varnish-{i}.varnish-peers.varnish.svc.cluster.local

Template VCL dynamique

L init-container genere le VCL dynamiquement en fonction du nombre de replicas du StatefulSet. Il n y a pas de limite hardcodee :

  • Interroge l API Kubernetes pour connaitre le nombre de replicas
  • Genere N backends peer_0 a peer_N-1
  • Configure le shard director avec tous les peers
  • Remplace __MY_ORDINAL__ par l index du pod courant

Chaque pod sait quel backend peer correspond a lui-meme, ce qui lui permet de determiner s il est le shard owner sans requete reseau.

Scaling

Le scaling est dynamique et sans limite :

kubectl scale statefulset varnish -n varnish --replicas=N

Apres le scaling, l init-container des nouveaux pods genere automatiquement le VCL adapte. Les pods existants doivent etre restartes (rollout restart) pour prendre en compte les nouveaux peers dans leur VCL.

Le shard director redistribue automatiquement les URLs entre les N pods avec un minimum de cache invalidation (consistent hashing).

Tester le scaling

Procedure de validation du scale horizontal :

# Scale up a 2 replicas
kubectl scale statefulset varnish -n varnish --replicas=2

# Attendre 25s (boot pod + decouverte peer + hot-reload)
sleep 25

# Verifier que le hot-reload a fonctionne sur pod-0
kubectl logs varnish-0 -n varnish -c vcl-reload --tail=5
# Attendu : "VCL 'shard_vX' now active"

# Verifier que les 2 peers sont healthy
kubectl exec varnish-0 -n varnish -c vcl-reload -- \
  sh -c 'printf "backend.list\n" | nc -w 2 localhost 6082' | grep peer
# Attendu : peer_0 healthy, peer_1 healthy

# Verifier le healthcheck des deux pods
kubectl exec varnish-0 -n varnish -c varnish -- /usr/local/bin/init --healthcheck
kubectl exec varnish-1 -n varnish -c varnish -- /usr/local/bin/init --healthcheck

# Scale down
kubectl scale statefulset varnish -n varnish --replicas=1

Le hot-reload est automatique : en moins de 10 secondes apres le boot du nouveau pod, tous les pods existants regenerent leur VCL et l activent via le port admin (nc localhost:6082).


Liens

Articles connexes


Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur la façon dont les données de vos commentaires sont traitées.