Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Slow websites SUCK

Slide 3

Slide 3 text

Web performance is an essential part of the user experience

Slide 4

Slide 4 text

~ SLOW DOWN

Slide 5

Slide 5 text

THROWING SERVERS AT THE PROBLEM

Slide 6

Slide 6 text

Mo' money Mo' servers Mo' problems

Slide 7

Slide 7 text

Identify slowest parts

Slide 8

Slide 8 text

OPTIMIZE

Slide 9

Slide 9 text

After a while you hit the limits

Slide 10

Slide 10 text

Caching

Slide 11

Slide 11 text

Hi, I'm Thijs

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

r va // s: tp ht sh ni rg .o

Slide 15

Slide 15 text

Released 20 years ago

Slide 16

Slide 16 text

USER VARNISH SERVER

Slide 17

Slide 17 text

Cache-Control: public, max-age=3600

Slide 18

Slide 18 text

Cache-Control: private, no-cache, no-store

Slide 19

Slide 19 text

fi Varnish Con guration Language

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

vcl 4.1; backend default { .host = "127.0.0.1"; .port = "8080"; } sub vcl_recv { if(req.url ~ "^/admin(/.*|$)") { return(pass); } unset req.http.Cookie; }

Slide 22

Slide 22 text

vcl 4.1; backend default { .host = "127.0.0.1"; .port = "8080"; } sub vcl_backend_response { if (beresp.http.Content-Type ~ "^image/") { set beresp.ttl = 1y; } else { set beresp.ttl = 1h; } }

Slide 23

Slide 23 text

VCL templates WordPress Drupal TYPO3 Magento Shopware Symfony

Slide 24

Slide 24 text

What’s new?

Slide 25

Slide 25 text

Version 9

Slide 26

Slide 26 text

Varnish 9 features ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ Native TLS Dynamic backends Structured JSON logging OpenTelemetry support GeoIP Accept header cleanup Rate limiting & throttling Tag-based cached invalidation JSON parsing & JQ support LUA & ECMAScript support ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ HMAC, message digest & Base64 Local file server Redis interface Response body manipulation Request body capturing Query string manipulation Header manipulation String functions HTTP client

Slide 27

Slide 27 text

https USER http http TLS PROXY VARNISH SERVER ffl The old days: o oad TLS

Slide 28

Slide 28 text

https USER Varnish native TLS https VARNISH SERVER

Slide 29

Slide 29 text

/usr/sbin/varnishd \ -a :80,http \ -a :443,https ...

Slide 30

Slide 30 text

$ varnishadm tls.cert.load \ /etc/varnish/cert.pem $ varnishadm tls.cert.commit $ varnishadm tls.cert.reload

Slide 31

Slide 31 text

vcl 4.1; backend default { .host = "backend.example.com"; .port = "443"; .ssl = "1"; }

Slide 32

Slide 32 text

Everything is freaking DNS problem Kris Buytaert

Slide 33

Slide 33 text

vcl 4.1; backend default { .host = "backend.example.com"; .port = "80"; } DNS resolution happens at compile time. Changes aren’t spotted at run time.

Slide 34

Slide 34 text

Message from VCC-compiler: Backend host "example.com": resolves to too many addresses. Only one IPv4 and one IPv6 are allowed. Please specify which exact address you want to use, we found all of these: 172.66.147.243:80 104.20.23.154:80 ('/etc/varnish/default.vcl' Line 4 Pos 13) .host = "example.com"; ------------#############-

Slide 35

Slide 35 text

Dynamic backends vcl 4.1; import reqwest; backend default none; sub vcl_init { new be = reqwest.client(base_url = "https://www.example.com/"); } sub vcl_recv { set req.backend_hint = be.backend(); }

Slide 36

Slide 36 text

https://github.com/varnish-rs/varnish-rs

Slide 37

Slide 37 text

Extra VMODs Modules that extend VCL capabilities

Slide 38

Slide 38 text

vcl 4.1; import reqwest; sub vcl_init { new client = reqwest.client(); } sub vcl_recv { client.init("sync", "https://api.example.com/" + req.http.user); if (client.status("sync") != 200) { return (synth(403)); } set req.http.user-id = client.header("sync", "id-header"); }

Slide 39

Slide 39 text

vcl 4.1; import fileserver; backend default none; sub vcl_init { new www = fileserver.root("/var/www/html"); } sub vcl_recv { set req.backend_hint = www.backend(); } No web server needed

Slide 40

Slide 40 text

sub vcl_recv { if(req.url ~ "^/(\?|$)") { set req.url = "/index.php"; } } sub vcl_backend_fetch { if (bereq.url ~ "\.php(\?|$)") { set bereq.backend = php.backend(); } else { set bereq.backend = files.backend(); } } l sub vcl_init { new php = fastcgi.new("php.example.com:9000", "/var/www/html"); new files = fileserver.root("/var/www/html"); } ta en rim backend default none; pe import fastcgi; import fileserver; Ex vcl 4.1;

Slide 41

Slide 41 text

vcl 4.1; import redis; import cookie; Interact with Redis sub vcl_init { new db = redis.db(location="localhost:6379"); } sub vcl_recv { if(req.url ~ "^/admin(/|$)") { cookie.parse(req.http.Cookie); if(!cookie.isset("SESSIONID")) { return(synth(401)); } } } db.command("HGET"); db.push(cookie.get("SESSIONID")); db.push("allowed"); db.execute(); if(db.get_string_reply() != "true") { return(synth(403)); }

Slide 42

Slide 42 text

vcl 4.1; import rers; sub vcl_init { new re_cache = rers.init(100); } sub vcl_deliver { re_cache.replace_resp_body("Welcome (\w+)!", "Welcome to my website!"); set resp.filters = "rers"; }

Slide 43

Slide 43 text

$ docker pull varnish $ helm install varnish -f values.yaml \ oci://docker.io/varnish/varnish-cache $ curl -Ls https://packages.varnish-software.com/varnish/bootstrap-deb.sh | sh \ && sudo apt-get install -y varnish $ curl -s https://packages.varnish-software.com/varnish/bootstrap-rpm.sh | sh \ && sudo yum install -y varnish Get started with Varnish

Slide 44

Slide 44 text

Varnish Gateway API for Kubernetes

Slide 45

Slide 45 text

n ar .v ay w te ga h is rg .o

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

--apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: varnish-gateway namespace: default annotations: cert-manager.io/issuer: letsencrypt spec: gatewayClassName: varnish listeners: - name: http protocol: HTTP port: 80 allowedRoutes: namespaces: from: All - name: https-todo port: 443 protocol: HTTPS hostname: "todo.demo.example.com" tls: mode: Terminate certificateRefs: - name: demo-tls allowedRoutes: namespaces: from: All

Slide 48

Slide 48 text

$ kubectl apply -f varnish-gateway.yaml gateway.gateway.networking.k8s.io/varnish-gateway created $ kubectl get gateways NAME varnish-gateway CLASS varnish ADDRESS 172.31.44.22 PROGRAMMED True AGE 58m

Slide 49

Slide 49 text

--apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: todo-http-route namespace: default spec: parentRefs: - name: varnish-gateway hostnames: - todo.demo.example.com rules: - backendRefs: - name: todo port: 80

Slide 50

Slide 50 text

$ kubectl get svc --field-selector metadata.name=todo NAME todo TYPE NodePort CLUSTER-IP 10.43.78.51 EXTERNAL-IP PORT(S) 80:31666/TCP $ kubectl apply -f todo-gateway-routes.yaml httproute.gateway.networking.k8s.io/todo-http-route created $ kubectl get httproutes NAME todo-http-route HOSTNAMES ["todo.demo.example.com"] AGE 12s AGE 49m

Slide 51

Slide 51 text

--apiVersion: gateway.varnish-software.com/v1alpha1 kind: VarnishCachePolicy metadata: name: cache-todo namespace: default spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: todo-http-route defaultTTL: 1h

Slide 52

Slide 52 text

$ kubectl apply -f varnish-cache-policy-todo.yaml varnishcachepolicy.gateway.varnish-software.com/cache-todo created $ kubectl get varnishcachepolicy NAME cache-todo TARGET KIND HTTPRoute TARGET NAME todo-http-route AGE 28s

Slide 53

Slide 53 text

apiVersion: gateway.varnish-software.com/v1alpha1 kind: VarnishCachePolicy metadata: name: my-cache-policy namespace: default spec: targetRef: group: gateway.networking.k8s.io kind: HTTPRoute # or Gateway name: my-route # sectionName: my-rule # optional: target a specific named rule defaultTTL: 5m # forcedTTL: 1h grace: 30s # serve stale while revalidating (default: 0) keep: 24h # serve stale when backend is down (default: 0) cacheKey: headers: - Accept-Language queryParameters: include: # allowlist (mutually exclusive with exclude) - page - filter # exclude: # denylist # - utm_source bypass: headers: - name: Authorization - name: Cookie valueRegex: "session_id|admin_token"

Slide 54

Slide 54 text

sub vcl_recv { if(req.http.host == "todo.demo.artifactcache.com") { unset req.http.cookie; return(hash); } } sub vcl_backend_response { set beresp.ttl = 1h; if(beresp.http.content-type ~ "^text/css") { set beresp.ttl = 1y; } }

Slide 55

Slide 55 text

$ kubectl create configmap user-vcl \ -n varnish-gateway-system \ --from-file=../conf/user.vcl gatewayClass: defaultParams: userVCL: enabled: true configMap: name: user-vcl key: user.vcl VARNISH GATEWAY VALUES.YAML - - $ helm install -f ../conf/varnish-gateway-values.yaml varnish-gateway \ oci://ghcr.io/varnish/charts/varnish-gateway \ --namespace varnish-gateway-system \ --create-namespace

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

https://varnish.org https://gateway.varnish.org https://varnish-software.com https://varnish-cdn.com

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content