-
Notifications
You must be signed in to change notification settings - Fork 4
/
restic.jsonnet
127 lines (117 loc) · 3.65 KB
/
restic.jsonnet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
local kube = import "kube.libsonnet";
local utils = import "utils.libsonnet";
local certman = import "cert-manager.jsonnet";
// NB: create accounts using
// kubectl -n restic exec -ti rest-server-xxx create_user myuser
// (modifies /data/.htpasswd in place)
local host = "restic.oldmacdonald.farm";
{
namespace:: {metadata+: {namespace: "restic"}},
ns: kube.Namespace($.namespace.metadata.namespace),
cert: certman.Certificate("cert") + $.namespace {
spec+: {
issuer_:: certman.letsencryptProd,
local i = self.issuer_,
issuerRef: {
name: i.metadata.name,
[if std.objectHas(i.metadata, "namespace") then "namespace"]: i.metadata.namespace,
kind: i.kind,
},
isCA: false,
usages: ["digital signature", "key encipherment"],
dnsNames: [host],
secretName: "ingress-tls",
duration_h_:: 365 * 24 / 4, // 3 months
duration: "%dh" % self.duration_h_,
renewBefore_h_:: self.duration_h_ / 3,
renewBefore: "%dh" % self.renewBefore_h_,
privateKey: {algorithm: "ECDSA"},
revisionHistoryLimit: 1,
},
},
ingress: utils.Ingress("ingress") + $.namespace {
local this = self,
host: host,
target_svc: $.svc,
metadata+: {
annotations+: {
"kubernetes.io/ingress.class": "nginx-internal",
// restic upload sends large bodies (that's the point)
"nginx.ingress.kubernetes.io/proxy-body-size": "0",
},
},
spec+: {
tls+: [{
hosts: [this.host],
secretName: $.cert.spec.secretName,
}],
},
},
svc: kube.Service("rest-server") + $.namespace {
target_pod: $.deploy.spec.template,
spec+: {
ports: [{
port: 80,
name: "http",
targetPort: "http",
}],
},
},
data: kube.PersistentVolumeClaim("data") + $.namespace {
storageClass: "csi-cephfs",
storage: "200Gi",
spec+: {
accessModes: ["ReadWriteMany"],
},
},
hpa: kube.HorizontalPodAutoscaler("rest-server") + $.namespace {
target: $.deploy,
spec+: {
maxReplicas: 5,
},
},
deploy: kube.Deployment("rest-server") + $.namespace {
spec+: {
template+: utils.PromScrape(8000) {
spec+: {
volumes_+: {
data: kube.PersistentVolumeClaimVolume($.data),
},
containers_+: {
default: kube.Container("rest-server") {
image: "restic/rest-server:0.11.0", // renovate
ports_+: {
http: {containerPort: 8000},
},
env_+: {
OPTIONS: std.join(" ", ["--%s=%s" % kv for kv in kube.objectItems(self.options_)]),
options_:: {
prometheus: true,
"max-size": kube.siToNum($.data.storage),
// TODO: enable nginx->backend TLS using self-signed certs
// https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-certificate-authentication
//tls: true,
//"tls-cert": "/cert/tls.crt",
//"tls-key": "/cert/tls.key",
},
},
volumeMounts_+: {
data: {mountPath: "/data"},
},
resources: {
requests: {cpu: "10m", memory: "25Mi"},
},
livenessProbe: {
tcpSocket: {port: "http"}, // FIXME
//httpGet: {path: "/config", port: "http"},
failureThreshold: 3,
timeoutSeconds: 10,
},
readinessProbe: self.livenessProbe,
},
},
},
},
},
},
}