blob: 16c59bb015bb6d557dd7c73e38906bfce70c70c0 [file] [log] [blame]
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +02001# Common cluster configuration.
2# This defines what Kubernetes resources are required to turn a bare k8s
3# deployment into a fully working cluster.
4# These assume that you're running on bare metal, and using the corresponding
5# NixOS deployment that we do.
6
7local kube = import "../../kube/kube.libsonnet";
8local policies = import "../../kube/policies.libsonnet";
9
10local calico = import "lib/calico.libsonnet";
11local certmanager = import "lib/cert-manager.libsonnet";
12local coredns = import "lib/coredns.libsonnet";
Serge Bazanski2414afe2021-05-24 15:08:06 +020013local identd = import "lib/identd.libsonnet";
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +020014local metallb = import "lib/metallb.libsonnet";
15local metrics = import "lib/metrics.libsonnet";
16local nginx = import "lib/nginx.libsonnet";
17local prodvider = import "lib/prodvider.libsonnet";
18local rook = import "lib/rook.libsonnet";
19local pki = import "lib/pki.libsonnet";
20
21{
22 Cluster(short, realm):: {
23 local cluster = self,
24 local cfg = cluster.cfg,
25
26 short:: short,
27 realm:: realm,
28 fqdn:: "%s.%s" % [cluster.short, cluster.realm],
29
30 cfg:: {
31 // Storage class used for internal services (like registry). This must
32 // be set to a valid storage class. This can either be a cloud provider class
33 // (when running on GKE &co) or a storage class created using rook.
34 storageClassNameRedundant: error "storageClassNameRedundant must be set",
35 },
36
37 // These are required to let the API Server contact kubelets.
38 crAPIServerToKubelet: kube.ClusterRole("system:kube-apiserver-to-kubelet") {
39 metadata+: {
40 annotations+: {
41 "rbac.authorization.kubernetes.io/autoupdate": "true",
42 },
43 labels+: {
44 "kubernetes.io/bootstrapping": "rbac-defaults",
45 },
46 },
47 rules: [
48 {
49 apiGroups: [""],
50 resources: ["nodes/%s" % r for r in [ "proxy", "stats", "log", "spec", "metrics" ]],
51 verbs: ["*"],
52 },
53 ],
54 },
55 crbAPIServer: kube.ClusterRoleBinding("system:kube-apiserver") {
56 roleRef: {
57 apiGroup: "rbac.authorization.k8s.io",
58 kind: "ClusterRole",
59 name: cluster.crAPIServerToKubelet.metadata.name,
60 },
61 subjects: [
62 {
63 apiGroup: "rbac.authorization.k8s.io",
64 kind: "User",
65 # A cluster API Server authenticates with a certificate whose CN is == to the FQDN of the cluster.
66 name: cluster.fqdn,
67 },
68 ],
69 },
70
71 // This ClusterRole is bound to all humans that log in via prodaccess/prodvider/SSO.
72 // It should allow viewing of non-sensitive data for debugability and openness.
73 crViewer: kube.ClusterRole("system:viewer") {
74 rules: [
75 {
76 apiGroups: [""],
77 resources: [
78 "nodes",
79 "namespaces",
80 "pods",
81 "configmaps",
82 "services",
83 ],
84 verbs: ["list"],
85 },
86 {
87 apiGroups: ["metrics.k8s.io"],
88 resources: [
89 "nodes",
90 "pods",
91 ],
92 verbs: ["list"],
93 },
94 {
95 apiGroups: ["apps"],
96 resources: [
97 "statefulsets",
98 ],
99 verbs: ["list"],
100 },
101 {
102 apiGroups: ["extensions"],
103 resources: [
104 "deployments",
105 "ingresses",
106 ],
107 verbs: ["list"],
Piotr Dobrowolski4e46d502024-01-09 23:21:01 +0100108 },
109 {
110 apiGroups: ["rbac.authorization.k8s.io"],
111 resources: [
112 "clusterroles",
113 "roles",
114 "clusterrolebindings",
115 "rolebindings",
116 ],
117 verbs: ["list", "get"],
118 },
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +0200119 ],
120 },
121 // This ClusterRole is applied (scoped to personal namespace) to all humans.
122 crFullInNamespace: kube.ClusterRole("system:admin-namespace") {
123 rules: [
124 {
125 apiGroups: ["", "extensions", "apps"],
126 resources: ["*"],
127 verbs: ["*"],
128 },
129 {
130 apiGroups: ["batch"],
131 resources: ["jobs", "cronjobs"],
132 verbs: ["*"],
133 },
Serge Bazanskif40c9242021-02-07 19:23:43 +0000134 {
135 apiGroups: ["networking.k8s.io"],
136 resources: ["ingresses"],
137 verbs: ["*"],
138 },
Patryk Jakuszewd0a0b182022-01-25 21:05:49 +0100139 {
Piotr Dobrowolski7e841062023-04-23 11:36:15 +0200140 apiGroups: ["cert-manager.io/v1"],
Patryk Jakuszewd0a0b182022-01-25 21:05:49 +0100141 resources: ["certificates"],
142 verbs: ["*"],
143 },
Piotr Dobrowolski4e46d502024-01-09 23:21:01 +0100144 {
145 apiGroups: ["networking.k8s.io"],
146 resources: ["networkpolicies"],
147 verbs: ["list", "get"],
148 },
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +0200149 ],
150 },
151 // This ClusterRoleBindings allows root access to cluster admins.
152 crbAdmins: kube.ClusterRoleBinding("system:admins") {
153 roleRef: {
154 apiGroup: "rbac.authorization.k8s.io",
155 kind: "ClusterRole",
156 name: "cluster-admin",
157 },
158 subjects: [
159 {
160 apiGroup: "rbac.authorization.k8s.io",
161 kind: "User",
162 name: user + "@hackerspace.pl",
163 } for user in [
164 "q3k",
165 "implr",
166 "informatic",
167 ]
168 ],
169 },
170
171 podSecurityPolicies: policies.Cluster {},
172
173 allowInsecureNamespaces: [
174 policies.AllowNamespaceInsecure("kube-system"),
175 policies.AllowNamespaceInsecure("metallb-system"),
176 ],
177
178 // Allow all service accounts (thus all controllers) to create secure pods.
179 crbAllowServiceAccountsSecure: kube.ClusterRoleBinding("policy:allow-all-secure") {
180 roleRef_: cluster.podSecurityPolicies.secureRole,
181 subjects: [
182 {
183 kind: "Group",
184 apiGroup: "rbac.authorization.k8s.io",
185 name: "system:serviceaccounts",
186 }
187 ],
188 },
189
190 // Calico network fabric
191 calico: calico.Environment {},
192
193 // CoreDNS for this cluster.
194 dns: coredns.Environment {
195 cfg+: {
196 cluster_domains: [
197 "cluster.local",
198 cluster.fqdn,
199 ],
200 },
201 },
202
203 // Metrics Server
204 metrics: metrics.Environment {},
205
206 // Metal Load Balancer
207 metallb: metallb.Environment {},
208
209 // Main nginx Ingress Controller
210 nginx: nginx.Environment {},
211
212 // Cert-manager (Let's Encrypt, CA, ...)
213 certmanager: certmanager.Environment {},
214
215 issuer: kube.ClusterIssuer("letsencrypt-prod") {
216 spec: {
217 acme: {
218 server: "https://acme-v02.api.letsencrypt.org/directory",
219 email: "bofh@hackerspace.pl",
220 privateKeySecretRef: {
221 name: "letsencrypt-prod"
222 },
Piotr Dobrowolski7e841062023-04-23 11:36:15 +0200223 solvers: [
224 { http01: { ingress: {} } },
225 ]
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +0200226 },
227 },
228 },
229
Serge Bazanski2414afe2021-05-24 15:08:06 +0200230 // Ident service
231 identd: identd.Environment {},
232
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +0200233 // Rook Ceph storage operator.
234 rook: rook.Operator {
235 operator+: {
236 spec+: {
Serge Bazanski464fb042021-09-11 20:24:27 +0000237 // Downscaled because of b.hswaw.net/6.
Serge Bazanski4f0468f2021-09-11 12:22:53 +0000238 replicas: 0,
Sergiusz Bazanskidbfa9882020-06-06 01:21:45 +0200239 },
240 },
241 },
242
243 // TLS PKI machinery (compatibility with mirko)
244 pki: pki.Environment(cluster.short, cluster.realm),
245
246 // Prodvider
247 prodvider: prodvider.Environment {
248 cfg+: {
249 apiEndpoint: "kubernetes.default.svc.%s" % [cluster.fqdn],
250 },
251 },
252 },
253}