diff --git a/docs/projects/ansible/collection/kubernetes/index.md b/docs/projects/ansible/collection/kubernetes/index.md index 5126ba7..7fa5489 100644 --- a/docs/projects/ansible/collection/kubernetes/index.md +++ b/docs/projects/ansible/collection/kubernetes/index.md @@ -29,14 +29,20 @@ To install this collection use `ansible-galaxy collection install nofusscomputin ## Features -Most of the features of this collection are from the included role `nfc_kubernetes`, please [view its page for feature details](roles/nfc_kubernetes/index.md). +- Install k3s cluster. Both Single and multi-node clusters + +- Configure the cluster + +- Upgrade a cluster + +For a more detailed list of featured checkout the roles [documentation](roles/nfc_kubernetes/index.md). ## Using this collection This collection has been designed to be a complete and self-contained management tool for a K3s kubernetes cluster. -## K3s Kubernetes Installation +## Cluster Installation By default the install playbook will install to localhost. @@ -64,4 +70,9 @@ The install playbook has a dynamic `hosts` key. This has been done to specifical For the available variables please view the [nfc_kubernetes role docs](roles/nfc_kubernetes/index.md#default-variables) +## Cluster Upgrade +[In place cluster upgrades](https://docs.k3s.io/upgrades/manual#upgrade-k3s-using-the-binary) is the method used to conduct the cluster upgrades. The logic for the upgrades first confirms that K3s is installed and that the local binary and running k3s version are the desired versions. If they are not, they will be updated to the desired version. On completion of this the node has its `k3s` service restarted which completes the upgrade process. + +!!! danger + not following the [Kubernetes version skew policy](https://kubernetes.io/releases/version-skew-policy/) when upgrading your cluster may break your cluster. diff --git a/docs/projects/ansible/collection/kubernetes/roles/nfc_kubernetes/index.md b/docs/projects/ansible/collection/kubernetes/roles/nfc_kubernetes/index.md index 3fe6509..2b766d3 100644 --- a/docs/projects/ansible/collection/kubernetes/roles/nfc_kubernetes/index.md +++ b/docs/projects/ansible/collection/kubernetes/roles/nfc_kubernetes/index.md @@ -70,6 +70,8 @@ This Ansible role is designed to deploy a K3s Kubernetes cluster. Without adding - Install the Helm Binary +- Upgrade cluster + ## Role Workflow diff --git a/roles/nfc_kubernetes/tasks/k3s/install.yaml b/roles/nfc_kubernetes/tasks/k3s/install.yaml index 88a74ae..4e7f3fb 100644 --- a/roles/nfc_kubernetes/tasks/k3s/install.yaml +++ b/roles/nfc_kubernetes/tasks/k3s/install.yaml @@ -138,28 +138,156 @@ when: directory_network_manager_metadata.stat.exists -- name: Check if K3s Installed +- name: Existing k3s File hash + ansible.builtin.stat: + checksum_algorithm: sha256 + name: /usr/local/bin/k3s + register: hash_sha256_k3s_existing_binary + + +- name: Install required python modules + ansible.builtin.pip: + name: "{{ item }}" + state: present + loop: "{{ pip_packages }}" + vars: + pip_packages: + - kubernetes>=12.0.0 + - PyYAML>=3.11 + + +- name: Fetch Kubernetes Node Object + kubernetes.core.k8s_info: + kind: Node + name: "{{ inventory_hostname }}" + register: kubernetes_node + when: > + hash_sha256_k3s_existing_binary.stat.exists | default(false) | bool + + +- name: Fetch Install K3s Metadata ansible.builtin.shell: cmd: | - if [[ $(service k3s status) ]]; then exit 0; else exit 1; fi + if [[ $(which k3s) ]]; then + + export installed_version=$(k3s --version | grep k3s | awk '{print $3}'); + export installed="true"; + export running_version="{{ kubernetes_node.resources[0].status.nodeInfo.kubeletVersion }}"; + + else + + export installed_version=0; + export installed="false"; + export running_version="0"; + + fi + + export correct_hash=$(wget -q https://github.com/k3s-io/k3s/releases/download/v + {{-KubernetesVersion + KubernetesVersion_k3s_prefix | urlencode -}} + /sha256sum-amd64.txt -O - | grep -v 'images' | awk '{print $1}'); + + cat < - nfc_role_kubernetes_master | default(false) | bool + register: k3s_metadata -- name: Check if K3s Installed - ansible.builtin.shell: - cmd: | - if [[ $(service k3s-agent status) ]]; then exit 0; else exit 1; fi - executable: /bin/bash - changed_when: false - failed_when: false - register: k3s_installed +- name: K3s Metadata Fact + ansible.builtin.set_fact: + node_k3s: "{{ k3s_metadata.stdout | from_yaml }}" + + +- name: Remove Cached K3s Binaries + ansible.builtin.file: + path: "/tmp/k3s.{{ cpu_arch.key }}" + state: absent + loop: "{{ nfc_kubernetes_install_architectures | dict2items }}" + loop_control: + loop_var: cpu_arch + vars: + ansible_connection: local when: > - not nfc_role_kubernetes_worker | default(false) | bool + lookup('ansible.builtin.file', '/tmp/k3s.' + cpu_arch.key) | hash('sha256') | string != node_k3s.desired_hash + + +- name: Download K3s Binary + ansible.builtin.uri: + url: |- + https://github.com/k3s-io/k3s/releases/download/v + {{- node_k3s.desired_version | urlencode -}} + /k3s + {%- if cpu_arch.key == 'aarch64' -%} + -arm64 + {%- endif %} + method: GET + return_content: false + status_code: + - 200 + - 304 + dest: "/tmp/k3s.{{ cpu_arch.key }}" + mode: "744" + register: k3s_download_files + delegate_to: localhost + failed_when: > + (lookup('ansible.builtin.file', '/tmp/k3s.' + cpu_arch.key) | hash('sha256') | string) != node_k3s.desired_hash + and + ( + k3s_download_files.status | int != 200 + or + k3s_download_files.status | int != 304 + ) + run_once: true + when: ansible_os_family == 'Debian' + loop: "{{ nfc_kubernetes_install_architectures | dict2items }}" + loop_control: + loop_var: cpu_arch + vars: + ansible_connection: local + + +- name: Copy K3s binary to Host + ansible.builtin.copy: + src: "/tmp/k3s.{{ ansible_architecture }}" + dest: "/usr/local/bin/k3s" + mode: '741' + owner: root + group: root + register: k3s_binary_copy + when: > + node_k3s.current_hash != node_k3s.desired_hash + + +- name: K3s Binary Upgrade + ansible.builtin.service: + name: |- + {%- if nfc_role_kubernetes_master | default(false) | bool -%} + k3s + {%- else -%} + k3s-agent + {%- endif %} + state: restarted + when: > + ( + k3s_binary_copy.changed | default(false) | bool + ) + or + ( + node_k3s.running_version != node_k3s.desired_version + and + node_k3s.installed | default(false) | bool + ) - name: Download Install Scripts @@ -192,61 +320,6 @@ when: "{{ nfc_role_kubernetes_install_olm }}" -- name: Download K3s Binary - ansible.builtin.uri: - url: |- - https://github.com/k3s-io/k3s/releases/download/v - {{- KubernetesVersion + KubernetesVersion_k3s_prefix | urlencode -}} - /k3s - {%- if cpu_arch.key == 'aarch64' -%} - -arm64 - {%- endif %} - method: GET - return_content: false - status_code: - - 200 - - 304 - dest: "/tmp/k3s.{{ cpu_arch.key }}" - mode: "744" - changed_when: false - register: k3s_download_files - delegate_to: localhost - run_once: true - # no_log: true - when: ansible_os_family == 'Debian' - loop: "{{ nfc_kubernetes_install_architectures | dict2items }}" - loop_control: - loop_var: cpu_arch - vars: - ansible_connection: local - - -- name: "[TRACE] Downloaded File SHA256" - ansible.builtin.set_fact: - hash_sha256_k3s_downloaded_binary: "{{ lookup('ansible.builtin.file', '/tmp/k3s.' + cpu_arch.key) | hash('sha256') | string }}" - delegate_to: localhost - loop: "{{ nfc_kubernetes_install_architectures | dict2items }}" - loop_control: - loop_var: cpu_arch - - -- name: Existing k3s File hash - ansible.builtin.stat: - checksum_algorithm: sha256 - name: /usr/local/bin/k3s - register: hash_sha256_k3s_existing_binary - - -- name: Copy K3s binary to Host - ansible.builtin.copy: - src: "/tmp/k3s.{{ ansible_architecture }}" - dest: "/usr/local/bin/k3s" - mode: '741' - owner: root - group: root - when: hash_sha256_k3s_existing_binary.stat.checksum | default('0') != hash_sha256_k3s_downloaded_binary - - - name: Copy install scripts to Host ansible.builtin.copy: src: "{{ item.path }}" @@ -308,7 +381,7 @@ and file_calico_yaml_metadata.stat.exists and - k3s_installed.rc == 0 + not node_k3s.installed | bool ) or 'calico_manifest' in ansible_run_tags @@ -341,13 +414,13 @@ ansible.builtin.shell: cmd: | INSTALL_K3S_SKIP_DOWNLOAD=true \ - INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \ + INSTALL_K3S_VERSION="{{ node_k3s.desired_version }}" \ /tmp/install.sh {% if nfc_role_kubernetes_etcd_enabled %}--cluster-init{% endif %} changed_when: false when: > kubernetes_config.cluster.prime.name | default(inventory_hostname) == inventory_hostname and - k3s_installed.rc == 1 + not node_k3s.installed | bool - name: Install Calico Operator @@ -502,7 +575,7 @@ cmd: | INSTALL_K3S_EXEC="server" \ INSTALL_K3S_SKIP_DOWNLOAD=true \ - INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \ + INSTALL_K3S_VERSION="{{ node_k3s.desired_version }}" \ K3S_TOKEN="{{ k3s_join_token }}" \ /tmp/install.sh executable: /bin/bash @@ -512,7 +585,7 @@ and not kubernetes_config.cluster.prime.name | default(inventory_hostname) == inventory_hostname and - k3s_installed.rc == 1 + not node_k3s.installed | bool - name: Install K3s (worker nodes) @@ -521,7 +594,7 @@ set -o pipefail INSTALL_K3S_EXEC="agent" \ INSTALL_K3S_SKIP_DOWNLOAD=true \ - INSTALL_K3S_VERSION="v{{ KubernetesVersion }}{{ KubernetesVersion_k3s_prefix }}" \ + INSTALL_K3S_VERSION="v{{ node_k3s.desired_version }}" \ K3S_TOKEN="{{ k3s_join_token }}" \ K3S_URL="https://{{ hostvars[kubernetes_config.cluster.prime.name | default(inventory_hostname)].ansible_host }}:6443" \ /tmp/install.sh - @@ -532,7 +605,7 @@ and not kubernetes_config.cluster.prime.name | default(inventory_hostname) == inventory_hostname and - k3s_installed.rc == 1 + not node_k3s.installed | bool - name: Set Kubernetes Final Install Fact