From 546880b4667f789ee1993b572f30e88cd1fae721 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 19 Aug 2022 22:42:47 +0200 Subject: kubernetes: add support for ansible managed node annotations,labels and taints --- common/kubernetes-cluster.yml | 5 ++- roles/kubernetes/decorations/tasks/annotations.yml | 44 ++++++++++++++++++++++ roles/kubernetes/decorations/tasks/labels.yml | 44 ++++++++++++++++++++++ roles/kubernetes/decorations/tasks/main.yml | 21 +++++++++++ roles/kubernetes/decorations/tasks/taints.yml | 44 ++++++++++++++++++++++ .../kubeadm/control-plane/tasks/primary.yml | 8 ++-- .../kubeadm/control-plane/tasks/secondary.yml | 5 ++- roles/kubernetes/kubeadm/reset/tasks/main.yml | 1 + roles/kubernetes/kubeadm/worker/tasks/main.yml | 1 + 9 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 roles/kubernetes/decorations/tasks/annotations.yml create mode 100644 roles/kubernetes/decorations/tasks/labels.yml create mode 100644 roles/kubernetes/decorations/tasks/main.yml create mode 100644 roles/kubernetes/decorations/tasks/taints.yml diff --git a/common/kubernetes-cluster.yml b/common/kubernetes-cluster.yml index 6958db15..d6860f60 100644 --- a/common/kubernetes-cluster.yml +++ b/common/kubernetes-cluster.yml @@ -55,4 +55,7 @@ roles: - role: kubernetes/kubeadm/worker -### TODO: add node labels (ie. for ingress daeomnset) +- name: finalize nodes + hosts: _kubernetes_nodes_ + roles: + - role: kubernetes/decorations diff --git a/roles/kubernetes/decorations/tasks/annotations.yml b/roles/kubernetes/decorations/tasks/annotations.yml new file mode 100644 index 00000000..9b47ecbf --- /dev/null +++ b/roles/kubernetes/decorations/tasks/annotations.yml @@ -0,0 +1,44 @@ +--- +- name: get list of current annotations + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + check_mode: no + command: kubectl --kubeconfig /etc/kubernetes/admin.conf get node '{{ kubernetes_node_name }}' -o jsonpath='{.metadata.annotations}' + changed_when: false + register: kubectl_list_annotations + +- set_fact: + current_annotations: "{{ kubectl_list_annotations.stdout | from_json }}" + +- name: add annotations to node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ kubernetes_node_annotations | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + when: "item.key not in current_annotations or current_annotations[item.key] != item.value" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf annotate --overwrite node '{{ kubernetes_node_name }}' '{{ item.key }}={{ item.value }}' + +- name: add stamp files for managed annotations + loop: "{{ kubernetes_node_annotations | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + copy: + dest: "/etc/kubernetes/decorations/annotations/{{ item.key }}" + content: "{{ item.value }}" + +- name: get list of managed labels + find: + path: /etc/kubernetes/decorations/annotations + register: managed_annotations + +- name: remove superflous annotations from node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ managed_annotations.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_annotations" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf annotate --overwrite node '{{ kubernetes_node_name }}' '{{ item }}-' + +- name: remove stamp files for superflous annotations + loop: "{{ managed_annotations.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_annotations" + file: + path: "/etc/kubernetes/decorations/annotations/{{ item }}" + state: absent diff --git a/roles/kubernetes/decorations/tasks/labels.yml b/roles/kubernetes/decorations/tasks/labels.yml new file mode 100644 index 00000000..1517616e --- /dev/null +++ b/roles/kubernetes/decorations/tasks/labels.yml @@ -0,0 +1,44 @@ +--- +- name: get list of current labels + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + check_mode: no + command: kubectl --kubeconfig /etc/kubernetes/admin.conf get node '{{ kubernetes_node_name }}' -o jsonpath='{.metadata.labels}' + changed_when: false + register: kubectl_list_labels + +- set_fact: + current_labels: "{{ kubectl_list_labels.stdout | from_json }}" + +- name: add labels to node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ kubernetes_node_labels | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + when: "item.key not in current_labels or current_labels[item.key] != item.value" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf label --overwrite node '{{ kubernetes_node_name }}' '{{ item.key }}={{ item.value }}' + +- name: add stamp files for managed labels + loop: "{{ kubernetes_node_labels | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + copy: + dest: "/etc/kubernetes/decorations/labels/{{ item.key }}" + content: "{{ item.value }}" + +- name: get list of managed labels + find: + path: /etc/kubernetes/decorations/labels + register: managed_labels + +- name: remove superflous labels from node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ managed_labels.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_labels" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf label --overwrite node '{{ kubernetes_node_name }}' '{{ item }}-' + +- name: remove stamp files for superflous labels + loop: "{{ managed_labels.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_labels" + file: + path: "/etc/kubernetes/decorations/labels/{{ item }}" + state: absent diff --git a/roles/kubernetes/decorations/tasks/main.yml b/roles/kubernetes/decorations/tasks/main.yml new file mode 100644 index 00000000..7d25c9de --- /dev/null +++ b/roles/kubernetes/decorations/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: generate directories for node decorations + loop: + - annotations + - labels + - taints + file: + path: "/etc/kubernetes/decorations/{{ item }}" + state: directory + +- name: manage node annotations + when: kubernetes_node_annotations is defined + include_tasks: annotations.yml + +- name: manage node labels + when: kubernetes_node_labels is defined + include_tasks: labels.yml + +- name: manage node taints + when: kubernetes_node_taints is defined + include_tasks: taints.yml diff --git a/roles/kubernetes/decorations/tasks/taints.yml b/roles/kubernetes/decorations/tasks/taints.yml new file mode 100644 index 00000000..fd60ef88 --- /dev/null +++ b/roles/kubernetes/decorations/tasks/taints.yml @@ -0,0 +1,44 @@ +--- +- name: get list of current taints + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + check_mode: no + command: kubectl --kubeconfig /etc/kubernetes/admin.conf get node '{{ kubernetes_node_name }}' -o jsonpath='{.spec.taints}' + changed_when: false + register: kubectl_list_taints + +- set_fact: + current_taints: "{{ kubectl_list_taints.stdout | ternary(kubectl_list_taints.stdout, '[]') | from_json }}" + +- name: add taints to node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ kubernetes_node_taints | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + when: "item.key not in current_taints or current_taints[item.key] != item.value" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf taint --overwrite node '{{ kubernetes_node_name }}' '{{ item.key }}={{ item.value }}' + +- name: add stamp files for managed taints + loop: "{{ kubernetes_node_taints | dict2items }}" + loop_control: + label: "{{ item.key }}={{ item.value }}" + copy: + dest: "/etc/kubernetes/decorations/taints/{{ item.key }}" + content: "{{ item.value }}" + +- name: get list of managed taints + find: + path: /etc/kubernetes/decorations/taints + register: managed_taints + +- name: remove superflous taints from node + delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + loop: "{{ managed_taints.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_taints" + command: kubectl --kubeconfig /etc/kubernetes/admin.conf taint --overwrite node '{{ kubernetes_node_name }}' '{{ item }}-' + +- name: remove stamp files for superflous taints + loop: "{{ managed_taints.files | map(attribute='path') | map('basename') }}" + when: "item not in kubernetes_node_taints" + file: + path: "/etc/kubernetes/decorations/taints/{{ item }}" + state: absent diff --git a/roles/kubernetes/kubeadm/control-plane/tasks/primary.yml b/roles/kubernetes/kubeadm/control-plane/tasks/primary.yml index cbad58d9..36195235 100644 --- a/roles/kubernetes/kubeadm/control-plane/tasks/primary.yml +++ b/roles/kubernetes/kubeadm/control-plane/tasks/primary.yml @@ -38,8 +38,8 @@ dest: /etc/kubernetes/kubeadm-init.errors - name: create bootstrap token for new cluster - command: kubeadm token create --ttl 42m check_mode: no + command: kubeadm token create --ttl 42m register: kubeadm_token_generate @@ -61,9 +61,9 @@ block: - name: fetch list of current nodes + check_mode: no command: kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes -o name changed_when: False - check_mode: no register: kubectl_node_list - name: save list of current nodes @@ -71,9 +71,9 @@ kubernetes_current_nodes: "{{ kubectl_node_list.stdout_lines | map('replace', 'node/', '') | list }}" - name: create bootstrap token for existing cluster + check_mode: no when: "groups['_kubernetes_nodes_'] | map('extract', hostvars, 'kubernetes_node_name') | difference(kubernetes_current_nodes) | length > 0" command: kubeadm token create --ttl 42m - check_mode: no register: kubeadm_token_create @@ -85,10 +85,10 @@ state: present - name: get ca certificate digest + check_mode: no shell: "set -o pipefail && openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'" args: executable: /bin/bash - check_mode: no register: kube_ca_openssl changed_when: False diff --git a/roles/kubernetes/kubeadm/control-plane/tasks/secondary.yml b/roles/kubernetes/kubeadm/control-plane/tasks/secondary.yml index aaa4d94e..0c7a285f 100644 --- a/roles/kubernetes/kubeadm/control-plane/tasks/secondary.yml +++ b/roles/kubernetes/kubeadm/control-plane/tasks/secondary.yml @@ -5,9 +5,9 @@ block: - name: fetch list of current nodes + check_mode: no command: kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes -o name changed_when: False - check_mode: no register: kubectl_node_list - name: save list of current nodes @@ -15,9 +15,9 @@ kubernetes_current_nodes: "{{ kubectl_node_list.stdout_lines | map('replace', 'node/', '') | list }}" - name: upload certs + check_mode: no when: "groups['_kubernetes_controlplane_nodes_'] | map('extract', hostvars, 'kubernetes_node_name') | difference(kubernetes_current_nodes) | length > 0" command: kubeadm init phase upload-certs --upload-certs - check_mode: no register: kubeadm_upload_certs - name: extracting encryption key for certs @@ -57,6 +57,7 @@ - name: wait for new control-plane node to register delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + check_mode: no command: "kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes -o name {{ kubernetes_node_name }}" changed_when: False register: kubectl_node_get diff --git a/roles/kubernetes/kubeadm/reset/tasks/main.yml b/roles/kubernetes/kubeadm/reset/tasks/main.yml index bc38ce81..ce343f3c 100644 --- a/roles/kubernetes/kubeadm/reset/tasks/main.yml +++ b/roles/kubernetes/kubeadm/reset/tasks/main.yml @@ -14,6 +14,7 @@ - /etc/kubernetes/network-plugin.yml - /etc/kubernetes/node-local-dns.yml - /etc/kubernetes/addons + - /etc/kubernetes/decorations - /etc/default/kubelet file: path: "{{ item }}" diff --git a/roles/kubernetes/kubeadm/worker/tasks/main.yml b/roles/kubernetes/kubeadm/worker/tasks/main.yml index 422f27c7..835967b8 100644 --- a/roles/kubernetes/kubeadm/worker/tasks/main.yml +++ b/roles/kubernetes/kubeadm/worker/tasks/main.yml @@ -30,6 +30,7 @@ - name: wait for new worker node to register delegate_to: "{{ groups['_kubernetes_primary_controlplane_node_'] | first }}" + check_mode: no command: "kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes -o name {{ kubernetes_node_name }}" changed_when: False register: kubectl_node_get -- cgit v1.2.3