---
title: "Varnish - der geheime Held der Website Geschwindigkeit mit Kubernetes"
description: "Erfahre, wie du mit Varnish Cache die Performance deiner Website drastisch steigerst. Perfekt für Kubernetes-Setups mit detaillierter VCL-Konfiguration und Best Practices."
canonical_url: "https://www.blueshoe.de/blog/varnish-website-geschwindigkeit-mit-kubernetes/"
---

Varnish ist ein spezieller HTTP-Cache. Er sitzt vor deiner Webanwendung und speichert fertige Seiten, damit Anfragen blitzschnell direkt aus dem Speicher beantwortet werden können. So wird dein Backend entlastet und deine Seite spürbar schneller, gerade in Kubernetes-Setups ein großer Vorteil.

![Varnish Kubernetes](/img/blog/varnishk8s.svg)

<global-blog-level-info>

- Kubernetes Basics
- Docker Basics
- [HTTP Caching](https://de.wikipedia.org/wiki/HTTP_Caching) Basics
- [Varnish HTTP Cache](https://varnish-cache.org/)

Solltest du Fragen haben, oder dir etwas unklar sein, kannst du die Kommentarfunktion unter dem Artikel nutzen.

</global-blog-level-info>

## Warum Varnish deine Website transformiert

Performance ist alles im Web. Wenn deine Nutzer warten müssen, springen sie ab. Varnish löst dieses Problem elegant: Als HTTP-Cache sitzt er vor deiner Anwendung und liefert Inhalte blitzschnell aus dem Speicher aus. Das Ergebnis? Bis zu 90% weniger Last auf dein Backend und deutlich schnellere Ladezeiten.

## Lass uns starten: Das brauchst du

Bevor wir loslegen, hier kurz die vier Dateien, die du für ein einfaches Setup benötigst:

- `default.vcl`: deine Varnish-Konfiguration
- `Dockerfile`: damit baust du dein Varnish-Image inklusive VCL
- `varnish.yaml`: Deployment und Service für Kubernetes
- `Ingress.yaml`: optional, damit deine Website über einen Domainnamen erreichbar wird

### Die VCL Datei verstehen und anpassen

Schauen wir uns erstmal die einzelnen Teile der `default.vcl` genauer an:

```vcl
backend default {
    .host = "website-svc";
    .port = "3001";
    .first_byte_timeout = 300s;
}
```

Der erste Block legt dein Backend fest. `website-svc` ist dabei der Name des Kubernetes-Services, auf den Varnish zugreift. Der Port `3001` ist der Port deiner Anwendung (zum Beispiel Django), der innerhalb des Clusters erreichbar ist. Mit `first_byte_timeout` stellst du ein, wie lange Varnish auf die erste Antwort vom Backend wartet.

```vcl
sub vcl_recv {
    if (req.method == "GET" && req.http.Cookie !~ "sessionid") {
        unset req.http.Cookie;
    }
}
```

`vcl_recv` wird bei jeder eingehenden Anfrage aufgerufen. Hier wird entschieden, ob Cookies entfernt werden. In diesem Fall entfernt Varnish alle Cookies von GET-Requests, die nicht `sessionid` enthalten. Das macht Caching effektiver, weil verschiedene Cookie-Werte sonst unterschiedliche Cache-Objekte erzeugen würden.

```vcl
sub vcl_backend_response {
    if (bereq.url ~ "^/de-de/aktuelles/.*") {
        set beresp.ttl = 2h;
    } else {
        set beresp.ttl = 12h;
    }
}
```

`vcl_backend_response` wird aufgerufen, wenn Varnish das Backend befragt hat und die Antwort verarbeitet. Hier legst du fest, wie lange Varnish den Inhalt cachen soll. Nachrichten-Seiten bekommen hier zum Beispiel nur 2 Stunden, alles andere bleibt 12 Stunden im Cache.

## Fortgeschrittene VCL-Techniken für die Praxis

**Grace Mode & Saint Mode (Backend-Ausfall überbrücken):**
Mit Grace und Saint Mode kannst du veraltete Inhalte ausliefern, wenn das Backend nicht erreichbar ist. Das erhöht die Ausfallsicherheit enorm.

```vcl
sub vcl_backend_fetch {
    if (beresp.status == 500 || beresp.status == 503) {
        set beresp.saintmode = 5m; // Markiere Backend für 5 Min. als "krank"
        return (abandon);
    }
    set beresp.grace = 2h; // Erlaube, diesen Inhalt 2h über seine TTL hinaus zu servieren
}
```

**Cache-Keys anpassen:**
Manipuliere den Cache-Key, um z.B. unwichtige Query-Parameter zu ignorieren und so die Hit-Rate zu erhöhen.

```vcl
sub vcl_hash {
    // Nur 'id' und 'lang' für den Cache-Key berücksichtigen
    if (req.url ~ "\?") {
        set req.hash += regsuball(req.url, "^.*\?((?:id|lang)=[^&]+).*$", "\1");
    }
    // ...
}
```

**Sicheres Purging via API:**
Richte einen sicheren HTTP-Endpoint zum gezielten Leeren des Caches ein.

```vcl
acl purge {
    "localhost";
    "192.168.1.0"/24; // Erlaube Purging nur aus diesem Netz
}

sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed."));
        }
        return (hash);
    }
}
```

### Dockerfile: VCL ins Image legen

```dockerfile
FROM varnish:stable
COPY default.vcl /etc/varnish/
```

So stellst du sicher, dass deine VCL immer direkt im Container liegt. Dein Image baust du anschließend mit:

```bash
docker build -t varnish:latest .
```

### Deployment und Service definieren

Das Deployment sorgt dafür, dass dein Varnish-Pod dauerhaft läuft und Kubernetes ihn automatisch neu startet, wenn er abstürzt. In unserem Beispiel läuft nur eine Instanz (replicas: 1), für Produktionsumgebungen kannst du hier aber auch mehrere Replikas eintragen.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: varnish
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: varnish
    spec:
      containers:
      - name: varnish
        image: varnish:latest
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: varnish
spec:
  selector:
    app: varnish
  ports:
    - port: 80
      targetPort: 80
```

Der zugehörige Service macht deinen Pod im Cluster erreichbar. Er verbindet den Ingress oder andere Pods mit deinem Varnish-Container. Wichtig ist dabei, dass targetPort und containerPort zusammenpassen.

`Super!` Damit ist nun dein Pod im Cluster erreichbar.

## Ingress-Konfiguration für Domain-Routing

Der Ingress ist das letzte Glied in der Kette. Er sorgt dafür, dass Anfragen aus dem Internet in deinen Cluster gelangen und dort an den richtigen Service, also deinen Varnish, weitergeleitet werden. Dadurch kannst du Domains und TLS-Zertifikate zentral verwalten.

Ein einfaches Beispiel sieht so aus:

```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: varnish-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  rules:
  - host: "example.com"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: varnish
            port:
              number: 80
```

Achte darauf, dass der Name des Services und der Port exakt zu deinem vorher definierten Service passen. So wird der komplette Webtraffic durch Varnish geschleust und deine Anwendung profitiert vom Cache.

## Monitoring und Debugging

Hier noch ein paar praktische Befehle, um deinen Cache und den Varnish-Server zu überwachen und besser zu steuern:

```bash
varnishstat
```

Zeigt live Cache-Statistiken, zum Beispiel Hits und Misses.

```bash
varnishlog
```

Zeigt genau, warum Requests gecacht wurden oder nicht.

```bash
varnishadm ban "req.url ~ .*"
```

Damit leerst du gezielt den Cache und erzwingst neue Inhalte.

```bash
varnishadm ping
```

Prüft, ob dein Varnish-Admin erreichbar ist.

```bash
varnishadm status
```

Zeigt den aktuellen Status deines Varnish-Prozesses.

## Best Practices für optimales Caching

### 1. Cache-Strategien definieren

- Statische Inhalte länger cachen (CSS, JS, Bilder)
- Dynamische Inhalte kürzer cachen
- Session-basierte Inhalte individuell behandeln

### 2. Performance-Monitoring einrichten

- Regelmäßig Cache-Hit-Rate überprüfen
- Speicherauslastung im Blick behalten
- Backend-Gesundheit überwachen

### 3. Cache-Invalidierung planen

- Automatisierte Prozesse für Content-Updates
- Gezielte Invalidierung statt komplettes Leeren
- Health-Checks für Backend-Server

## Varnish im Vergleich: Die richtige Caching-Strategie wählen

Varnish ist extrem mächtig, aber nicht immer die einzige Lösung. Wie schlägt es sich im Vergleich zu anderen Caching-Mechanismen?

<table>
<thead>
  <tr>
    <th align="left">
      Caching-Lösung
    </th>
    
    <th align="left">
      Stärken
    </th>
    
    <th align="left">
      Schwächen
    </th>
    
    <th align="left">
      Optimal für...
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td align="left">
      <strong>
        Varnish Cache
      </strong>
    </td>
    
    <td align="left">
      <strong>
        Maximale Flexibilität
      </strong>
      
       durch VCL; Caching von ganzen HTTP-Objekten; Features wie Grace/Saint Mode.
    </td>
    
    <td align="left">
      <strong>
        Höhere Komplexität
      </strong>
      
       als einfache Caches; kein nativer TLS-Support (benötigt einen Proxy davor).
    </td>
    
    <td align="left">
      ...komplexe Websites (z.B. E-Commerce, News-Portale) mit dynamischen Inhalten, die eine feingranulare Cache-Steuerung benötigen.
    </td>
  </tr>
  
  <tr>
    <td align="left">
      <strong>
        Nginx Caching
      </strong>
    </td>
    
    <td align="left">
      <strong>
        Einfache Konfiguration
      </strong>
      
      ; direkt im Webserver integriert; sehr performant; kann TLS terminieren.
    </td>
    
    <td align="left">
      <strong>
        Weniger flexible
      </strong>
      
       Cache-Logik als Varnish; primär für statische Assets und einfache Responses.
    </td>
    
    <td align="left">
      ...einfachere Websites und Anwendungen, bei denen ein unkomplizierter Cache für statische Dateien und API-Antworten ausreicht.
    </td>
  </tr>
  
  <tr>
    <td align="left">
      <strong>
        CDN (z.B. Cloudflare)
      </strong>
    </td>
    
    <td align="left">
      <strong>
        Global verteilt
      </strong>
      
       (geringe Latenz weltweit); Schutz vor DDoS-Angriffen; einfaches Setup.
    </td>
    
    <td align="left">
      <strong>
        Kostenintensiver
      </strong>
      
      ; weniger Kontrolle über die Cache-Invalidierung; "Blackbox".
    </td>
    
    <td align="left">
      ...global agierende Websites, die von einem verteilten Cache und zusätzlichen Sicherheitsfeatures profitieren wollen.
    </td>
  </tr>
</tbody>
</table>

## Häufig gestellte Fragen (FAQ)

### Wie kann ich überprüfen, ob eine Seite aus dem Varnish-Cache geladen wird?

Überprüfe die HTTP-Header der Antwort in den Entwicklertools deines Browsers. Varnish fügt typischerweise Header wie `X-Varnish` (interne Transaktions-ID) und `Age` (wie lange das Objekt im Cache liegt) hinzu. Ein `Age`-Wert größer als 0 ist ein sicheres Zeichen für einen Cache-Hit.

### Warum ist meine Cache-Hit-Rate niedrig?

Die häufigsten Gründe sind:

1. **Cookies:** Varnish cacht standardmäßig keine Anfragen mit Cookies. Passe deine `vcl_recv` an, um unnötige Cookies zu entfernen.
2. **Set-Cookie-Header vom Backend:** Wenn dein Backend einen `Set-Cookie`-Header sendet, wird die Antwort nicht gecacht.
3. **Cache-Control-Header:** Achte auf `Cache-Control: private` oder `max-age=0` vom Backend.

### Wie schütze ich den Varnish-Admin-Port in Kubernetes?

Der Admin-Port sollte niemals extern erreichbar sein. Stelle sicher, dass dein Kubernetes-Service für Varnish nur den HTTP-Port (z.B. 80) freigibt. Der Zugriff auf `varnishadm` sollte nur über `kubectl exec` in den Pod erfolgen.

### Wie viel RAM bzw. Speicher brauche ich für Varnish?

Das hängt stark von deinem Usage‑Profil ab. Empfohlen wird eine RAM‑Konfiguration zwischen 1 GB und 16 GB, kombiniert mit SSD‑Speicher.

### Kann Varnish auch ohne Query‑Parameter cachen?

Ja, du kannst Query‑Parameter entfernen (z. B. per RegEx in VCL), um nur ein Objekt zu cachen:

```vcl
sub vcl_recv {
  set req.url = regsub(req.url, "\?.*", "");
}
```

### Wie lassen sich benutzerdefinierte Fehlerseiten konfigurieren?

Über `vcl_error` kannst du eigene HTML‑Seiten mit einer synthetischen Antwort erstellen. Beispiel:

```vcl
sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic {"<html>…</html>"};
  deliver;
}
```

## Fazit

Damit bist du jetzt komplett durch. Dein Setup von `default.vcl` bis zum Ingress steht und Varnish sorgt jetzt dafür, dass deine Seite deutlich schneller lädt. Mit der richtigen Konfiguration wird Varnish zum geheimen Helden deiner Website-Performance.

<global-button :color="blue" :label="Mehr über Varnish erfahren" :target="_blank" :url="https://varnish-cache.org" className="mb-6">



</global-button>

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
