From 2d126c2a793d442e5280e9505d1e37227753e613 Mon Sep 17 00:00:00 2001 From: Bjoern Teipel Date: Thu, 1 Feb 2024 21:55:39 +0000 Subject: [PATCH 1/2] Fix cluster_name variable preference As we set cluster_name per inventory, setting it in group vars cerates a preference issue, overriding the inventory hostvar --- .../group_vars/k8s_cluster/k8s-cluster.yml | 4 +++- .../openstack-flex/group_vars/k8s_cluster/k8s-cluster.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ansible/inventory/openstack-enterprise/group_vars/k8s_cluster/k8s-cluster.yml b/ansible/inventory/openstack-enterprise/group_vars/k8s_cluster/k8s-cluster.yml index b3ce2fa6..257f6697 100644 --- a/ansible/inventory/openstack-enterprise/group_vars/k8s_cluster/k8s-cluster.yml +++ b/ansible/inventory/openstack-enterprise/group_vars/k8s_cluster/k8s-cluster.yml @@ -157,7 +157,9 @@ kube_encrypt_secret_data: true # DNS configuration. # Kubernetes cluster name, also will be used as DNS domain -cluster_name: cluster.local +# Set via inventory +#cluster_name: cluster.local +# # Subdomains of DNS domain to be resolved via /etc/resolv.conf for hostnet pods ndots: 2 # dns_timeout: 2 diff --git a/ansible/inventory/openstack-flex/group_vars/k8s_cluster/k8s-cluster.yml b/ansible/inventory/openstack-flex/group_vars/k8s_cluster/k8s-cluster.yml index 3d05fd6b..0c39ef99 100644 --- a/ansible/inventory/openstack-flex/group_vars/k8s_cluster/k8s-cluster.yml +++ b/ansible/inventory/openstack-flex/group_vars/k8s_cluster/k8s-cluster.yml @@ -157,7 +157,9 @@ kube_encrypt_secret_data: false # DNS configuration. # Kubernetes cluster name, also will be used as DNS domain -cluster_name: cluster.local +# Set via inventory +#cluster_name: cluster.local + # Subdomains of DNS domain to be resolved via /etc/resolv.conf for hostnet pods ndots: 2 # dns_timeout: 2 From b5fcf10374aae48b4ee531283e8e5ca7c0307772 Mon Sep 17 00:00:00 2001 From: Bjoern Teipel Date: Wed, 7 Feb 2024 05:57:50 +0000 Subject: [PATCH 2/2] Adding playbook to install and configure k8s nodes - Add k8s_install role to install, upgrade and configure k8s nodes post install, such as labling - Add scaffolding to support future k8s installer --- ansible-collection-requirements.yml | 3 + ansible/playbooks/setup-kubernetes.yml | 25 +++ ansible/playbooks/vars/default.yml | 9 + ansible/roles/k8s_install/README.md | 59 ++++++ ansible/roles/k8s_install/defaults/main.yml | 26 +++ ansible/roles/k8s_install/handlers/main.yml | 2 + ansible/roles/k8s_install/meta/main.yml | 16 ++ .../roles/k8s_install/tasks/k8s_client.yml | 59 ++++++ .../k8s_install/tasks/k8s_label_nodes.yml | 59 ++++++ .../k8s_install/tasks/kubespray_install.yml | 42 +++++ .../k8s_install/tasks/kubespray_upgrade.yml | 42 +++++ ansible/roles/k8s_install/tasks/main.yml | 168 ++++++++++++++++++ ansible/roles/k8s_install/tests/inventory | 50 ++++++ ansible/roles/k8s_install/tests/test.yml | 1 + ansible/roles/k8s_install/vars/main.yml | 2 + dev-requirements.txt | 24 +++ docs/quickstart.md | 5 +- requirements.txt | 3 +- 18 files changed, 592 insertions(+), 3 deletions(-) create mode 100644 ansible/playbooks/setup-kubernetes.yml create mode 100644 ansible/playbooks/vars/default.yml create mode 100644 ansible/roles/k8s_install/README.md create mode 100644 ansible/roles/k8s_install/defaults/main.yml create mode 100644 ansible/roles/k8s_install/handlers/main.yml create mode 100644 ansible/roles/k8s_install/meta/main.yml create mode 100644 ansible/roles/k8s_install/tasks/k8s_client.yml create mode 100644 ansible/roles/k8s_install/tasks/k8s_label_nodes.yml create mode 100644 ansible/roles/k8s_install/tasks/kubespray_install.yml create mode 100644 ansible/roles/k8s_install/tasks/kubespray_upgrade.yml create mode 100644 ansible/roles/k8s_install/tasks/main.yml create mode 100644 ansible/roles/k8s_install/tests/inventory create mode 100644 ansible/roles/k8s_install/tests/test.yml create mode 100644 ansible/roles/k8s_install/vars/main.yml diff --git a/ansible-collection-requirements.yml b/ansible-collection-requirements.yml index 349b442d..0ab07c43 100644 --- a/ansible-collection-requirements.yml +++ b/ansible-collection-requirements.yml @@ -2,6 +2,9 @@ collections: - name: https://opendev.org/openstack/ansible-collections-openstack version: 2.2.0 type: git + - name: https://github.com/ansible-collections/ansible.posix + version: 1.5.4 + type: git - name: https://github.com/ansible-collections/community.general version: 8.2.0 type: git diff --git a/ansible/playbooks/setup-kubernetes.yml b/ansible/playbooks/setup-kubernetes.yml new file mode 100644 index 00000000..8a97f3e1 --- /dev/null +++ b/ansible/playbooks/setup-kubernetes.yml @@ -0,0 +1,25 @@ +--- +# Copyright 2024-Present, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- hosts: localhost + become: True + gather_facts: "{{ gather_facts | default(true) }}" + environment: "{{ deployment_environment_variables | default({}) }}" + vars_files: + - 'vars/default.yml' + roles: + - role: "k8s_install" + pre_execution_hook: "source /opt/genestack/scripts/genestack.rc" + kubeprovider: "{{ kube_installer }}" diff --git a/ansible/playbooks/vars/default.yml b/ansible/playbooks/vars/default.yml new file mode 100644 index 00000000..c719a6db --- /dev/null +++ b/ansible/playbooks/vars/default.yml @@ -0,0 +1,9 @@ +--- + +# General settings +ansible_forks: "{{ (hostvars[inventory_hostname]['ansible_processor_nproc'] ** 2 |round(0,'floor') |int }}" +async_timeout: 4500 #75 minutes + +kube_installer: + name: "{{ lookup('env','K8S_PROVIDER') |default('kubespray') }}" + path: "/opt/genestack/submodules/kubespray" diff --git a/ansible/roles/k8s_install/README.md b/ansible/roles/k8s_install/README.md new file mode 100644 index 00000000..37b0262f --- /dev/null +++ b/ansible/roles/k8s_install/README.md @@ -0,0 +1,59 @@ +Role k8s_install +================ + +Role to install k8s distributions and apply configurations tasks post install including + +- Pull kubctl configuration from the first cluster node +- Node labeling (install only) + +A kubespray like inventory is expected, supplying at a minimum: + +`k8s_cluster` setting `cluster_name` and consisting of the children +`kube_control_plane`, `kube_node`. + +The `cluster_name` variable must be configured to a desired FQDN, outside of `cluster.local` for obvious reasons +such a tld `.local` can not utilize EV certificates. + +At this time only the kubespray installer is supported, others can be added over time. +The override `kube_install_mode` defaults to `install` which utilizes the kubespray `cluster.yml`. +By setting this override to `upgrade`, the role delegates to the `upgrade.yml` playbook preceded by a version check. +Other modes such as scaling out, increasing k8s node count, will be added over time. + +Requirements +------------ + +- Supplied kubespray code to run the cluster playbook + +Role Variables +-------------- + +See [defaults](defaults/main.yml) + + +Dependencies +------------ + +N/A + + +Example Playbook +---------------- + +```shell +- hosts: localhost + become: True + gather_facts: "{{ gather_facts | default(true) }}" + vars_files: + - 'vars/default.yml' + roles: + - role: "k8s_install" + pre_execution_hook: "source env.rc" + kubeprovider: + name: "kubespray" + path: "/opt/kubespray" +``` + +License +------- + +[![Apache License, Version 2.0](https://img.shields.io/badge/License-Apache-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) diff --git a/ansible/roles/k8s_install/defaults/main.yml b/ansible/roles/k8s_install/defaults/main.yml new file mode 100644 index 00000000..42a475fc --- /dev/null +++ b/ansible/roles/k8s_install/defaults/main.yml @@ -0,0 +1,26 @@ +--- + +ansible_forks: 8 +async_timeout: 4500 #75 minutes + +# Base kubernets parameters +kube_install_mode: "install" # install | upgrade | scaleout +supported_kube_installer: + - "kubespray" + +# Command which gets executed prior to the +# installation, if utilized inside the install +# or upgrade task +pre_execution_hook: + +# How to build the kubernetes client configuration +# +# retrieve: Get the configuration from the first api host +# authorize: TODO setup a local kubernetes user +kubeconfig_file: "{{ lookup('env','HOME') |default('/root') }}/.kube/config" +kubeconfig_mode: "retrieve" + +# Which k8s installer to use +kubeprovider: + name: 'kubespray' + path: '/opt/kubespray' diff --git a/ansible/roles/k8s_install/handlers/main.yml b/ansible/roles/k8s_install/handlers/main.yml new file mode 100644 index 00000000..04b60400 --- /dev/null +++ b/ansible/roles/k8s_install/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for k8s_install diff --git a/ansible/roles/k8s_install/meta/main.yml b/ansible/roles/k8s_install/meta/main.yml new file mode 100644 index 00000000..b7f7697d --- /dev/null +++ b/ansible/roles/k8s_install/meta/main.yml @@ -0,0 +1,16 @@ +galaxy_info: + author: Bjoern Teipel + description: A light weight wrapper to install k3s from a kubespray-like Ansible inventory + company: Rackspace Technology + license: Apache-2.0 + min_ansible_version: 2.15.8 + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. +dependencies: [] + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. diff --git a/ansible/roles/k8s_install/tasks/k8s_client.yml b/ansible/roles/k8s_install/tasks/k8s_client.yml new file mode 100644 index 00000000..bb80a305 --- /dev/null +++ b/ansible/roles/k8s_install/tasks/k8s_client.yml @@ -0,0 +1,59 @@ +--- +# Copyright 2024, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Not intended to run stand alone, please run within a playbook +# and expose parameters as listed below: +# +# - Loaded kubespray like inventory +# - cluster_name + +- name: Create kubectl config directory + ansible.builtin.file: + path: "{{ lookup('env','HOME') }}/.kube/{{ cluster_name }}" + state: directory + recurse: True + mode: '0700' + +- name: Get kubernetes client + ansible.posix.synchronize: + mode: pull + src: "{{ item.user }}@{{ item.host }}:/usr/local/bin/kubectl" + dest: "/usr/local/bin/kubectl" + loop: + - user: "{{ ansible_become_user |default('root') }}" + host: "{{ groups['k8s_cluster'][0] }}" + +- block: + - name: Get kubernetes config + ansible.posix.synchronize: + mode: pull + src: "{{ item.user }}@{{ item.host }}:/root/.kube/config" + dest: "{{ lookup('env','HOME') }}/.kube/{{ cluster_name }}/" + #dest: "{{ lookup('env','HOME') }}/.kube/" + loop: + - user: "{{ ansible_become_user |default('root') }}" + host: "{{ groups['k8s_cluster'][0] }}" + + - name: Set path to kubectl config + ansible.builtin.set_fact: + kubeconfig_file: "{{ lookup('env','HOME') }}/.kube/{{ cluster_name }}/config" + + - name: "Display configuration" + ansible.builtin.debug: + msg: "{{ item.name }}: {{ item.value }}" + loop: + - name: "Kubectl Config (updated)" + value: "{{ kubeconfig_file }}" diff --git a/ansible/roles/k8s_install/tasks/k8s_label_nodes.yml b/ansible/roles/k8s_install/tasks/k8s_label_nodes.yml new file mode 100644 index 00000000..709397a4 --- /dev/null +++ b/ansible/roles/k8s_install/tasks/k8s_label_nodes.yml @@ -0,0 +1,59 @@ +--- +# Copyright 2024-Present, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: "Map node to label/role" + ansible.builtin.set_fact: + kubectl_options: | + {% set _kctl = kubectl_options |default([]) %} + {% if (item.hosts |length) > 0 %} + {% for node in item.hosts %} + {% set _label = "" %} + {% set _role = "" %} + {% set _node = "label node " + node + " " %} + {% if item.label is defined %} + {% set _label = item.label %} + {% endif %} + {% if item.role is defined %} + {% set _role = " role=" + item.role %} + {% endif %} + {% if _kctl.append(_node + _label + _role) %}{% endif %} + {% endfor %} + {% endif %} + {{ _kctl }} + loop: + - hosts: "{{ groups['openstack_control_plane'] }}" + label: "openstack-control-plane=enabled" + - hosts: "{{ groups['openstack_compute_nodes'] }}" + label: "openstack-compute-node=enabled" + - hosts: "{{ groups['openstack_network_nodes'] |default([]) }}" + label: "openstack-network-node=enabled" + - hosts: "{{ groups['ovn_network_nodes'] |default([]) }}" + label: "openstack-network-node=enabled" + - hosts: "{{ groups['openstack_storage_nodes'] |default([]) }}" + label: "openstack-storage-plane=enabled" + - hosts: "{{ groups['cinder_storage_nodes'] |default([]) }}" + label: "openstack-storage-node=enabled" + - hosts: "{{ groups['storage_nodes'] |default([]) }}" + role: "storage-node" + - hosts: "{{ groups['ceph_storage_nodes'] |default([]) }}" + label: "ceph-storage-node=enabled" + role: "storage-node" + +- name: "Apply label" + ansible.builtin.shell: | + kubectl --kubeconfig="{{ kubeconfig_file }}" {{ item }} + args: + executable: /bin/bash + loop: "{{ kubectl_options }}" diff --git a/ansible/roles/k8s_install/tasks/kubespray_install.yml b/ansible/roles/k8s_install/tasks/kubespray_install.yml new file mode 100644 index 00000000..c579b422 --- /dev/null +++ b/ansible/roles/k8s_install/tasks/kubespray_install.yml @@ -0,0 +1,42 @@ +--- +# Copyright 2024-Present, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: "Execute kubespray installer" + block: + - name: "Output" + debug: + msg: + - "Executing kubespray installer in mode {{ kube_install_mode }}" + - "Output will be send to /var/log/kubespray.log" + - "Max timeout set to {{ async_timeout }} seconds" + + - name: "Execute kubespray cluster.yml" + ansible.builtin.shell: | + set -o pipefail # + {% if pre_execution_hook is defined %} + {{ pre_execution_hook }} + {% endif %} + ansible-playbook --forks {{ ansible_forks }} cluster.yml 2>&1 |tee -a /var/log/kubespray.log + echo -e "\nRC: $?" |tee -a /var/log/kubespray.log + args: + executable: /bin/bash + chdir: "{{ kubeprovider.path }}" + register: _kubernetes_install + changed_when: + - "_kubernetes_install.rc == 0" + - "_kubernetes_install.stdout |regex_search('changed=(1[0-9]*)')" + failed_when: _kubernetes_install.rc not in [0] + async: "{{ async_timeout }}" + poll: 5 diff --git a/ansible/roles/k8s_install/tasks/kubespray_upgrade.yml b/ansible/roles/k8s_install/tasks/kubespray_upgrade.yml new file mode 100644 index 00000000..fe3b8d52 --- /dev/null +++ b/ansible/roles/k8s_install/tasks/kubespray_upgrade.yml @@ -0,0 +1,42 @@ +--- +# Copyright 2024-Present, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: "Execute kubespray upgrade" + block: + - name: "Output" + debug: + msg: + - "Executing kubespray installer in mode {{ kube_install_mode }}" + - "Output will be send to /var/log/kubespray-upgrade.log" + - "Max timeout set to {{ async_timeout }} seconds" + + - name: "Execute kubespray upgrade-cluster.yml" + ansible.builtin.shell: | + set -o pipefail # + {% if pre_execution_hook is defined %} + {{ pre_execution_hook }} + {% endif %} + ansible-playbook --forks {{ ansible_forks }} upgrade-cluster.yml 2>&1 |tee -a /var/log/kubespray-upgrade.log + echo -e "\nRC: $?" |tee -a /var/log/kubespray-upgrade.log + args: + executable: /bin/bash + chdir: "{{ kubeprovider.path }}" + register: _kubernetes_install + changed_when: + - "_kubernetes_install.rc == 0" + - "_kubernetes_install.stdout |regex_search('changed=(1[0-9]*)')" + failed_when: _kubernetes_install.rc not in [0] + async: "{{ async_timeout }}" + poll: 5 diff --git a/ansible/roles/k8s_install/tasks/main.yml b/ansible/roles/k8s_install/tasks/main.yml new file mode 100644 index 00000000..76e02084 --- /dev/null +++ b/ansible/roles/k8s_install/tasks/main.yml @@ -0,0 +1,168 @@ +--- +# Copyright 2024, Rackspace Technology, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +### +### Pre execution checks +### + +- name: Gather variables for each operating system + include_vars: "{{ lookup('first_found', params) }}" + vars: + params: + files: + - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_version'] | lower }}.yml" + - "{{ ansible_facts['distribution'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" + - "{{ ansible_facts['os_family'] | lower }}-{{ ansible_facts['distribution_major_version'] | lower }}.yml" + - "{{ ansible_facts['distribution'] | lower }}.yml" + - "{{ ansible_facts['os_family'] | lower }}.yml" + - "main.yml" + paths: + - "{{ role_path }}/vars" + tags: + - always + +- name: "Assert kubeconfig mode" + ansible.builtin.assert: + that: + - "kubeconfig_mode in ['retrieve']" + tags: + - always + +- name: "Load all inventory variables" + ansible.builtin.include_vars: + dir: "{{ item }}" + ignore_unknown_extensions: True + extensions: + - 'yaml' + - 'yml' + loop: "{{ ansible_inventory_sources }}" + tags: + - always + +- name: "Assert cluster_name is not set to cluster.local" + ansible.builtin.assert: + that: + - "hostvars[ groups['k8s_cluster'][0] ]['cluster_name'] not in ['cluster.local']" + tags: + - always + +- name: "Display base configuration" + ansible.builtin.debug: + msg: "{{ item.msg }}: {{ item.value }}" + loop: + - msg: "Pre Execution Hook" + value: "{{ pre_execution_hook }}" + - msg: "Kubernetes Product" + value: "{{ kubeprovider.name }}" + - msg: "Kubernetes Installer Path" + value: "{{ kubeprovider.path }}" + - msg: "Kubernetes Cluster Name" + value: "{{ hostvars[ groups['k8s_cluster'][0] ]['cluster_name'] }}" + - msg: "Kubectl Config (default)" + value: "{{ kubeconfig_file }}" + tags: + - always + +- name: "Check supported kubernetes installer" + ansible.builtin.assert: + that: + - "kubeprovider.name in supported_kube_installer" + fail_msg: "Requested kubernetes installer not supported" + quiet: True + tags: + - always + +- name: "Setting facts" + ansible.builtin.set_fact: + cluster_name: "{{ hostvars[ groups['k8s_cluster'][0] ]['cluster_name'] }}" + tags: + - always + + +### +### Installation section +### + +### (Kubespray) Install K8s cluster +- name: "Execute kubespray installer" + ansible.builtin.import_tasks: kubespray_install.yml + tags: + - install + when: + - "(kubeprovider.name | lower) == 'kubespray'" + - "kube_install_mode == 'install'" + +### Install K8s client after cluster install +- name: "Ensure k8s client configuration" + ansible.builtin.import_tasks: k8s_client.yml + tags: + - always + when: + - "kube_install_mode == 'install' or kube_install_mode == 'upgrade'" + + +### +### Upgrade section +### + +### Retrieve k8s server versions +- name: "Determine kubernetes server version" + kubernetes.core.k8s_cluster_info: + kubeconfig: "{{ kubeconfig_file }}" + register: _kubernetes_server_info + failed_when: _kubernetes_server_info.version.server.kubernetes.gitVersion is not defined + tags: + - always + +- name: "Set current and desired version facts" + ansible.builtin.set_fact: + kube_desired_version: "{{ kube_version |regex_findall('[0-9]+') |join }}" + #kube_current_version: "{{ _kubernetes_server_info.stdout |from_json |json_query('serverVersion.gitVersion') |regex_findall('[0-9]+') |join }}" #kubectl output + kube_current_version: "{{ _kubernetes_server_info.version.server.kubernetes.gitVersion |regex_findall('[0-9]+') |join }}" + tags: + - always + +### (Kubespray) Upgrade +- debug: + msg: "Upgrade skipped as kubernetes version {{ kube_desired_version }} <= {{ kube_current_version }}" + when: + - "kube_desired_version <= kube_current_version" + +- name: "Check kubespray upgrade" + ansible.builtin.import_tasks: kubespray_upgrade.yml + tags: + - upgrade + when: + - "(kubeprovider.name | lower) == 'kubespray'" + - "kube_install_mode == 'upgrade'" + - "kube_desired_version > kube_current_version" + +### +### Scale section +### + +# TODO + +### +### Label nodes +### + +- name: "Apply labels to nodes" + ansible.builtin.import_tasks: k8s_label_nodes.yml + tags: + - always + - label_nodes + when: + - "kube_install_mode == 'install'" diff --git a/ansible/roles/k8s_install/tests/inventory b/ansible/roles/k8s_install/tests/inventory new file mode 100644 index 00000000..f9306776 --- /dev/null +++ b/ansible/roles/k8s_install/tests/inventory @@ -0,0 +1,50 @@ +all: + hosts: + bastion1: + ansible_host: 10.100.0.1 + c1: + ansible_host: 10.100.0.2 + c2: + ansible_host: 10.100.0.3 + c3: + ansible_host: 10.100.0.4 + w1: + ansible_host: 10.100.0.5 + w2: + ansible_host: 10.100.0.6 + children: + k8s_cluster: + vars: + cluster_name: dev.local # This clustername should be changed to match your environment domain name. + children: + kube_control_plane: # all k8s control plane nodes need to be in this group + hosts: + c1: null + c2: null + c3: null + etcd: # all etcd nodes need to be in this group + hosts: + c1: null + c2: null + c3: null + kube_node: # all k8s enabled nodes need to be in this group + hosts: + c1: null + c2: null + c3: null + w1: null + w2: null + bastion: + vars: + ansible_user: root + hosts: + bastion1: null + openstack_control_plane: # nodes used for nova compute labeled as openstack-control-plane=enabled + hosts: + c1: null + c2: null + c3: null + openstack_compute_nodes: # nodes used for nova compute labeled as openstack-compute-node=enabled + hosts: + w1: null + w2: null diff --git a/ansible/roles/k8s_install/tests/test.yml b/ansible/roles/k8s_install/tests/test.yml new file mode 100644 index 00000000..ed97d539 --- /dev/null +++ b/ansible/roles/k8s_install/tests/test.yml @@ -0,0 +1 @@ +--- diff --git a/ansible/roles/k8s_install/vars/main.yml b/ansible/roles/k8s_install/vars/main.yml new file mode 100644 index 00000000..9ef2cec3 --- /dev/null +++ b/ansible/roles/k8s_install/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for k8s_install diff --git a/dev-requirements.txt b/dev-requirements.txt index 178d3d12..e024e590 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1 +1,25 @@ +ansible-compat==4.1.11 +ansible-lint==24.2.0 +attrs==23.2.0 +black==24.1.1 +bracex==2.4 +click==8.1.7 +filelock==3.13.1 +jsonschema==4.21.1 +jsonschema-specifications==2023.12.1 +markdown-it-py==3.0.0 +mdurl==0.1.2 +mypy-extensions==1.0.0 +pathspec==0.12.1 +platformdirs==4.2.0 +pygments==2.17.2 +referencing==0.33.0 reno==4.0.0 +rich==13.7.0 +rpds-py==0.17.1 +ruamel.yaml==0.18.6 +subprocess-tee==0.4.1 +tomli==2.0.1 +typing-extensions==4.9.0 +wcmatch==8.5 +yamllint==1.34.0 diff --git a/docs/quickstart.md b/docs/quickstart.md index 51cea7d3..f7796d4f 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -43,10 +43,11 @@ Existing OpenStack Ansible inventory can be converted using the `/opt/genestack/ script which provides a `hosts.yml` Once the inventory is updated and configuration altered (networking etc), the Kubernetes cluster can be initialized with +the `setup-kubernetes.yml` playbook which in addition will also label nodes for OpenStack installation. ``` shell source /opt/genestack/scripts/genestack.rc -cd /opt/genestack/submodules/kubespray +cd /opt/genestack/ansible/playbooks -ansible-playbook cluster.yml +ansible-playbook setup-kubernetes.yml ``` diff --git a/requirements.txt b/requirements.txt index af16aab3..412cb4ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,5 +5,6 @@ jmespath==1.0.1 MarkupSafe==2.1.3 netaddr==0.9.0 pbr==5.11.1 -ruamel.yaml==0.17.35 +ruamel.yaml==0.18.6 ruamel.yaml.clib==0.2.8 +kubernetes>=24.2.0