diff --git a/ansible-collection-requirements.yml b/ansible-collection-requirements.yml index 0ff8346622..21f1fe1300 100644 --- a/ansible-collection-requirements.yml +++ b/ansible-collection-requirements.yml @@ -48,7 +48,7 @@ collections: source: https://github.com/ansible-collections/openvswitch.openvswitch type: git version: 2.1.1 -- name: osa_ops.mcapi_vexxhost - source: https://opendev.org/openstack/openstack-ansible-ops#/mcapi_vexxhost +- name: adriacloud.kubernetes + source: https://github.com/adriacloud/ansible-collection-kubernetes type: git - version: master + version: 26.4.1 diff --git a/etc/openstack_deploy/openstack_user_config.yml.aio.j2 b/etc/openstack_deploy/openstack_user_config.yml.aio.j2 index f7609575f5..6e6abd4d2a 100644 --- a/etc/openstack_deploy/openstack_user_config.yml.aio.j2 +++ b/etc/openstack_deploy/openstack_user_config.yml.aio.j2 @@ -228,7 +228,7 @@ repo_infra_hosts: ip: {{ bootstrap_host_public_address }} management_ip: {{ bootstrap_host_management_address }} -{% if 'zookeeper' in bootstrap_host_scenarios_expanded %} +{% if 'zookeeper' in bootstrap_host_scenarios_expanded or 'infra' in bootstrap_host_scenarios_expanded %} coordination_hosts: aio1: ip: {{ bootstrap_host_public_address }} @@ -238,3 +238,14 @@ coordination_hosts: zookeeper_container: 3 {% endif %} {% endif %} + +{% if 'k8s' in bootstrap_host_scenarios_expanded or 'infra' in bootstrap_host_scenarios_expanded %} +cluster_api_hosts: + aio1: + ip: {{ bootstrap_host_public_address }} + management_ip: {{ bootstrap_host_management_address }} +{% if 'infra' in bootstrap_host_scenarios_expanded %} + affinity: + k8s_container: 3 +{% endif %} +{% endif %} diff --git a/inventory/group_vars/k8s_all/defaults.yml b/inventory/group_vars/k8s_all/defaults.yml new file mode 100644 index 0000000000..9f9b2480ff --- /dev/null +++ b/inventory/group_vars/k8s_all/defaults.yml @@ -0,0 +1,55 @@ +--- +# Copyright 2026, BBC R&D +# +# 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. + +# Pick a range of addresses for cilium that do not collide with anything else +cilium_ipv4_cidr: 172.29.200.0/22 + +# Set a clusterctl version. Supported list can be found in defaults: +# https://github.com/adriacloud/ansible-collection-kubernetes/blob/main/roles/clusterctl/defaults/main.yml +clusterctl_version: 1.12.3 +cluster_api_version: 1.12.3 +cluster_api_infrastructure_provider: openstack +cluster_api_infrastructure_version: 0.14.1 + +# wire OSA group, host and network addresses into k8s deployment +kubelet_hostname: "{{ ansible_facts['hostname'] | lower }}" +kubelet_node_ip: "{{ management_address }}" +kubernetes_control_plane_group: k8s_container +kubernetes_hostname: "{{ internal_lb_vip_address }}" +kubernetes_non_init_namespace: true + +# Define k8s version for the control cluster +kubernetes_version: 1.35.2 + +# Define LXC container overrides +lxc_container_config_list: "{{ ((hostvars[physical_host]['ansible_facts']['os_family'] | lower) == 'debian') | ternary(['lxc.apparmor.profile=unconfined'], []) }}" + +lxc_container_mount_auto: + - "proc:rw" + - "sys:rw" + +# Set this manually, or kube-proxy will try to do this - not possible +# in a non-init namespace and will fail in LXC +openstack_host_nf_conntrack_max: 1572864 + +# OSA containers dont run ssh by default so cannot use synchronize +upload_helm_chart_method: copy + +# Run ansible modules in a venv on the target hosts +ansible_collection_kubernetes_target_venv: /opt/mcapi_ansible_venv + +# Enable periodic cluster API state collection (note: this is not a guaranteed functional backup) +# See https://cluster-api.sigs.k8s.io/clusterctl/commands/move +cluster_api_backups_enabled: False diff --git a/inventory/group_vars/k8s_all/haproxy_service.yml b/inventory/group_vars/k8s_all/haproxy_service.yml new file mode 100644 index 0000000000..b77d43a818 --- /dev/null +++ b/inventory/group_vars/k8s_all/haproxy_service.yml @@ -0,0 +1,43 @@ +--- +# Copyright 2026, BBC R&D +# +# 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. + +haproxy_k8s_service: + haproxy_service_name: k8s + haproxy_backend_nodes: "{{ groups['k8s_all'] | default([]) }}" + haproxy_ssl: false + haproxy_ssl_all_vips: false + haproxy_port: 6443 + haproxy_balance_type: tcp + haproxy_balance_alg: leastconn + haproxy_interval: '15000' + haproxy_backend_port: 6443 + haproxy_backend_rise: 2 + haproxy_backend_fall: 2 + haproxy_timeout_server: '15m' + haproxy_timeout_client: '5m' + haproxy_backend_options: + - tcplog + - ssl-hello-chk + - log-health-checks + - httpchk GET /healthz + haproxy_backend_httpcheck_options: + - 'send hdr User-Agent "osa-haproxy-healthcheck" meth GET uri /healthz' + haproxy_backend_server_options: + - check-ssl + - verify none + haproxy_service_enabled: "{{ groups['k8s_all'] is defined and groups['k8s_all'] | length > 0 }}" + +k8s_haproxy_services: + - "{{ haproxy_k8s_service | combine(haproxy_k8s_service_overrides | default({})) }}" diff --git a/inventory/group_vars/magnum_all/source_git.yml b/inventory/group_vars/magnum_all/source_git.yml index d74c6fe1cf..5c7f9ff056 100644 --- a/inventory/group_vars/magnum_all/source_git.yml +++ b/inventory/group_vars/magnum_all/source_git.yml @@ -19,3 +19,11 @@ magnum_git_repo: "{{ openstack_opendev_base_url }}/openstack/magnum" magnum_git_install_branch: 1b8f1b9ba0051203841100d3ce244ba832741c68 magnum_git_track_branch: stable/2026.1 + +magnum_capi_vexxhost_git_repo: "{{ openstack_github_base_url }}/vexxhost/magnum-cluster-api" +magnum_capi_vexxhost_git_install_branch: v0.36.0 +magnum_capi_vexxhost_git_track_branch: None + +magnum_capi_azimuth_git_repo: "{{ openstack_opendev_base_url }}/openstack/magnum-capi-helm" +magnum_capi_azimuth_git_install_branch: d60ae3f89cd925a7097082facfd9c140ea8cf9a2 +magnum_capi_azimuth_git_track_branch: master diff --git a/playbooks/k8s-install.yml b/playbooks/k8s-install.yml new file mode 100644 index 0000000000..cd366ff843 --- /dev/null +++ b/playbooks/k8s-install.yml @@ -0,0 +1,17 @@ +--- +# Copyright 2026, BBC R&D +# +# 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: Importing k8s playbook + import_playbook: openstack.osa.k8s diff --git a/tests/roles/bootstrap-host/templates/user_variables_magnum.yml.j2 b/tests/roles/bootstrap-host/templates/user_variables_magnum.yml.j2 index 454c0a52a7..bb1b013f5d 100644 --- a/tests/roles/bootstrap-host/templates/user_variables_magnum.yml.j2 +++ b/tests/roles/bootstrap-host/templates/user_variables_magnum.yml.j2 @@ -13,6 +13,18 @@ # See the License for the specific language governing permissions and # limitations under the License. +{% if 'k8s' in bootstrap_host_scenarios_expanded %} +# Tempest alongside capi testing takes too long +tempest_install: False +functional_test_k8s_version: "{{ zuul_vars.kubernetes_version | default(undef()) }}" +{% if 'vexxhost' in bootstrap_host_scenarios_expanded %} +magnum_k8s_driver: "vexxhost" +post_setup_openstack_hook: /etc/ansible/roles/os_magnum/tests/functional_test.yml +{% elif 'azimuth' in bootstrap_host_scenarios_expanded %} +magnum_k8s_driver: "azimuth" +{% endif %} +{% else %} +magnum_k8s_driver: "heat" magnum_glance_images: - name: fedora-coreos-latest disk_format: qcow2 @@ -70,3 +82,5 @@ tempest_tempest_conf_overrides_magnum: master_flavor_id: m1.magnum flavor_id: s1.magnum image_id: fedora-coreos-latest + +{% endif %} diff --git a/tests/roles/bootstrap-host/vars/main.yml b/tests/roles/bootstrap-host/vars/main.yml index b32b1625fc..0cfb7af908 100644 --- a/tests/roles/bootstrap-host/vars/main.yml +++ b/tests/roles/bootstrap-host/vars/main.yml @@ -55,7 +55,7 @@ bootstrap_host_scenarios_expanded: |- 'freezer' in bootstrap_host_scenarios %} {% set _ = scenario_list.extend(['swift']) %} {% endif %} - {% if ('magnum' in bootstrap_host_scenarios) %} + {% if ('magnum' in bootstrap_host_scenarios and 'capi' not in bootstrap_host_scenarios) %} {% set _ = scenario_list.extend(['heat']) %} {% endif %} {% if 'manila' in bootstrap_host_scenarios %} diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml index 1032bc368c..93495d9008 100644 --- a/zuul.d/jobs.yaml +++ b/zuul.d/jobs.yaml @@ -270,6 +270,7 @@ - name: openstack/ironic - name: openstack/ironic-inspector - name: openstack/magnum + - name: openstack/magnum-capi-helm - name: openstack/masakari - name: openstack/masakari-monitors - name: openstack/mistral @@ -357,6 +358,7 @@ - ^playbooks\/haproxy(-install)?\.yml - ^playbooks\/utility(-install|_host)\.yml - ^playbooks\/zookeeper-(-install)?\.yml + - ^playbooks\/k8s-(-install)?\.yml # Running linters check