python/examples/rollout-statefulset.py
Kian-Meng Ang 2d299b7a57 Fix typos
Found via `codespell -S CHANGELOG.md,*.json,*.unprocessed -L querys,couldn`
2023-01-27 11:10:29 +08:00

143 lines
4.7 KiB
Python

"""
This example covers the following:
- Create headless server
- Create statefulset
- Update statefulset
- List controller revisions which belong to specified statefulset
- Roll out statefulset
Note:
If your kubernetes version is lower than 1.22(exclude 1.22), the kubernetes-client version must be lower than 1.22(also exclude 1.22).
Because new feature 'AvailableReplicas' for StatefulSetStatus is supported in native kubernetes since version 1.22, mismatch version between kubernetes and kubernetes-client will raise exception ValueError
"""
from kubernetes import client, config
def create_service(core_v1_api):
body = client.V1Service(
api_version="v1",
kind="Service",
metadata=client.V1ObjectMeta(
name="redis-test-svc"
),
spec=client.V1ServiceSpec(
selector={"app": "redis"},
cluster_ip="None",
type="ClusterIP",
ports=[client.V1ServicePort(
port=6379,
target_port=6379
)]
)
)
# Create the service in specified namespace
# (Can replace "default" with a namespace you may have created)
core_v1_api.create_namespaced_service(namespace="default", body=body)
def create_stateful_set_object():
container = client.V1Container(
name="sts-redis",
image="redis",
image_pull_policy="IfNotPresent",
ports=[client.V1ContainerPort(container_port=6379)],
)
# Template
template = client.V1PodTemplateSpec(
metadata=client.V1ObjectMeta(labels={"app": "redis"}),
spec=client.V1PodSpec(containers=[container]))
# Spec
spec = client.V1StatefulSetSpec(
replicas=1,
service_name="redis-test-svc",
selector=client.V1LabelSelector(
match_labels={"app": "redis"}
),
template=template)
# StatefulSet
statefulset = client.V1StatefulSet(
api_version="apps/v1",
kind="StatefulSet",
metadata=client.V1ObjectMeta(name="statefulset-redis"),
spec=spec)
return statefulset
def create_stateful_set(apps_v1_api, stateful_set_object):
# Create the Statefulset in default namespace
# You can replace the namespace with you have created
apps_v1_api.create_namespaced_stateful_set(
namespace="default", body=stateful_set_object
)
def update_stateful_set(apps_v1_api, statefulset):
# Update container image
statefulset.spec.template.spec.containers[0].image = "redis:6.2"
statefulset_name = statefulset.metadata.name
# Patch the statefulset
apps_v1_api.patch_namespaced_stateful_set(
name=statefulset_name, namespace="default", body=statefulset
)
def list_controller_revision(apps_v1_api, namespace, stateful_set_name):
# Get all controller revisions in specified namespace
controller_revision_list = apps_v1_api.list_namespaced_controller_revision(
namespace)
# Get all controller revisions which belong to specified statefulset.
controller_revision_belong_to_sts = []
for controller_revision in controller_revision_list.items:
owner_kind = controller_revision.metadata.owner_references[0].kind
owner_name = controller_revision.metadata.owner_references[0].name
if owner_kind == "StatefulSet" and owner_name == stateful_set_name:
controller_revision_belong_to_sts.append(
(controller_revision.metadata.name, controller_revision.revision))
return sorted(controller_revision_belong_to_sts, key=lambda x: x[1])
def rollout_namespaced_stateful_set(
apps_v1_api,
name,
namespace,
controller_revision_name):
# Get the specified controller revision object
_controller_revision = apps_v1_api.read_namespaced_controller_revision(
controller_revision_name, namespace)
# Roll out statefulset to the specified revision
apps_v1_api.patch_namespaced_stateful_set(
name, namespace, body=_controller_revision.data)
def main():
# Loading the local kubeconfig
config.load_kube_config()
apps_v1_api = client.AppsV1Api()
core_v1_api = client.CoreV1Api()
stateful_set_obj = create_stateful_set_object()
create_service(core_v1_api)
create_stateful_set(apps_v1_api, stateful_set_obj)
update_stateful_set(apps_v1_api, stateful_set_obj)
# Wait for finishing creation of controller revision
import time
time.sleep(15)
# List the controller revision
controller_revisions = list_controller_revision(
apps_v1_api, "default", "statefulset-redis")
rollout_namespaced_stateful_set(
apps_v1_api,
"statefulset-redis",
"default",
controller_revisions[0][0])
if __name__ == "__main__":
main()