blob: a56fc9085b1c979a4849f16ea0b819ffbdf3d7e3 [file] [log] [blame]
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +01001# Deploy MetalLB
2
3local kube = import "../../../kube/kube.libsonnet";
4
5local bindServiceAccountClusterRole(sa, cr) = kube.ClusterRoleBinding(cr.metadata.name) {
6 roleRef: {
7 apiGroup: "rbac.authorization.k8s.io",
8 kind: "ClusterRole",
9 name: cr.metadata.name,
10 },
11 subjects: [
12 {
13 kind: "ServiceAccount",
14 name: sa.metadata.name,
15 namespace: sa.metadata.namespace,
16 },
17 ],
18};
19
20{
21 Environment: {
22 local env = self,
23 local cfg = env.cfg,
24 cfg:: {
25 namespace: "metallb-system",
26 namespaceCreate: true,
Piotr Dobrowolskib187bf52019-05-05 12:11:14 +020027 version:: "v0.7.3",
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +020028 imageController: "metallb/controller:" + cfg.version,
29 imageSpeaker: "metallb/speaker:" + cfg.version,
Sergiusz Bazanski14cbacb2019-04-01 18:00:44 +020030 addressPools: error "addressPools must be set in config",
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +010031 },
32
33 ns: if cfg.namespaceCreate then kube.Namespace(cfg.namespace),
34
35 saController: kube.ServiceAccount("controller") {
36 metadata+: {
37 namespace: cfg.namespace,
38 },
39 },
40
41 saSpeaker: kube.ServiceAccount("speaker") {
42 metadata+: {
43 namespace: cfg.namespace,
44 },
45 },
46
47 crController: kube.ClusterRole("%s:controller" % cfg.namespace) {
48 rules: [
49 {
50 apiGroups: [""],
51 resources: ["services"],
52 verbs: ["get", "list", "watch", "update"],
53 },
54 {
55 apiGroups: [""],
56 resources: ["services/status"],
57 verbs: ["update"],
58 },
59 {
60 apiGroups: [""],
61 resources: ["events"],
62 verbs: ["create", "patch"],
63 },
64 ],
65 },
66
67 crbController: bindServiceAccountClusterRole(env.saController, env.crController),
68
69 crSpeaker: kube.ClusterRole("%s:speaker" % cfg.namespace) {
70 rules: [
71 {
72 apiGroups: [""],
73 resources: ["services", "endpoints", "nodes"],
74 verbs: ["get", "list", "watch"],
75 },
76 ],
77 },
78
79 crbSpeaker: bindServiceAccountClusterRole(env.saSpeaker, env.crSpeaker),
80
81 roleWatcher: kube.Role("config-watcher") {
82 metadata+: {
83 namespace: cfg.namespace,
84 },
85 rules: [
86 {
87 apiGroups: [""],
88 resources: ["configmaps"],
89 verbs: ["get", "list", "watch"],
90 },
91 {
92 apiGroups: [""],
93 resources: ["events"],
94 verbs: ["create"],
95 },
96 ],
97 },
98
99 rbWatcher: kube.RoleBinding("config-watcher") {
100 metadata+: {
101 namespace: cfg.namespace,
102 },
103 subjects: [
104 { kind: "ServiceAccount", name: env.saController.metadata.name },
105 { kind: "ServiceAccount", name: env.saSpeaker.metadata.name },
106 ],
107 roleRef: {
108 apiGroup: "rbac.authorization.k8s.io",
109 kind: "Role",
110 name: env.roleWatcher.metadata.name,
111 },
112 },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200113
114 deployController: kube.Deployment("controller") {
115 metadata+: {
116 namespace: cfg.namespace,
117 },
118 spec+: {
119 revisionHistoryLimit: 3,
120 template+: {
121 spec+: {
122 serviceAccountName: env.saController.metadata.name,
123 terminationGracePeriodSeconds: 0,
124 securityContext: {
125 runAsNonRoot: true,
126 runAsUser: 65534, # nobody
127 },
128 containers_: {
129 controller: kube.Container("controller") {
130 image: cfg.imageController,
131 args: [ "--port=7472", "--config=config" ],
132 ports: [
133 { name: "monitoring", containerPort: 7472 },
134 ],
135 resources: {
Sergiusz Bazanski242152f2019-04-04 16:53:27 +0200136 limits: { cpu: "200m", memory: "300Mi" },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200137 },
138 securityContext: {
139 allowPrivilegeEscalation: false,
140 capabilities: { drop: [ "all" ] },
141 readOnlyRootFilesystem: true,
142 },
143 },
144 },
145 },
146 },
147 },
148 },
149
150 daemonsetSpeaker: kube.DaemonSet("speaker") {
151 metadata+: {
152 namespace: cfg.namespace,
153 },
154 spec+: {
155 template+: {
156 spec+: {
157 serviceAccountName: env.saSpeaker.metadata.name,
158 hostNetwork: true,
159 containers_: {
160 speaker: kube.Container("speaker") {
161 image: cfg.imageSpeaker,
162 args: [ "--port=7472", "--config=config" ],
163 env_: {
164 METALLB_NODE_NAME: kube.FieldRef("spec.nodeName"),
165 },
166 ports: [
167 { name: "monitoring", containerPort: 7472 },
168 ],
169 resources: {
Sergiusz Bazanski242152f2019-04-04 16:53:27 +0200170 limits: { cpu: "200m", memory: "300Mi" },
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200171 },
172 securityContext: {
173 allowPrivilegeEscalation: false,
174 capabilities: { drop: [ "all" ], add: [ "net_raw" ] },
175 readOnlyRootFilesystem: true,
176 },
177 },
178 },
179 },
180 },
181 },
182 },
183
184 configMap: kube.ConfigMap("config") {
185 local cm = self,
186 metadata+: {
187 namespace: cfg.namespace,
188 },
189 data: {
190 config: std.manifestYamlDoc({
Sergiusz Bazanski14cbacb2019-04-01 18:00:44 +0200191 "address-pools": cfg.addressPools,
Sergiusz Bazanskia9c7e862019-04-01 17:56:28 +0200192 }),
193 },
194 },
Sergiusz Bazanski1e565dc2019-01-18 09:40:59 +0100195 },
196}