blob: 60cbaaa00cfe0fd72539ee158b11102c2a7ebd85 [file] [log] [blame]
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +01001# Top level cluster configuration.
2
3local kube = import "../../kube/kube.libsonnet";
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +02004local policies = import "../../kube/policies.libsonnet";
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +02005
Sergiusz Bazanskiaf3be422019-01-17 18:57:19 +01006local calico = import "lib/calico.libsonnet";
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +02007local certmanager = import "lib/cert-manager.libsonnet";
8local cockroachdb = import "lib/cockroachdb.libsonnet";
9local coredns = import "lib/coredns.libsonnet";
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +010010local metallb = import "lib/metallb.libsonnet";
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +020011local metrics = import "lib/metrics.libsonnet";
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020012local nginx = import "lib/nginx.libsonnet";
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020013local prodvider = import "lib/prodvider.libsonnet";
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +020014local registry = import "lib/registry.libsonnet";
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020015local rook = import "lib/rook.libsonnet";
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +010016
17local Cluster(fqdn) = {
18 local cluster = self,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +020019 local cfg = cluster.cfg,
20
21 cfg:: {
22 // Storage class used for internal services (like registry). This must
23 // be set to a valid storage class. This can either be a cloud provider class
24 // (when running on GKE &co) or a storage class created using rook.
25 storageClassNameRedundant: error "storageClassNameRedundant must be set",
26 },
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +010027
28 // These are required to let the API Server contact kubelets.
29 crAPIServerToKubelet: kube.ClusterRole("system:kube-apiserver-to-kubelet") {
30 metadata+: {
31 annotations+: {
32 "rbac.authorization.kubernetes.io/autoupdate": "true",
33 },
34 labels+: {
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020035 "kubernetes.io/bootstrapping": "rbac-defaults",
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +010036 },
37 },
38 rules: [
39 {
40 apiGroups: [""],
41 resources: ["nodes/%s" % r for r in [ "proxy", "stats", "log", "spec", "metrics" ]],
42 verbs: ["*"],
43 },
44 ],
45 },
Sergiusz Bazanski5bebbeb2019-01-13 22:08:05 +010046 crbAPIServer: kube.ClusterRoleBinding("system:kube-apiserver") {
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +010047 roleRef: {
48 apiGroup: "rbac.authorization.k8s.io",
49 kind: "ClusterRole",
50 name: cluster.crAPIServerToKubelet.metadata.name,
51 },
52 subjects: [
53 {
54 apiGroup: "rbac.authorization.k8s.io",
55 kind: "User",
56 # A cluster API Server authenticates with a certificate whose CN is == to the FQDN of the cluster.
57 name: fqdn,
58 },
59 ],
Sergiusz Bazanski49b9a132019-01-14 00:02:59 +010060 },
61
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020062 // This ClusteRole is bound to all humans that log in via prodaccess/prodvider/SSO.
63 // It should allow viewing of non-sensitive data for debugability and openness.
64 crViewer: kube.ClusterRole("system:viewer") {
65 rules: [
66 {
67 apiGroups: [""],
68 resources: [
69 "nodes",
70 "namespaces",
71 "pods",
72 "configmaps",
73 "services",
74 ],
75 verbs: ["list"],
76 },
77 {
78 apiGroups: ["metrics.k8s.io"],
79 resources: [
80 "nodes",
81 "pods",
82 ],
83 verbs: ["list"],
84 },
85 {
86 apiGroups: ["apps"],
87 resources: [
88 "statefulsets",
89 ],
90 verbs: ["list"],
91 },
92 {
93 apiGroups: ["extensions"],
94 resources: [
95 "deployments",
96 "ingresses",
97 ],
98 verbs: ["list"],
99 }
100 ],
101 },
102 // This ClusterRole is applied (scoped to personal namespace) to all humans.
103 crFullInNamespace: kube.ClusterRole("system:admin-namespace") {
104 rules: [
105 {
106 apiGroups: ["*"],
107 resources: ["*"],
108 verbs: ["*"],
109 },
110 ],
111 },
112 // This ClusterRoleBindings allows root access to cluster admins.
113 crbAdmins: kube.ClusterRoleBinding("system:admins") {
114 roleRef: {
115 apiGroup: "rbac.authorization.k8s.io",
116 kind: "ClusterRole",
117 name: "cluster-admin",
118 },
119 subjects: [
120 {
121 apiGroup: "rbac.authorization.k8s.io",
122 kind: "User",
123 name: user + "@hackerspace.pl",
124 } for user in [
125 "q3k",
126 "implr",
127 "informatic",
128 ]
129 ],
130 },
131
132 podSecurityPolicies: policies.Cluster {},
133
134 allowInsecureNamespaces: [
135 policies.AllowNamespaceInsecure("kube-system"),
136 # TODO(q3k): fix this?
137 policies.AllowNamespaceInsecure("ceph-waw2"),
Sergiusz Bazanski5f3a5e02019-09-25 02:51:51 +0200138 policies.AllowNamespaceInsecure("matrix"),
139 policies.AllowNamespaceInsecure("registry"),
140 policies.AllowNamespaceInsecure("internet"),
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200141 ],
142
143 // Allow all service accounts (thus all controllers) to create secure pods.
144 crbAllowServiceAccountsSecure: kube.ClusterRoleBinding("policy:allow-all-secure") {
145 roleRef_: cluster.podSecurityPolicies.secureRole,
146 subjects: [
147 {
148 kind: "Group",
149 apiGroup: "rbac.authorization.k8s.io",
150 name: "system:serviceaccounts",
151 }
152 ],
153 },
154
Sergiusz Bazanskiaf3be422019-01-17 18:57:19 +0100155 // Calico network fabric
156 calico: calico.Environment {},
Sergiusz Bazanski49b9a132019-01-14 00:02:59 +0100157 // CoreDNS for this cluster.
Sergiusz Bazanski54490d32019-10-02 20:47:18 +0200158 dns: coredns.Environment {
159 cfg+: {
160 cluster_domains: [
161 "cluster.local",
162 fqdn,
163 ],
164 },
165 },
Sergiusz Bazanskiaf3be422019-01-17 18:57:19 +0100166 // Metrics Server
167 metrics: metrics.Environment {},
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +0100168 // Metal Load Balancer
Sergiusz Bazanski14cbacb2019-04-01 18:00:44 +0200169 metallb: metallb.Environment {
170 cfg+: {
171 addressPools: [
172 { name: "public-v4-1", protocol: "layer2", addresses: ["185.236.240.50-185.236.240.63"] },
173 ],
174 },
175 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200176 // Main nginx Ingress Controller
177 nginx: nginx.Environment {},
Piotr Dobrowolski79ddbc52019-04-02 13:20:15 +0200178 certmanager: certmanager.Environment {},
Sergiusz Bazanskie31d64f2019-10-02 20:59:26 +0200179 issuer: kube.ClusterIssuer("letsencrypt-prod") {
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200180 spec: {
181 acme: {
182 server: "https://acme-v02.api.letsencrypt.org/directory",
183 email: "bofh@hackerspace.pl",
184 privateKeySecretRef: {
185 name: "letsencrypt-prod"
186 },
187 http01: {},
188 },
189 },
190 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200191
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200192 // Rook Ceph storage
Sergiusz Bazanskic3b0f762019-06-20 16:42:19 +0200193 rook: rook.Operator {
194 operator+: {
195 spec+: {
196 // TODO(q3k): Bring up the operator again when stability gets fixed
197 // See: https://github.com/rook/rook/issues/3059#issuecomment-492378873
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200198 replicas: 1,
Sergiusz Bazanskic3b0f762019-06-20 16:42:19 +0200199 },
200 },
201 },
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200202
203 // Docker registry
204 registry: registry.Environment {
205 cfg+: {
206 domain: "registry.%s" % [fqdn],
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200207 storageClassName: cfg.storageClassNameParanoid,
208 objectStorageName: "waw-hdd-redundant-2-object",
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200209 },
210 },
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200211
212 // Prodvider
Sergiusz Bazanskid186e942019-10-04 13:46:39 +0200213 prodvider: prodvider.Environment {
214 cfg+: {
215 apiEndpoint: "kubernetes.default.svc.%s" % [cluster.fqdn],
216 },
217 },
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100218};
219
Sergiusz Bazanski49b9a132019-01-14 00:02:59 +0100220
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100221{
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200222 k0: {
223 local k0 = self,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200224 cluster: Cluster("k0.hswaw.net") {
225 cfg+: {
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200226 storageClassNameParanoid: k0.ceph.blockParanoid.name,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200227 },
228 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200229 cockroach: {
Sergiusz Bazanskid5338922019-08-09 14:13:50 +0200230 waw2: cockroachdb.Cluster("crdb-waw1") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200231 cfg+: {
232 topology: [
Sergiusz Bazanski184678b2019-06-22 02:07:41 +0200233 { name: "bc01n01", node: "bc01n01.hswaw.net" },
234 { name: "bc01n02", node: "bc01n02.hswaw.net" },
235 { name: "bc01n03", node: "bc01n03.hswaw.net" },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200236 ],
Sergiusz Bazanskid5338922019-08-09 14:13:50 +0200237 hostPath: "/var/db/crdb-waw1",
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200238 },
239 },
Sergiusz Bazanski1fad2e52019-08-01 20:16:27 +0200240 clients: {
241 cccampix: k0.cockroach.waw2.Client("cccampix"),
242 cccampixDev: k0.cockroach.waw2.Client("cccampix-dev"),
243 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200244 },
245 ceph: {
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200246 // waw1 cluster - dead as of 2019/08/06, data corruption
247 // waw2 cluster
248 waw2: rook.Cluster(k0.cluster.rook, "ceph-waw2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200249 spec: {
250 mon: {
251 count: 3,
252 allowMultiplePerNode: false,
253 },
254 storage: {
255 useAllNodes: false,
256 useAllDevices: false,
257 config: {
258 databaseSizeMB: "1024",
259 journalSizeMB: "1024",
260 },
261 nodes: [
262 {
263 name: "bc01n01.hswaw.net",
264 location: "rack=dcr01 chassis=bc01 host=bc01n01",
265 devices: [ { name: "sda" } ],
266 },
267 {
268 name: "bc01n02.hswaw.net",
269 location: "rack=dcr01 chassis=bc01 host=bc01n02",
270 devices: [ { name: "sda" } ],
271 },
272 {
273 name: "bc01n03.hswaw.net",
274 location: "rack=dcr01 chassis=bc01 host=bc01n03",
275 devices: [ { name: "sda" } ],
276 },
277 ],
278 },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200279 benji:: {
280 metadataStorageClass: "waw-hdd-paranoid-2",
281 encryptionPassword: std.split((importstr "../secrets/plain/k0-benji-encryption-password"), '\n')[0],
282 pools: [
283 "waw-hdd-redundant-2",
284 "waw-hdd-redundant-2-metadata",
285 "waw-hdd-paranoid-2",
286 "waw-hdd-yolo-2",
287 ],
288 s3Configuration: {
289 awsAccessKeyId: "RPYZIROFXNLQVU2WJ4R3",
290 awsSecretAccessKey: std.split((importstr "../secrets/plain/k0-benji-secret-access-key"), '\n')[0],
291 bucketName: "benji-k0-backups",
292 endpointUrl: "https://s3.eu-central-1.wasabisys.com/",
293 },
294 }
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200295 },
296 },
297 // redundant block storage
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200298 blockRedundant: rook.ECBlockPool(k0.ceph.waw2, "waw-hdd-redundant-2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200299 spec: {
300 failureDomain: "host",
301 erasureCoded: {
302 dataChunks: 2,
303 codingChunks: 1,
304 },
305 },
306 },
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200307 // paranoid block storage (3 replicas)
308 blockParanoid: rook.ReplicatedBlockPool(k0.ceph.waw2, "waw-hdd-paranoid-2") {
309 spec: {
310 failureDomain: "host",
311 replicated: {
312 size: 3,
313 },
314 },
315 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200316 // yolo block storage (no replicas!)
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200317 blockYolo: rook.ReplicatedBlockPool(k0.ceph.waw2, "waw-hdd-yolo-2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200318 spec: {
319 failureDomain: "host",
320 replicated: {
321 size: 1,
322 },
323 },
324 },
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200325 objectRedundant: rook.S3ObjectStore(k0.ceph.waw2, "waw-hdd-redundant-2-object") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200326 spec: {
327 metadataPool: {
328 failureDomain: "host",
329 replicated: { size: 3 },
330 },
331 dataPool: {
332 failureDomain: "host",
333 erasureCoded: {
334 dataChunks: 2,
335 codingChunks: 1,
336 },
337 },
338 },
339 },
340 },
Sergiusz Bazanski9496d992019-09-02 16:32:40 +0200341
342 # Used for owncloud.hackerspace.pl, which for now lices on boston-packets.hackerspace.pl.
343 nextcloud: kube._Object("ceph.rook.io/v1", "CephObjectStoreUser", "nextcloud") {
344 metadata+: {
345 namespace: "ceph-waw2",
346 },
347 spec: {
348 store: "waw-hdd-redundant-2-object",
349 displayName: "nextcloud",
350 },
351 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200352 },
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100353}