Commit 8fff6733 authored by Geoff Simmons's avatar Geoff Simmons

First VCL template for a self-sharding Varnish cluster.

parent c1f1433e
vcl 4.0;
import std;
import directors;
probe vk8s_probe_varnish {
.request = "HEAD /vk8s_cluster_health HTTP/1.1"
"Host: vk8s_cluster";
.interval = 1s;
}
{{range $node := .ClusterNodes -}}
backend {{$node.Name}} {
.host = "{{(index $node.Addresses 0).IP}}";
.port = "{{(index $node.Addresses 0).Port}}";
.probe = probe_varnish;
}
{{end -}}
acl vk8s_cluster_acl {
{{- range $node := .ClusterNodes}}
"{{(index $node.Addresses 0).IP}}";
{{- end}}
}
sub vcl_init {
new vk8s_cluster = directors.shard();
{{range $node := .ClusterNodes -}}
varnish_director.add_backend({{$node.Name}});
{{end -}}
varnish_director.reconfigure();
}
sub vcl_recv {
if (remote.ip ~ vk8s_cluster_acl) {
if (req.http.Host == "vk8s_cluster") {
if (req.url == "/vk8s_cluster_health") {
return (vcl(vk8s_readiness));
}
return (synth(404));
}
# prevent deadlock for accidental cyclic requests
set req.hash_ignore_busy = true;
# if we're async, don't deliver stale
if (req.http.VK8S-Is-Bgfetch == "true") {
set req.grace = 0s;
}
return (hash);
}
}
sub vcl_backend_fetch {
if (bereq.retries == 0
&& !bereq.uncacheable
&& remote.ip !~ vk8s_cluster_acl
&& "" + varnish_director.backend(resolve=NOW) != server.identity) {
set bereq.backend = varnish_director.backend(resolve=LAZY);
set bereq.http.VK8S-Is-Bgfetch = bereq.is_bgfetch;
return (fetch);
}
}
sub vcl_backend_response {
if (bereq.backend == varnish_director.backend(resolve=LAZY)) {
if (beresp.http.VK8S-Cluster-TTL) {
set beresp.ttl = std.duration(
beresp.http.VK8S-Cluster-TTL + "s", 1s);
{{- /* XXX make this TTL configurable */}}
if (beresp.ttl > 5m) {
set beresp.ttl = 5m;
}
unset beresp.http.VK8S-Cluster-TTL;
}
else {
set beresp.uncacheable = true;
}
return (deliver);
}
}
sub vcl_backend_error {
if (bereq.backend == varnish_director.backend(resolve=LAZY)) {
return (deliver);
}
}
sub vcl_deliver {
unset resp.http.VK8S-Cluster-TTL;
if (remote.ip ~ vk8s_cluster_acl) {
if (! obj.uncacheable) {
set resp.http.X-Cluster-TTL = obj.ttl;
}
return (deliver);
}
}
......@@ -34,6 +34,7 @@ import (
"path/filepath"
"reflect"
"testing"
"text/template"
)
var teaSvc = Service{
......@@ -215,3 +216,58 @@ func TestCanoncial(t *testing.T) {
}
}
}
var varnishCluster = struct{
ClusterNodes []Service
}{
ClusterNodes: []Service{
Service{
Name: "varnish-8445d4f7f-z2b9p",
Addresses: []Address{
{"172.17.0.12", 80},
},
},
Service{
Name: "varnish-8445d4f7f-k22dn",
Addresses: []Address{
{"172.17.0.13", 80},
},
},
Service{
Name: "varnish-8445d4f7f-ldljf",
Addresses: []Address{
{"172.17.0.14", 80},
},
},
},
}
func TestShardTemplate(t *testing.T) {
var buf bytes.Buffer
tmpl, err := template.New("self-shard.tmpl").Funcs(fMap).
ParseFiles("self-shard.tmpl")
if err != nil {
t.Error("Cannot parse shard template:", err)
return
}
if err := tmpl.Execute(&buf, varnishCluster); err != nil {
t.Error("Execute():", err)
return
}
t.Log(buf.String())
// goldpath := filepath.Join("testdata", "ingressrule.golden")
// gold, err := ioutil.ReadFile(goldpath)
// if err != nil {
// t.Fatalf("Error reading %s: %v", goldpath, err)
// }
// if !bytes.Equal(buf.Bytes(), gold) {
// t.Errorf("Generated VCL for IngressSpec does not match gold "+
// "file: %s", goldpath)
// if testing.Verbose() {
// t.Log("Generated VCL:", string(buf.Bytes()))
// t.Log(goldpath, ":", string(gold))
// }
// }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment