blob: 1226354c77cf77a500a42023312270cee6aa7a7c [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"),
138 ],
139
140 // Allow all service accounts (thus all controllers) to create secure pods.
141 crbAllowServiceAccountsSecure: kube.ClusterRoleBinding("policy:allow-all-secure") {
142 roleRef_: cluster.podSecurityPolicies.secureRole,
143 subjects: [
144 {
145 kind: "Group",
146 apiGroup: "rbac.authorization.k8s.io",
147 name: "system:serviceaccounts",
148 }
149 ],
150 },
151
Sergiusz Bazanskiaf3be422019-01-17 18:57:19 +0100152 // Calico network fabric
153 calico: calico.Environment {},
Sergiusz Bazanski49b9a132019-01-14 00:02:59 +0100154 // CoreDNS for this cluster.
Sergiusz Bazanskiaf3be422019-01-17 18:57:19 +0100155 dns: coredns.Environment {},
156 // Metrics Server
157 metrics: metrics.Environment {},
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +0100158 // Metal Load Balancer
Sergiusz Bazanski14cbacb2019-04-01 18:00:44 +0200159 metallb: metallb.Environment {
160 cfg+: {
161 addressPools: [
162 { name: "public-v4-1", protocol: "layer2", addresses: ["185.236.240.50-185.236.240.63"] },
163 ],
164 },
165 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200166 // Main nginx Ingress Controller
167 nginx: nginx.Environment {},
Piotr Dobrowolski79ddbc52019-04-02 13:20:15 +0200168 certmanager: certmanager.Environment {},
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200169 issuer: certmanager.ClusterIssuer("letsencrypt-prod") {
170 spec: {
171 acme: {
172 server: "https://acme-v02.api.letsencrypt.org/directory",
173 email: "bofh@hackerspace.pl",
174 privateKeySecretRef: {
175 name: "letsencrypt-prod"
176 },
177 http01: {},
178 },
179 },
180 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200181
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200182 // Rook Ceph storage
Sergiusz Bazanskic3b0f762019-06-20 16:42:19 +0200183 rook: rook.Operator {
184 operator+: {
185 spec+: {
186 // TODO(q3k): Bring up the operator again when stability gets fixed
187 // See: https://github.com/rook/rook/issues/3059#issuecomment-492378873
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200188 replicas: 1,
Sergiusz Bazanskic3b0f762019-06-20 16:42:19 +0200189 },
190 },
191 },
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200192
193 // Docker registry
194 registry: registry.Environment {
195 cfg+: {
196 domain: "registry.%s" % [fqdn],
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200197 storageClassName: cfg.storageClassNameParanoid,
198 objectStorageName: "waw-hdd-redundant-2-object",
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200199 },
200 },
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +0200201
202 // Prodvider
203 prodvider: prodvider.Environment {},
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100204};
205
Sergiusz Bazanski49b9a132019-01-14 00:02:59 +0100206
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100207{
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200208 k0: {
209 local k0 = self,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200210 cluster: Cluster("k0.hswaw.net") {
211 cfg+: {
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200212 storageClassNameParanoid: k0.ceph.blockParanoid.name,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +0200213 },
214 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200215 cockroach: {
Sergiusz Bazanskid5338922019-08-09 14:13:50 +0200216 waw2: cockroachdb.Cluster("crdb-waw1") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200217 cfg+: {
218 topology: [
Sergiusz Bazanski184678b2019-06-22 02:07:41 +0200219 { name: "bc01n01", node: "bc01n01.hswaw.net" },
220 { name: "bc01n02", node: "bc01n02.hswaw.net" },
221 { name: "bc01n03", node: "bc01n03.hswaw.net" },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200222 ],
Sergiusz Bazanskid5338922019-08-09 14:13:50 +0200223 hostPath: "/var/db/crdb-waw1",
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200224 },
225 },
Sergiusz Bazanski1fad2e52019-08-01 20:16:27 +0200226 clients: {
227 cccampix: k0.cockroach.waw2.Client("cccampix"),
228 cccampixDev: k0.cockroach.waw2.Client("cccampix-dev"),
229 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200230 },
231 ceph: {
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200232 // waw1 cluster - dead as of 2019/08/06, data corruption
233 // waw2 cluster
234 waw2: rook.Cluster(k0.cluster.rook, "ceph-waw2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200235 spec: {
236 mon: {
237 count: 3,
238 allowMultiplePerNode: false,
239 },
240 storage: {
241 useAllNodes: false,
242 useAllDevices: false,
243 config: {
244 databaseSizeMB: "1024",
245 journalSizeMB: "1024",
246 },
247 nodes: [
248 {
249 name: "bc01n01.hswaw.net",
250 location: "rack=dcr01 chassis=bc01 host=bc01n01",
251 devices: [ { name: "sda" } ],
252 },
253 {
254 name: "bc01n02.hswaw.net",
255 location: "rack=dcr01 chassis=bc01 host=bc01n02",
256 devices: [ { name: "sda" } ],
257 },
258 {
259 name: "bc01n03.hswaw.net",
260 location: "rack=dcr01 chassis=bc01 host=bc01n03",
261 devices: [ { name: "sda" } ],
262 },
263 ],
264 },
265 },
266 },
267 // redundant block storage
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200268 blockRedundant: rook.ECBlockPool(k0.ceph.waw2, "waw-hdd-redundant-2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200269 spec: {
270 failureDomain: "host",
271 erasureCoded: {
272 dataChunks: 2,
273 codingChunks: 1,
274 },
275 },
276 },
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200277 // paranoid block storage (3 replicas)
278 blockParanoid: rook.ReplicatedBlockPool(k0.ceph.waw2, "waw-hdd-paranoid-2") {
279 spec: {
280 failureDomain: "host",
281 replicated: {
282 size: 3,
283 },
284 },
285 },
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200286 // yolo block storage (no replicas!)
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200287 blockYolo: rook.ReplicatedBlockPool(k0.ceph.waw2, "waw-hdd-yolo-2") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200288 spec: {
289 failureDomain: "host",
290 replicated: {
291 size: 1,
292 },
293 },
294 },
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +0200295 objectRedundant: rook.S3ObjectStore(k0.ceph.waw2, "waw-hdd-redundant-2-object") {
Sergiusz Bazanskic7258f42019-06-21 00:24:09 +0200296 spec: {
297 metadataPool: {
298 failureDomain: "host",
299 replicated: { size: 3 },
300 },
301 dataPool: {
302 failureDomain: "host",
303 erasureCoded: {
304 dataChunks: 2,
305 codingChunks: 1,
306 },
307 },
308 },
309 },
310 },
311 },
Sergiusz Bazanski4d9e72c2019-01-13 22:06:33 +0100312}