Skip to content

Commit ee67a03

Browse files
authored
Merge pull request kubernetes-client#1717 from showjason/rollout-sts-ds
add examples which mainly show a way to rollout statefulset and daemo…
2 parents 6c90fe3 + 6fa47ea commit ee67a03

File tree

2 files changed

+254
-0
lines changed

2 files changed

+254
-0
lines changed

examples/rollout-daemonset.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""
2+
This example covers the following:
3+
- Create daemonset
4+
- Update daemonset
5+
- List contoller revisions which belong to specified daemonset
6+
- Roll out daemonset
7+
"""
8+
9+
10+
from kubernetes import client, config
11+
12+
13+
def create_daemon_set_object():
14+
container = client.V1Container(
15+
name="ds-redis",
16+
image="redis",
17+
image_pull_policy="IfNotPresent",
18+
ports=[client.V1ContainerPort(container_port=6379)],
19+
)
20+
# Template
21+
template = client.V1PodTemplateSpec(
22+
metadata=client.V1ObjectMeta(labels={"app": "redis"}),
23+
spec=client.V1PodSpec(containers=[container]))
24+
# Spec
25+
spec = client.V1DaemonSetSpec(
26+
selector=client.V1LabelSelector(
27+
match_labels={"app": "redis"}
28+
),
29+
template=template)
30+
# DaemonSet
31+
daemonset = client.V1DaemonSet(
32+
api_version="apps/v1",
33+
kind="DaemonSet",
34+
metadata=client.V1ObjectMeta(name="daemonset-redis"),
35+
spec=spec)
36+
37+
return daemonset
38+
39+
40+
def create_daemon_set(apps_v1_api, daemon_set_object):
41+
# Create the Daemonset in default namespace
42+
# You can replace the namespace with you have created
43+
apps_v1_api.create_namespaced_daemon_set(
44+
namespace="default", body=daemon_set_object
45+
)
46+
47+
48+
def update_daemon_set(apps_v1_api, daemonset):
49+
# Update container image
50+
daemonset.spec.template.spec.containers[0].image = "redis:6.2"
51+
daemonset_name = daemonset.metadata.name
52+
# Patch the daemonset
53+
apps_v1_api.patch_namespaced_daemon_set(
54+
name=daemonset_name, namespace="default", body=daemonset
55+
)
56+
57+
58+
def list_controller_revision(apps_v1_api, namespace, daemon_set_name):
59+
# Get all controller revisions in specified namespace
60+
controller_revision_list = apps_v1_api.list_namespaced_controller_revision(
61+
namespace)
62+
# Get all controller revisions which belong to specified daemonset.
63+
controller_revision_belong_to_ds = []
64+
for controller_revision in controller_revision_list.items:
65+
owner_kind = controller_revision.metadata.owner_references[0].kind
66+
owner_name = controller_revision.metadata.owner_references[0].name
67+
if owner_kind == "DaemonSet" and owner_name == daemon_set_name:
68+
controller_revision_belong_to_ds.append(
69+
(controller_revision.metadata.name, controller_revision.revision))
70+
return sorted(controller_revision_belong_to_ds, key=lambda x: x[1])
71+
72+
73+
def rollout_namespaced_daemon_set(
74+
apps_v1_api,
75+
name,
76+
namespace,
77+
controller_revision_name):
78+
79+
# Get the specified controller revision object
80+
_controller_revision = apps_v1_api.read_namespaced_controller_revision(
81+
controller_revision_name, namespace)
82+
# Roll out daemonset to the specified revision
83+
apps_v1_api.patch_namespaced_daemon_set(
84+
name, namespace, body=_controller_revision.data)
85+
86+
87+
def main():
88+
# Loading the local kubeconfig
89+
config.load_kube_config()
90+
apps_v1_api = client.AppsV1Api()
91+
core_v1_api = client.CoreV1Api()
92+
daemon_set_obj = create_daemon_set_object()
93+
94+
create_daemon_set(apps_v1_api, daemon_set_obj)
95+
96+
update_daemon_set(apps_v1_api, daemon_set_obj)
97+
98+
# Wait for finishing creation of controller revision
99+
import time
100+
time.sleep(15)
101+
# List the controller revison
102+
controller_revisions = list_controller_revision(
103+
apps_v1_api, "default", "daemonset-redis")
104+
rollout_namespaced_daemon_set(
105+
apps_v1_api,
106+
"daemonset-redis",
107+
"default",
108+
controller_revisions[0][0])
109+
110+
111+
if __name__ == "__main__":
112+
main()

examples/rollout-statefulset.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""
2+
This example covers the following:
3+
- Create headless server
4+
- Create statefulset
5+
- Update statefulset
6+
- List contoller revisions which belong to specified statefulset
7+
- Roll out statefulset
8+
Note:
9+
If your kubernetes version is lower than 1.22(exclude 1.22), the kubernetes-client version must be lower than 1.22(alse exclude 1.22).
10+
Because new feature 'AvailableReplicas' for StatefulSetStatus is supported in native kubernetes since version 1.22, mismatch version between kubernetes and kubernetes-client will raise execption ValueError
11+
"""
12+
13+
14+
from kubernetes import client, config
15+
16+
17+
def create_service(core_v1_api):
18+
body = client.V1Service(
19+
api_version="v1",
20+
kind="Service",
21+
metadata=client.V1ObjectMeta(
22+
name="redis-test-svc"
23+
),
24+
spec=client.V1ServiceSpec(
25+
selector={"app": "redis"},
26+
cluster_ip="None",
27+
type="ClusterIP",
28+
ports=[client.V1ServicePort(
29+
port=6379,
30+
target_port=6379
31+
)]
32+
)
33+
)
34+
# Create the service in specified namespace
35+
# (Can replace "default" with a namespace you may have created)
36+
core_v1_api.create_namespaced_service(namespace="default", body=body)
37+
38+
39+
def create_stateful_set_object():
40+
container = client.V1Container(
41+
name="sts-redis",
42+
image="redis",
43+
image_pull_policy="IfNotPresent",
44+
ports=[client.V1ContainerPort(container_port=6379)],
45+
)
46+
# Template
47+
template = client.V1PodTemplateSpec(
48+
metadata=client.V1ObjectMeta(labels={"app": "redis"}),
49+
spec=client.V1PodSpec(containers=[container]))
50+
# Spec
51+
spec = client.V1StatefulSetSpec(
52+
replicas=1,
53+
service_name="redis-test-svc",
54+
selector=client.V1LabelSelector(
55+
match_labels={"app": "redis"}
56+
),
57+
template=template)
58+
# StatefulSet
59+
statefulset = client.V1StatefulSet(
60+
api_version="apps/v1",
61+
kind="StatefulSet",
62+
metadata=client.V1ObjectMeta(name="statefulset-redis"),
63+
spec=spec)
64+
65+
return statefulset
66+
67+
68+
def create_stateful_set(apps_v1_api, stateful_set_object):
69+
# Create the Statefulset in default namespace
70+
# You can replace the namespace with you have created
71+
apps_v1_api.create_namespaced_stateful_set(
72+
namespace="default", body=stateful_set_object
73+
)
74+
75+
76+
def update_stateful_set(apps_v1_api, statefulset):
77+
# Update container image
78+
statefulset.spec.template.spec.containers[0].image = "redis:6.2"
79+
statefulset_name = statefulset.metadata.name
80+
# Patch the statefulset
81+
apps_v1_api.patch_namespaced_stateful_set(
82+
name=statefulset_name, namespace="default", body=statefulset
83+
)
84+
85+
86+
def list_controller_revision(apps_v1_api, namespace, stateful_set_name):
87+
# Get all controller revisions in specified namespace
88+
controller_revision_list = apps_v1_api.list_namespaced_controller_revision(
89+
namespace)
90+
# Get all controller revisions which belong to specified statefulset.
91+
controller_revision_belong_to_sts = []
92+
for controller_revision in controller_revision_list.items:
93+
owner_kind = controller_revision.metadata.owner_references[0].kind
94+
owner_name = controller_revision.metadata.owner_references[0].name
95+
if owner_kind == "StatefulSet" and owner_name == stateful_set_name:
96+
controller_revision_belong_to_sts.append(
97+
(controller_revision.metadata.name, controller_revision.revision))
98+
return sorted(controller_revision_belong_to_sts, key=lambda x: x[1])
99+
100+
101+
def rollout_namespaced_stateful_set(
102+
apps_v1_api,
103+
name,
104+
namespace,
105+
controller_revision_name):
106+
107+
# Get the specified controller revision object
108+
_controller_revision = apps_v1_api.read_namespaced_controller_revision(
109+
controller_revision_name, namespace)
110+
# Roll out statefulset to the specified revision
111+
apps_v1_api.patch_namespaced_stateful_set(
112+
name, namespace, body=_controller_revision.data)
113+
114+
115+
def main():
116+
# Loading the local kubeconfig
117+
config.load_kube_config()
118+
apps_v1_api = client.AppsV1Api()
119+
core_v1_api = client.CoreV1Api()
120+
stateful_set_obj = create_stateful_set_object()
121+
122+
create_service(core_v1_api)
123+
124+
create_stateful_set(apps_v1_api, stateful_set_obj)
125+
126+
update_stateful_set(apps_v1_api, stateful_set_obj)
127+
128+
# Wait for finishing creation of controller revision
129+
import time
130+
time.sleep(15)
131+
# List the controller revison
132+
controller_revisions = list_controller_revision(
133+
apps_v1_api, "default", "statefulset-redis")
134+
rollout_namespaced_stateful_set(
135+
apps_v1_api,
136+
"statefulset-redis",
137+
"default",
138+
controller_revisions[0][0])
139+
140+
141+
if __name__ == "__main__":
142+
main()

0 commit comments

Comments
 (0)