Browse Source

Bring back StatefulSet support

It's based on previous wotk on PetSets, but is adapted for
Kubernetes 1.5.

Change-Id: Ia1a18503514c2bfd6d90e6e265df33ede61e74d2
Yuriy Taraday 2 years ago
parent
commit
968a65fbf2

+ 1
- 1
doc/source/dsl.rst View File

@@ -101,7 +101,7 @@ service
101 101
    * - kind
102 102
      - Kind of k8s object to use for containers deployment.
103 103
      - false
104
-     - one of: ["Deployment", "DaemonSet"]
104
+     - one of: ["Deployment", "DaemonSet", "StatefulSet"]
105 105
      - Deployment
106 106
    * - containers
107 107
      - List of containers under multi-container pod.

+ 4
- 2
fuel_ccp/common/utils.py View File

@@ -1,3 +1,4 @@
1
+import itertools
1 2
 import logging
2 3
 import os
3 4
 import pkg_resources
@@ -158,7 +159,8 @@ def get_deploy_components_info(rendering_context=None):
158 159
 def get_deployed_components():
159 160
     """Returns set of deployed components."""
160 161
     deployed_deployments = kubernetes.list_cluster_deployments()
161
-    deployed_components = set(
162
-        kubernetes.get_object_names(deployed_deployments)
162
+    deployed_statefulsets = kubernetes.list_cluster_statefulsets()
163
+    deployed_components = set(kubernetes.get_object_names(
164
+        itertools.chain(deployed_deployments, deployed_statefulsets))
163 165
     )
164 166
     return deployed_components

+ 10
- 2
fuel_ccp/deploy.py View File

@@ -134,8 +134,15 @@ def parse_role(component, topology, configmaps, jinja_imports):
134 134
             'Affinity is in conflict with annotations with key: %s'
135 135
             .format(same_keywords))
136 136
     annotations.update(affinity)
137
-    obj = templates.serialize_deployment(service_name, cont_spec, annotations,
138
-                                         replicas, component_name, strategy)
137
+
138
+    if service.get("kind") != "StatefulSet":
139
+        obj = templates.serialize_deployment(service_name, cont_spec,
140
+                                             annotations, replicas,
141
+                                             component_name, strategy)
142
+    else:
143
+        obj = templates.serialize_statefulset(service_name, cont_spec,
144
+                                              annotations, replicas,
145
+                                              component_name)
139 146
     yield [obj]
140 147
 
141 148
     yield _process_ports(service)
@@ -203,6 +210,7 @@ def _process_ports(service):
203 210
                     service["name"], ingress_host, source_port))
204 211
     service_template = templates.serialize_service(
205 212
         service["name"], ports,
213
+        headless=service.get("kind") == "StatefulSet",
206 214
         annotations=service.get('annotations', {}).get('service'))
207 215
     yield service_template
208 216
 

+ 14
- 1
fuel_ccp/kubernetes.py View File

@@ -10,7 +10,13 @@ CONF = config.CONF
10 10
 
11 11
 LOG = logging.getLogger(__name__)
12 12
 
13
-UPDATABLE_OBJECTS = ('ConfigMap', 'Deployment', 'Service', 'Ingress')
13
+UPDATABLE_OBJECTS = (
14
+    'ConfigMap',
15
+    'Deployment',
16
+    'Service',
17
+    'Ingress',
18
+    'StatefulSet',
19
+)
14 20
 
15 21
 
16 22
 def get_client(kube_apiserver=None, key_file=None, cert_file=None,
@@ -177,6 +183,13 @@ def list_cluster_ingress():
177 183
         namespace=CONF.kubernetes.namespace)
178 184
 
179 185
 
186
+def list_cluster_statefulsets():
187
+    client = get_client()
188
+    return pykube.StatefulSet.objects(client).filter(
189
+        namespace=CONF.kubernetes.namespace,
190
+        selector="ccp=true")
191
+
192
+
180 193
 def get_object_names(items):
181 194
     names = []
182 195
     for item in items:

+ 25
- 0
fuel_ccp/templates.py View File

@@ -352,6 +352,31 @@ def serialize_deployment(name, spec, annotations, replicas, component_name,
352 352
     return deployment
353 353
 
354 354
 
355
+def serialize_statefulset(name, spec, annotations, replicas, component_name):
356
+    return {
357
+        "apiVersion": "apps/v1beta1",
358
+        "kind": "StatefulSet",
359
+        "metadata": {
360
+            "name": name
361
+        },
362
+        "spec": {
363
+            "serviceName": name,
364
+            "replicas": replicas,
365
+            "template": {
366
+                "metadata": {
367
+                    "annotations": annotations,
368
+                    "labels": {
369
+                        "ccp": "true",
370
+                        "app": name,
371
+                        "ccp-component": component_name
372
+                    }
373
+                },
374
+                "spec": spec
375
+            }
376
+        }
377
+    }
378
+
379
+
355 380
 def serialize_affinity(service, topology):
356 381
     policy = {
357 382
         "nodeAffinity": {

+ 8
- 1
fuel_ccp/validation/service.py View File

@@ -179,6 +179,13 @@ SERVICE_SCHEMA = {
179 179
             "additionalProperties": False,
180 180
             "required": ["name", "containers"],
181 181
 
182
+            "not": {  # strategy needs to be absent for StatefulSet's
183
+                "properties": {
184
+                    "kind": {"enum": ["StatefulSet"]},
185
+                },
186
+                "required": ["kind", "strategy"],
187
+            },
188
+
182 189
             "properties": {
183 190
                 "name": NOT_EMPTY_STRING_SCHEMA,
184 191
                 "ports": {
@@ -207,7 +214,7 @@ SERVICE_SCHEMA = {
207 214
                     }
208 215
                 },
209 216
                 "kind": {
210
-                    "enum": ["Deployment", "DaemonSet"]
217
+                    "enum": ["Deployment", "DaemonSet", "StatefulSet"]
211 218
                 },
212 219
                 "hostNetwork": {
213 220
                     "type": "boolean"

Loading…
Cancel
Save