mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-03-26 21:33:02 +00:00
add ability to filter the list of pods to be drained by a pod label selector (#606)
* add ability to filter the list of pods to be drained by a label selector
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- k8s_drain - add ability to filter the list of pods to be drained by a pod label selector (https://github.com/ansible-collections/kubernetes.core/issues/474).
|
||||
@@ -41,6 +41,15 @@ options:
|
||||
- The name of the node.
|
||||
required: true
|
||||
type: str
|
||||
pod_selectors:
|
||||
description:
|
||||
- Label selector to filter pods on the node.
|
||||
- This option has effect only when C(state) is set to I(drain).
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
aliases:
|
||||
- label_selectors
|
||||
delete_options:
|
||||
type: dict
|
||||
default: {}
|
||||
@@ -116,6 +125,14 @@ EXAMPLES = r"""
|
||||
state: cordon
|
||||
name: foo
|
||||
|
||||
- name: Drain node "foo" using label selector to filter the list of pods to be drained.
|
||||
kubernetes.core.k8s_drain:
|
||||
state: drain
|
||||
name: foo
|
||||
pod_selectors:
|
||||
- 'app!=csi-attacher'
|
||||
- 'app!=csi-provisioner'
|
||||
|
||||
"""
|
||||
|
||||
RETURN = r"""
|
||||
@@ -329,6 +346,17 @@ class K8sDrainAnsible(object):
|
||||
)
|
||||
)
|
||||
|
||||
def list_pods(self):
|
||||
params = {
|
||||
"field_selector": "spec.nodeName={name}".format(
|
||||
name=self._module.params.get("name")
|
||||
)
|
||||
}
|
||||
pod_selectors = self._module.params.get("pod_selectors")
|
||||
if pod_selectors:
|
||||
params["label_selector"] = ",".join(pod_selectors)
|
||||
return self._api_instance.list_pod_for_all_namespaces(**params)
|
||||
|
||||
def delete_or_evict_pods(self, node_unschedulable):
|
||||
# Mark node as unschedulable
|
||||
result = []
|
||||
@@ -351,12 +379,7 @@ class K8sDrainAnsible(object):
|
||||
self.patch_node(unschedulable=False)
|
||||
|
||||
try:
|
||||
field_selector = "spec.nodeName={name}".format(
|
||||
name=self._module.params.get("name")
|
||||
)
|
||||
pod_list = self._api_instance.list_pod_for_all_namespaces(
|
||||
field_selector=field_selector
|
||||
)
|
||||
pod_list = self.list_pods()
|
||||
# Filter pods
|
||||
force = self._drain_options.get("force", False)
|
||||
ignore_daemonset = self._drain_options.get("ignore_daemonsets", False)
|
||||
@@ -487,6 +510,11 @@ def argspec():
|
||||
wait_sleep=dict(type="int", default=5),
|
||||
),
|
||||
),
|
||||
pod_selectors=dict(
|
||||
type="list",
|
||||
elements="str",
|
||||
aliases=["label_selectors"],
|
||||
),
|
||||
)
|
||||
)
|
||||
return argument_spec
|
||||
|
||||
@@ -281,6 +281,7 @@
|
||||
that:
|
||||
- dset_result.resources | list | length > 0
|
||||
|
||||
# test: drain using disable_eviction=true
|
||||
- name: Uncordon node
|
||||
k8s_drain:
|
||||
state: uncordon
|
||||
@@ -347,6 +348,90 @@
|
||||
register: _result
|
||||
failed_when: _result.resources
|
||||
|
||||
# test: drain using pod_selectors
|
||||
- name: Uncordon node
|
||||
k8s_drain:
|
||||
state: uncordon
|
||||
name: '{{ node_to_drain }}'
|
||||
|
||||
- name: create a Pod for test
|
||||
k8s:
|
||||
namespace: '{{ test_namespace }}'
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: 'ansible-drain-pod'
|
||||
labels:
|
||||
app: ansible-drain
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
nodeSelectorTerms:
|
||||
- matchFields:
|
||||
- key: metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- '{{ node_to_drain }}'
|
||||
containers:
|
||||
- name: ansible-container
|
||||
image: busybox
|
||||
command:
|
||||
- '/bin/sh'
|
||||
- '-c'
|
||||
- 'while true; do echo $(date); sleep 10; done'
|
||||
|
||||
- name: Drain node using pod_selectors 'app!=ansible-drain'
|
||||
k8s_drain:
|
||||
state: drain
|
||||
name: '{{ node_to_drain }}'
|
||||
pod_selectors:
|
||||
- app!=ansible-drain
|
||||
delete_options:
|
||||
terminate_grace_period: 0
|
||||
delete_emptydir_data: true
|
||||
force: true
|
||||
ignore_daemonsets: true
|
||||
register: drain_pod_selector
|
||||
|
||||
- name: assert that node has been drained
|
||||
assert:
|
||||
that:
|
||||
- drain_pod_selector is changed
|
||||
- '"node {{ node_to_drain }} marked unschedulable." in drain_pod_selector.result'
|
||||
|
||||
- name: assert that pod created before is still running
|
||||
k8s_info:
|
||||
namespace: '{{ test_namespace }}'
|
||||
kind: Pod
|
||||
label_selectors:
|
||||
- app=ansible-drain
|
||||
field_selectors:
|
||||
- status.phase=Running
|
||||
register: pods
|
||||
failed_when: pods.resources == []
|
||||
|
||||
- name: Drain node using pod_selectors 'app=ansible-drain'
|
||||
k8s_drain:
|
||||
state: drain
|
||||
name: '{{ node_to_drain }}'
|
||||
pod_selectors:
|
||||
- app=ansible-drain
|
||||
delete_options:
|
||||
terminate_grace_period: 0
|
||||
force: true
|
||||
register: drain_pod_selector_equal
|
||||
|
||||
- name: assert that node was not drained
|
||||
assert:
|
||||
that:
|
||||
- drain_pod_selector_equal is changed
|
||||
- '"node {{ node_to_drain }} already marked unschedulable." in drain_pod_selector_equal.result'
|
||||
- '"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {{ test_namespace }}/ansible-drain-pod." in drain_pod_selector_equal.warnings'
|
||||
|
||||
- name: Uncordon node
|
||||
k8s_drain:
|
||||
state: uncordon
|
||||
|
||||
Reference in New Issue
Block a user