blob: 52ff93cfb744a712bd1a34f04a8faafd1392cc81 [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";
4
5{
6 Environment: {
7 local env = self,
8 local cfg = env.cfg,
9 cfg:: {
10 image: "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0",
11 namespace: "nginx-system",
12 },
13
14 metadata:: {
15 namespace: cfg.namespace,
16 labels: {
17 "app.kubernetes.io/name": "ingress-nginx",
18 "app.kubernetes.io/part-of": "ingress-nginx",
19 },
20 },
21
22 namespace: kube.Namespace(cfg.namespace),
23
24 maps: {
25 make(name):: kube.ConfigMap(name) {
26 metadata+: env.metadata,
27 },
28 configuration: env.maps.make("nginx-configuration"),
Sergiusz Bazanski543b4122019-06-29 22:42:39 +020029 tcp: env.maps.make("tcp-services") {
30 data: {
31 "22": "gerrit/gerrit:22"
32 }
33 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020034 udp: env.maps.make("udp-services"),
35 },
36
37 sa: kube.ServiceAccount("nginx-ingress-serviceaccount") {
38 metadata+: env.metadata,
39 },
40
41 cr: kube.ClusterRole("nginx-ingress-clusterrole") {
42 metadata+: env.metadata {
43 namespace:: null,
44 },
45 rules: [
46 {
47 apiGroups: [""],
48 resources: ["configmaps", "endpoints", "nodes", "pods", "secrets"],
49 verbs: ["list", "watch"],
50 },
51 {
52 apiGroups: [""],
53 resources: ["nodes"],
54 verbs: ["get"],
55 },
56 {
57 apiGroups: [""],
58 resources: ["services"],
59 verbs: ["get", "list", "watch"],
60 },
61 {
62 apiGroups: ["extensions"],
63 resources: ["ingresses"],
64 verbs: ["get", "list", "watch"],
65 },
66 {
67 apiGroups: [""],
68 resources: ["events"],
69 verbs: ["create", "patch"],
70 },
71 {
72 apiGroups: ["extensions"],
73 resources: ["ingresses/status"],
74 verbs: ["update"],
75 },
76 ],
77 },
78
79 crb: kube.ClusterRoleBinding("nginx-ingress-clusterrole-nisa-binding") {
80 metadata+: env.metadata {
81 namespace:: null,
82 },
83 roleRef: {
84 apiGroup: "rbac.authorization.k8s.io",
85 kind: "ClusterRole",
86 name: env.cr.metadata.name,
87 },
88 subjects: [
89 {
90 kind: "ServiceAccount",
91 name: env.sa.metadata.name,
92 namespace: env.sa.metadata.namespace,
93 },
94 ],
95 },
96
97 role: kube.Role("nginx-ingress-role") {
98 metadata+: env.metadata,
99 rules : [
100 {
101 apiGroups: [""],
102 resources: ["configmaps", "pods", "secrets", "namespaces"],
103 verbs: ["get"],
104 },
105 {
106 apiGroups: [""],
107 resources: ["configmaps"],
108 resourceNames: ["ingress-controller-leader-nginx"],
109 verbs: ["get", "update"],
110 },
111 {
112 apiGroups: [""],
113 resources: ["configmaps"],
114 verbs: ["create"],
115 },
116 {
117 apiGroups: [""],
118 resources: ["endpoints"],
119 verbs: ["get"],
120 },
121 ],
122 },
123
124 roleb: kube.RoleBinding("nginx-ingress-role-nisa-binding") {
125 metadata+: env.metadata,
126 roleRef: {
127 apiGroup: "rbac.authorization.k8s.io",
128 kind: "Role",
129 name: env.role.metadata.name,
130 },
131 subjects: [
132 {
133 kind: "ServiceAccount",
134 name: env.sa.metadata.name,
135 namespace: env.sa.metadata.namespace,
136 },
137 ],
138 },
139
140 service: kube.Service("ingress-nginx") {
141 metadata+: env.metadata,
142 target_pod:: env.deployment.spec.template,
143 spec+: {
144 type: "LoadBalancer",
Sergiusz Bazanski09a0f062019-06-29 22:38:12 +0200145 // The nginx ingress instrance is single-instance and metallb l2 (which we run)
146 // does SNAT on 'Cluster', thereby losing the source IP address.
147 // See: https://metallb.universe.tf/usage/#cluster-traffic-policy
148 externalTrafficPolicy: "Local",
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200149 ports: [
Sergiusz Bazanski543b4122019-06-29 22:42:39 +0200150 { name: "ssh", port: 22, targetPort: 22, protocol: "TCP" },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200151 { name: "http", port: 80, targetPort: 80, protocol: "TCP" },
152 { name: "https", port: 443, targetPort: 443, protocol: "TCP" },
153 ],
154 },
155 },
156
157 deployment: kube.Deployment("nginx-ingress-controller") {
158 metadata+: env.metadata,
159 spec+: {
160 replicas: 1,
161 template+: {
162 spec+: {
163 serviceAccountName: env.sa.metadata.name,
164 containers_: {
165 controller: kube.Container("nginx-ingress-controller") {
166 image: cfg.image,
167 args: [
168 "/nginx-ingress-controller",
169 "--configmap=%s/%s" % [cfg.namespace, env.maps.configuration.metadata.name],
170 "--tcp-services-configmap=%s/%s" % [cfg.namespace, env.maps.tcp.metadata.name],
171 "--udp-services-configmap=%s/%s" % [cfg.namespace, env.maps.udp.metadata.name],
172 "--publish-service=%s/%s" % [cfg.namespace, env.service.metadata.name],
173 "--annotations-prefix=nginx.ingress.kubernetes.io",
174 ],
175 env_: {
176 POD_NAME: kube.FieldRef("metadata.name"),
177 POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
178 },
179 ports_: {
180 http: { containerPort: 80 },
181 https: { containerPort: 443 },
182 },
183 livenessProbe: {
184 failureThreshold: 3,
185 httpGet: {
186 path: "/healthz",
187 port: 10254,
188 scheme: "HTTP",
189 },
190 initialDelaySeconds: 10,
191 periodSeconds: 10,
192 successThreshold: 1,
193 timeoutSeconds: 10,
194 },
195 readinessProbe: {
196 failureThreshold: 3,
197 httpGet: {
198 path: "/healthz",
199 port: 10254,
200 scheme: "HTTP",
201 },
202 periodSeconds: 10,
203 successThreshold: 1,
204 timeoutSeconds: 10,
205 },
206 securityContext: {
207 allowPrivilegeEscalation: true,
208 capabilities: {
209 drop: ["ALL"],
210 add: ["NET_BIND_SERVICE"],
211 },
212 runAsUser: 33,
213 },
214 },
215 },
216 },
217 },
218 },
219 },
220 },
221}