blob: 8e8673a8086e1b37e50829fe3f43c73b62642a05 [file] [log] [blame]
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +02001# Deploy a per-cluster Nginx Ingress Controller
2
3local kube = import "../../../kube/kube.libsonnet";
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +02004local policies = import "../../../kube/policies.libsonnet";
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +02005
6{
7 Environment: {
8 local env = self,
9 local cfg = env.cfg,
10 cfg:: {
Serge Bazanski2e8d24b2021-03-25 18:39:52 +010011 # Built from nginx-ingress-controller/Dockerfile:
12 #
13 # $ cd cluster/kube/lib/nginx-ingress-controller
14 # $ docker build -t eu.gcr.io/bgpwtf/nginx-ingress-controller:v0.44.0-r1 .
15 # [..]
16 # (2/8) Upgrading libcrypto1.1 (1.1.1i-r0 -> 1.1.1k-r0)
17 # (3/8) Upgrading libssl1.1 (1.1.1i-r0 -> 1.1.1k-r0
18 # [...]
19 # (8/8) Upgrading openssl (1.1.1i-r0 -> 1.1.1k-r0)
20 # $ docker push eu.gcr.io/bgpwtf/nginx-ingress-controller:v0.44.0-r1
21 #
22 # TODO(q3k): unfork this once openssl 1.1.1k lands in upstream
23 # nginx-ingress-controller.
24 image: "eu.gcr.io/bgpwtf/nginx-ingress-controller:v0.44.0-r1",
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020025 namespace: "nginx-system",
26 },
27
28 metadata:: {
29 namespace: cfg.namespace,
30 labels: {
31 "app.kubernetes.io/name": "ingress-nginx",
32 "app.kubernetes.io/part-of": "ingress-nginx",
33 },
34 },
35
36 namespace: kube.Namespace(cfg.namespace),
37
Sergiusz Bazanskib13b7ff2019-08-29 20:12:24 +020038 allowInsecure: policies.AllowNamespaceInsecure(cfg.namespace),
39
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020040 maps: {
41 make(name):: kube.ConfigMap(name) {
42 metadata+: env.metadata,
43 },
Serge Bazanskie17f7ed2021-05-22 19:10:30 +000044 configuration: env.maps.make("nginx-configuration") {
45 data: {
46 "proxy-set-headers": "%s/nginx-custom-headers" % [cfg.namespace],
47 },
48 },
49 customHeaders: env.maps.make("nginx-custom-headers") {
50 data: {
51 # RFC6648 deprecates X-prefixed headers as a convention in
52 # multiple application protocols, including HTTP. It
53 # recommends that any new headers should just start off
54 # with a final standardized name, ie. suggests to use
55 # Toaster-ID instead of X-Toaster-ID.
56 #
57 # However, it also acknowledges that headers likely to
58 # never be standardized can still be prefixed with OrgName-
59 # or other constructs. And since we're not even attempting
60 # to standardize anything here, this is what we use to
61 # prefix hscloud-specific headers.
62 #
63 # Hscloud == hscloud, this repository.
64 # Nic == nginx-ingress-controller, this ingress controller.
65
66 # Set source port/addr. Source-IP duplicates
67 # X-Forwarded-For, but is added for consistency with
68 # Source-Port.
69 #
70 # Source-IP is an IP address in two possible formats:
71 # IPv4: "1.2.3.4"
72 # IPv6: "2a0d:1234::42"
73 # Any other format received by services should be
74 # considered invalid, and the service should assume a
75 # misconfiguration of the N-I-C.
76 "Hscloud-Nic-Source-IP": "${remote_addr}",
77 # Source-Port is a stringified TCP port, encoding a port
78 # number from 1 to 65535. Any other value received by
79 # services should be considered invalid, and the service
80 # should assume a misconfiguration of the N-I-C.
81 "Hscloud-Nic-Source-Port": "${remote_port}",
82 },
83 },
Sergiusz Bazanski543b4122019-06-29 22:42:39 +020084 tcp: env.maps.make("tcp-services") {
85 data: {
Piotr Dobrowolskif00edf62020-07-02 18:30:38 +020086 "22": "gerrit/gerrit:22",
Sergiusz Bazanski543b4122019-06-29 22:42:39 +020087 }
88 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020089 udp: env.maps.make("udp-services"),
90 },
91
92 sa: kube.ServiceAccount("nginx-ingress-serviceaccount") {
93 metadata+: env.metadata,
94 },
95
96 cr: kube.ClusterRole("nginx-ingress-clusterrole") {
97 metadata+: env.metadata {
98 namespace:: null,
99 },
100 rules: [
101 {
102 apiGroups: [""],
103 resources: ["configmaps", "endpoints", "nodes", "pods", "secrets"],
104 verbs: ["list", "watch"],
105 },
106 {
107 apiGroups: [""],
108 resources: ["nodes"],
109 verbs: ["get"],
110 },
111 {
112 apiGroups: [""],
113 resources: ["services"],
114 verbs: ["get", "list", "watch"],
115 },
116 {
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100117 apiGroups: ["extensions", "networking.k8s.io"],
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200118 resources: ["ingresses"],
119 verbs: ["get", "list", "watch"],
120 },
121 {
122 apiGroups: [""],
123 resources: ["events"],
124 verbs: ["create", "patch"],
125 },
126 {
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100127 apiGroups: ["extensions", "networking.k8s.io"],
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200128 resources: ["ingresses/status"],
129 verbs: ["update"],
130 },
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100131 {
132 apiGroups: ["extensions", "networking.k8s.io"],
133 resources: ["ingressclasses"],
134 verbs: ["get", "list", "watch"],
135 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200136 ],
137 },
138
139 crb: kube.ClusterRoleBinding("nginx-ingress-clusterrole-nisa-binding") {
140 metadata+: env.metadata {
141 namespace:: null,
142 },
143 roleRef: {
144 apiGroup: "rbac.authorization.k8s.io",
145 kind: "ClusterRole",
146 name: env.cr.metadata.name,
147 },
148 subjects: [
149 {
150 kind: "ServiceAccount",
151 name: env.sa.metadata.name,
152 namespace: env.sa.metadata.namespace,
153 },
154 ],
155 },
156
157 role: kube.Role("nginx-ingress-role") {
158 metadata+: env.metadata,
159 rules : [
160 {
161 apiGroups: [""],
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100162 resources: ["namespaces"],
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200163 verbs: ["get"],
164 },
165 {
166 apiGroups: [""],
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100167 resources: ["configmaps", "pods", "secrets", "endpoints"],
168 verbs: ["get", "list", "watch"],
169 },
170 {
171 apiGroups: [""],
172 resources: ["services"],
173 verbs: ["get", "list", "watch"],
174 },
175 {
176 apiGroups: ["extensions", "networking.k8s.io"],
177 resources: ["ingresses"],
178 verbs: ["get", "list", "watch"],
179 },
180 {
181 apiGroups: ["extensions", "networking.k8s.io"],
182 resources: ["ingresses/status"],
183 verbs: ["update"],
184 },
185 {
186 apiGroups: ["extensions", "networking.k8s.io"],
187 resources: ["ingressclasses"],
188 verbs: ["get", "list", "watch"],
189 },
190 {
191 apiGroups: [""],
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200192 resources: ["configmaps"],
193 resourceNames: ["ingress-controller-leader-nginx"],
194 verbs: ["get", "update"],
195 },
196 {
197 apiGroups: [""],
198 resources: ["configmaps"],
199 verbs: ["create"],
200 },
201 {
202 apiGroups: [""],
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100203 resources: ["events"],
204 verbs: ["create", "patch"],
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200205 },
206 ],
207 },
208
209 roleb: kube.RoleBinding("nginx-ingress-role-nisa-binding") {
210 metadata+: env.metadata,
211 roleRef: {
212 apiGroup: "rbac.authorization.k8s.io",
213 kind: "Role",
214 name: env.role.metadata.name,
215 },
216 subjects: [
217 {
218 kind: "ServiceAccount",
219 name: env.sa.metadata.name,
220 namespace: env.sa.metadata.namespace,
221 },
222 ],
223 },
224
225 service: kube.Service("ingress-nginx") {
226 metadata+: env.metadata,
227 target_pod:: env.deployment.spec.template,
228 spec+: {
229 type: "LoadBalancer",
230 ports: [
Sergiusz Bazanski543b4122019-06-29 22:42:39 +0200231 { name: "ssh", port: 22, targetPort: 22, protocol: "TCP" },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200232 { name: "http", port: 80, targetPort: 80, protocol: "TCP" },
233 { name: "https", port: 443, targetPort: 443, protocol: "TCP" },
234 ],
235 },
236 },
237
Piotr Dobrowolskif00edf62020-07-02 18:30:38 +0200238 serviceGitea: kube.Service("ingress-nginx-gitea") {
239 metadata+: env.metadata,
240 target_pod:: env.deployment.spec.template,
241 spec+: {
242 type: "LoadBalancer",
243 loadBalancerIP: "185.236.240.60",
244 ports: [
245 { name: "ssh", port: 22, targetPort: 222, protocol: "TCP" },
246 { name: "http", port: 80, targetPort: 80, protocol: "TCP" },
247 { name: "https", port: 443, targetPort: 443, protocol: "TCP" },
248 ],
249 },
250 },
251
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200252 deployment: kube.Deployment("nginx-ingress-controller") {
253 metadata+: env.metadata,
254 spec+: {
Sergiusz Bazanskifd323a02019-11-17 19:49:04 +0100255 replicas: 5,
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200256 template+: {
257 spec+: {
258 serviceAccountName: env.sa.metadata.name,
259 containers_: {
260 controller: kube.Container("nginx-ingress-controller") {
261 image: cfg.image,
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100262 imagePullPolicy: "IfNotPresent",
263 lifecycle: {
264 preStop: {
265 exec: {
266 command: [ "/wait-shutdown" ],
267 },
268 },
269 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200270 args: [
271 "/nginx-ingress-controller",
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100272 "--election-id=ingress-controller-leader",
273 "--ingress-class=nginx",
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200274 "--configmap=%s/%s" % [cfg.namespace, env.maps.configuration.metadata.name],
275 "--tcp-services-configmap=%s/%s" % [cfg.namespace, env.maps.tcp.metadata.name],
276 "--udp-services-configmap=%s/%s" % [cfg.namespace, env.maps.udp.metadata.name],
277 "--publish-service=%s/%s" % [cfg.namespace, env.service.metadata.name],
278 "--annotations-prefix=nginx.ingress.kubernetes.io",
279 ],
280 env_: {
281 POD_NAME: kube.FieldRef("metadata.name"),
282 POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
283 },
284 ports_: {
285 http: { containerPort: 80 },
286 https: { containerPort: 443 },
287 },
288 livenessProbe: {
289 failureThreshold: 3,
290 httpGet: {
291 path: "/healthz",
292 port: 10254,
293 scheme: "HTTP",
294 },
295 initialDelaySeconds: 10,
296 periodSeconds: 10,
297 successThreshold: 1,
298 timeoutSeconds: 10,
299 },
300 readinessProbe: {
301 failureThreshold: 3,
302 httpGet: {
303 path: "/healthz",
304 port: 10254,
305 scheme: "HTTP",
306 },
307 periodSeconds: 10,
308 successThreshold: 1,
309 timeoutSeconds: 10,
310 },
311 securityContext: {
312 allowPrivilegeEscalation: true,
313 capabilities: {
314 drop: ["ALL"],
315 add: ["NET_BIND_SERVICE"],
316 },
Serge Bazanski2e8d24b2021-03-25 18:39:52 +0100317 runAsUser: 101,
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200318 },
Serge Bazanski059fdfe2020-09-12 21:44:53 +0000319 resources: {
320 limits: { cpu: "2", memory: "4G" },
321 requests: { cpu: "1", memory: "1G" },
322 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200323 },
324 },
325 },
326 },
327 },
328 },
329 },
330}