blob: 13e3f5630adf65f0545e2d208ec9ffc62f9bc12f [file] [log] [blame]
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02001# Deploy Rook/Ceph Operator
2
3local kube = import "../../../kube/kube.libsonnet";
4
5{
6 Environment: {
7 local env = self,
8 local cfg = env.cfg,
9 cfg:: {
10 image: "rook/ceph:master",
11 namespace: "rook-ceph-system",
12 },
13
14 metadata:: {
15 namespace: cfg.namespace,
16 labels: {
17 "operator": "rook",
18 "storage-backend": "ceph",
19 },
20 },
21
22 namespace: kube.Namespace(cfg.namespace),
23
24 crds: {
25 cephclusters: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephCluster") {
26 spec+: {
27 additionalPrinterColumns: [
28 { name: "DataDirHostPath", type: "string", description: "Directory used on the K8s nodes", JSONPath: ".spec.dataDirHostPath" },
29 { name: "MonCount", type: "string", description: "Number of MONs", JSONPath: ".spec.mon.count" },
30 { name: "Age", type: "date", JSONPath: ".metadata.creationTimestamp" },
31 { name: "State", type: "string", description: "Current State", JSONPath: ".status.state" },
32 ],
33 validation: {
34 # Converted from official operator YAML
35 "openAPIV3Schema": {
36 "properties": {
37 "spec": {
38 "properties": {
39 "cephVersion": {
40 "properties": {
41 "allowUnsupported": {
42 "type": "boolean"
43 },
44 "image": {
45 "type": "string"
46 },
47 "name": {
48 "pattern": "^(luminous|mimic|nautilus)$",
49 "type": "string"
50 }
51 }
52 },
53 "dashboard": {
54 "properties": {
55 "enabled": {
56 "type": "boolean"
57 },
58 "urlPrefix": {
59 "type": "string"
60 },
61 "port": {
62 "type": "integer"
63 }
64 }
65 },
66 "dataDirHostPath": {
67 "pattern": "^/(\\S+)",
68 "type": "string"
69 },
70 "mon": {
71 "properties": {
72 "allowMultiplePerNode": {
73 "type": "boolean"
74 },
75 "count": {
76 "maximum": 9,
77 "minimum": 1,
78 "type": "integer"
79 },
80 "preferredCount": {
81 "maximum": 9,
82 "minimum": 0,
83 "type": "integer"
84 }
85 },
86 "required": [
87 "count"
88 ]
89 },
90 "network": {
91 "properties": {
92 "hostNetwork": {
93 "type": "boolean"
94 }
95 }
96 },
97 "storage": {
98 "properties": {
99 "nodes": {
100 "items": {},
101 "type": "array"
102 },
103 "useAllDevices": {},
104 "useAllNodes": {
105 "type": "boolean"
106 }
107 }
108 }
109 },
110 "required": [
111 "mon"
112 ]
113 }
114 }
115 }
116 }
117 },
118 },
119 cephfilesystems: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephFilesystem") {
120 spec+: {
121 additionalPrinterColumns: [
122 { name: "MdsCount", type: "string", description: "Number of MDs", JSONPath: ".spec.metadataServer.activeCount" },
123 { name: "Age", type: "date", JSONPath: ".metadata.creationTimestamp" },
124 ],
125 },
126 },
127 cephnfses: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephNFS") {
128 spec+: {
129 names+: {
130 shortNames: ["nfs"],
131 },
132 },
133 },
134 cephobjectstores: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephObjectStore"),
135 cephobjectstoreusers: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephObjectStoreUser"),
136 cephblockpools: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephBlockPool"),
137 volumes: kube.CustomResourceDefinition("rook.io", "v1alpha2", "Volume") {
138 spec+: {
139 names+: {
140 shortNames: ["rv"],
141 },
142 },
143 },
144 },
145
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200146 sa: kube.ServiceAccount("rook-ceph-system") {
147 metadata+: env.metadata,
148 },
149
150 crs: {
151 clusterMgmt: kube.ClusterRole("rook-ceph-cluster-mgmt") {
152 metadata+: env.metadata {
153 namespace:: null,
154 },
155 rules: [
156 {
157 apiGroups: [""],
158 resources: ["secrets", "pods", "pods/log", "services", "configmaps"],
159 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
160 },
161 {
162 apiGroups: ["apps"],
163 resources: ["deployments", "daemonsets", "replicasets"],
164 verbs: ["get", "list", "watch", "create", "update", "delete"],
165 },
166 ],
167 },
168 global: kube.ClusterRole("rook-ceph-global") {
169 metadata+: env.metadata {
170 namespace:: null,
171 },
172 rules: [
173 {
174 apiGroups: [""],
175 resources: ["pods", "nodes", "nodes/proxy"],
176 verbs: ["get", "list", "watch"],
177 },
178 {
179 apiGroups: [""],
180 resources: ["events", "persistentvolumes", "persistentvolumeclaims", "endpoints"],
181 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
182 },
183 {
184 apiGroups: ["storage.k8s.io"],
185 resources: ["storageclasses"],
186 verbs: ["get", "list", "watch", "create", "update", "delete"],
187 },
188 {
189 apiGroups: ["ceph.rook.io"],
190 resources: ["*"],
191 verbs: ["*"],
192 },
193 {
194 apiGroups: ["rook.io"],
195 resources: ["*"],
196 verbs: ["*"],
197 },
198 ],
199 },
200 mgrCluster: kube.ClusterRole("rook-ceph-mgr-cluster") {
201 metadata+: env.metadata {
202 namespace:: null,
203 },
204 rules: [
205 {
206 apiGroups: [""],
207 resources: ["configmaps", "nodes", "nodes/proxy"],
208 verbs: ["get", "list", "watch"],
209 },
210 ]
211 },
212 },
213
214 crb: kube.ClusterRoleBinding("ceph-rook-global") {
215 metadata+: env.metadata,
216 roleRef: {
217 apiGroup: "rbac.authorization.k8s.io",
218 kind: "ClusterRole",
219 name: env.crs.global.metadata.name,
220 },
221 subjects: [
222 {
223 kind: "ServiceAccount",
224 name: env.sa.metadata.name,
225 namespace: env.sa.metadata.namespace,
226 },
227 ],
228 },
229
230 role: kube.Role("ceph-rook-system") {
231 metadata+: env.metadata,
232 rules: [
233 {
234 apiGroups: [""],
235 resources: ["pods", "configmaps"],
236 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
237 },
238 {
239 apiGroups: ["apps"],
240 resources: ["daemonsets"],
241 verbs: ["get", "list", "watch", "create", "update", "delete"],
242 },
243 ],
244 },
245
246 rb: kube.RoleBinding("ceph-rook-system") {
247 metadata+: env.metadata,
248 roleRef: {
249 apiGroup: "rbac.authorization.k8s.io",
250 kind: "Role",
251 name: env.role.metadata.name,
252 },
253 subjects: [
254 {
255 kind: "ServiceAccount",
256 name: env.sa.metadata.name,
257 namespace: env.sa.metadata.namespace,
258 },
259 ],
260 },
261
262 operator: kube.Deployment("rook-ceph-operator") {
263 metadata+: env.metadata,
264 spec+: {
265 template+: {
266 spec+: {
267 serviceAccountName: env.sa.metadata.name,
268 containers_: {
269 operator: kube.Container("rook-ceph-operator") {
270 image: cfg.image,
271 args: ["ceph", "operator"],
272 volumeMounts_: {
273 "rook-config": { mountPath: "/var/lib/rook" },
274 "default-config-dir": { mountPath: "/etc/ceph" },
275 },
276 env_: {
277 LIB_MODULES_DIR_PATH: "/run/current-system/kernel-modules/lib/modules/",
278 ROOK_ALLOW_MULTIPLE_FILESYSTEMS: "false",
279 ROOK_LOG_LEVEL: "info",
280 ROOK_MON_HEALTHCHECK_INTERVAL: "45s",
281 ROOK_MON_OUT_TIMEOUT: "600s",
282 ROOK_DISCOVER_DEVICES_INTERVAL: "60m",
283 ROOK_HOSTPATH_REQUIRES_PRIVILEGED: "false",
284 ROOK_ENABLE_SELINUX_RELABELING: "true",
285 ROOK_ENABLE_FSGROUP: "true",
286 NODE_NAME: kube.FieldRef("spec.nodeName"),
287 POD_NAME: kube.FieldRef("metadata.name"),
288 POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
289 },
290 },
291 },
292 volumes_: {
293 "rook-config": { emptyDir: {} },
294 "default-config-dir": { emptyDir: {} },
295 },
296 },
297 },
298 },
299 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200300 },
301}