diff --git a/.github/workflows/containers.yaml b/.github/workflows/containers.yaml index 07ad80ab9..ee34f5c41 100644 --- a/.github/workflows/containers.yaml +++ b/.github/workflows/containers.yaml @@ -33,7 +33,7 @@ jobs: strategy: matrix: # if you add a container here, add it to the 'clean_containers' job below - project: [ironic, neutron, keystone, nova, openstack-client, cinder] + project: [ironic, neutron, keystone, nova, openstack-client, cinder, octavia] steps: - name: setup docker buildx @@ -182,6 +182,7 @@ jobs: - neutron - keystone - nova + - octavia - openstack-client - dnsmasq - ironic-nautobot-client diff --git a/apps/openstack/octavia.yaml b/apps/openstack/octavia.yaml new file mode 100644 index 000000000..273320998 --- /dev/null +++ b/apps/openstack/octavia.yaml @@ -0,0 +1,4 @@ +--- +component: octavia +repoURL: https://tarballs.opendev.org/openstack/openstack-helm +chartVersion: 2025.1.12+80041dfbb diff --git a/components/images-openstack.yaml b/components/images-openstack.yaml index 04a63ba03..088d6b8d3 100644 --- a/components/images-openstack.yaml +++ b/components/images-openstack.yaml @@ -101,4 +101,12 @@ images: cinder_backup: "ghcr.io/rackerlabs/understack/cinder:2024.2-ubuntu_jammy" cinder_storage_init: "docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_jammy" cinder_backup_storage_init: "docker.io/openstackhelm/ceph-config-helper:latest-ubuntu_jammy" + + # octavia + octavia_api: "ghcr.io/rackerlabs/understack/octavia:2024.2-ubuntu_jammy" + octavia_db_sync: "ghcr.io/rackerlabs/understack/octavia:2024.2-ubuntu_jammy" + octavia_worker: "ghcr.io/rackerlabs/understack/octavia:2024.2-ubuntu_jammy" + octavia_housekeeping: "ghcr.io/rackerlabs/understack/octavia:2024.2-ubuntu_jammy" + octavia_health_manager: "ghcr.io/rackerlabs/understack/octavia:2024.2-ubuntu_jammy" + octavia_health_manager_init: "docker.io/openstackhelm/heat:2024.2-ubuntu_jammy" ... diff --git a/components/octavia/README.md b/components/octavia/README.md new file mode 100644 index 000000000..54f153374 --- /dev/null +++ b/components/octavia/README.md @@ -0,0 +1 @@ +# OpenStack Octavia Load Balancers diff --git a/components/octavia/kustomization.yaml b/components/octavia/kustomization.yaml new file mode 100644 index 000000000..6fb0e942d --- /dev/null +++ b/components/octavia/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - octavia-rabbitmq-queue.yaml + - octavia-mariadb-db.yaml diff --git a/components/octavia/octavia-mariadb-db.yaml b/components/octavia/octavia-mariadb-db.yaml new file mode 100644 index 000000000..24c8c978a --- /dev/null +++ b/components/octavia/octavia-mariadb-db.yaml @@ -0,0 +1,52 @@ +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: Database +metadata: + name: octavia + namespace: openstack +spec: + # If you want the database to be created with a different name than the resource name + # name: data-custom + mariaDbRef: + name: mariadb # name of the MariaDB kind + waitForIt: true + characterSet: utf8 + collate: utf8_general_ci + retryInterval: 5s +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: User +metadata: + name: octavia + namespace: openstack +spec: + # If you want the user to be created with a different name than the resource name + # name: user-custom + mariaDbRef: + name: mariadb # name of the MariaDB kind + waitForIt: true + passwordSecretKeyRef: + name: octavia-db-password + key: password + # This field is immutable and defaults to 10, 0 means unlimited. + maxUserConnections: 0 + host: "%" + retryInterval: 5s +--- +apiVersion: k8s.mariadb.com/v1alpha1 +kind: Grant +metadata: + name: octavia-grant + namespace: openstack +spec: + mariaDbRef: + name: mariadb # name of the MariaDB kind + waitForIt: true + privileges: + - "ALL" + database: "octavia" + table: "*" + username: octavia + grantOption: true + host: "%" + retryInterval: 5s diff --git a/components/octavia/octavia-rabbitmq-queue.yaml b/components/octavia/octavia-rabbitmq-queue.yaml new file mode 100644 index 000000000..2f73b448e --- /dev/null +++ b/components/octavia/octavia-rabbitmq-queue.yaml @@ -0,0 +1,76 @@ +--- +apiVersion: rabbitmq.com/v1beta1 +kind: User +metadata: + name: octavia + namespace: openstack +spec: + tags: + - management # available tags are 'management', 'policymaker', 'monitoring' and 'administrator' + - policymaker + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack + importCredentialsSecret: + name: octavia-rabbitmq-password +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Vhost +metadata: + name: octavia-vhost + namespace: openstack +spec: + name: "octavia" # vhost name; required and cannot be updated + defaultQueueType: quorum # default queue type for this vhost; require RabbitMQ version 3.11.12 or above + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Queue +metadata: + name: octavia-queue + namespace: openstack +spec: + name: octavia-qq # name of the queue + vhost: "octavia" # default to '/' if not provided + type: quorum # without providing a queue type, rabbitmq creates a classic queue + autoDelete: false + durable: true # setting 'durable' to false means this queue won't survive a server restart + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Permission +metadata: + name: octavia-permission + namespace: openstack +spec: + vhost: "octavia" # name of a vhost + userReference: + name: "octavia" # name of a user.rabbitmq.com in the same namespace; must specify either spec.userReference or spec.user + permissions: + write: ".*" + configure: ".*" + read: ".*" + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack +--- +apiVersion: rabbitmq.com/v1beta1 +kind: Policy +metadata: + name: octavia-notifications-ttl + namespace: openstack +spec: + name: octavia-notifications-ttl # name of the policy + vhost: "octavia" # default to '/' if not provided + pattern: "^notifications.*" # regex used to match queues and exchanges + applyTo: "queues" # set to 'queues', 'exchanges', or 'all' + priority: 1 # defaults to 0 + definition: # policy definition + message-ttl: 86400000 + rabbitmqClusterReference: + name: rabbitmq # rabbitmqCluster must exist in the same namespace as this resource + namespace: openstack diff --git a/components/octavia/values.yaml b/components/octavia/values.yaml new file mode 100644 index 000000000..f82c761eb --- /dev/null +++ b/components/octavia/values.yaml @@ -0,0 +1,125 @@ +--- + +# typically overridden by environmental +# values, but should include all endpoints +# required by this chart +endpoints: + oslo_messaging: + statefulset: + replicas: 3 + name: rabbitmq-server + hosts: + default: rabbitmq-nodes + load_balancer: + port: + api: + public: 443 + scheme: + public: https + host_fqdn_override: + public: + tls: + secretName: octavia-tls-public + issuerRef: + name: understack-cluster-issuer + kind: ClusterIssuer + +network: + # configure OpenStack Helm to use Undercloud's ingress + # instead of expecting the ingress controller provided + # by OpenStack Helm + use_external_ingress_controller: true + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + # set our default issuer + cert-manager.io/cluster-issuer: understack-cluster-issuer + external_policy_local: false + node_port: + enabled: false + +conf: + octavia: + api_settings: + enabled_provider_drivers: >- + ovn: "The Octavia OVN driver", + default_provider_driver: ovn + driver_agent: + enabled_provider_agents: ovn + ovn: + ovn_nb_connection: tcp:ovn-ovsdb-nb.openstack.svc.cluster.local:6641 + ovn_sb_connection: tcp:ovn-ovsdb-sb.openstack.svc.cluster.local:6642 + +dependencies: + dynamic: + common: + local_image_registry: + jobs: null + static: + api: + jobs: + - octavia-db-sync + - octavia-ks-user + - octavia-ks-endpoints + worker: + jobs: + - octavia-db-sync + - octavia-ks-user + - octavia-ks-endpoints + housekeeping: + jobs: + - octavia-db-sync + - octavia-ks-user + - octavia-ks-endpoints + health_manager: + jobs: + - octavia-db-sync + - octavia-ks-user + - octavia-ks-endpoints + db_sync: + jobs: + +manifests: + job_db_init: false + job_rabbit_init: false + pod_rally_test: false + secret_db: true + secret_keystone: true + service_ingress_api: false + +# we don't want to enable OpenStack Helm's +# helm.sh/hooks because they set them as +# post-install,post-upgrade which in ArgoCD +# maps to PostSync. However the deployments +# and statefulsets in OpenStack Helm +# depend on the jobs to complete to become +# healthy. Which they cannot because they are in +# the post step and not in the main step. +# Turning this on results in the keys jobs +# editing the annotation which deletes the item +# and wipes our keys. +helm3_hook: false + +annotations: + job: + octavia_db_sync: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-options: Replace=true + octavia_ks_service: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-options: Replace=true + octavia_ks_user: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-options: Replace=true + octavia_ks_endpoints: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-options: Replace=true + octavia_bootstrap: + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation + argocd.argoproj.io/sync-options: Replace=true diff --git a/components/openstack-secrets.tpl.yaml b/components/openstack-secrets.tpl.yaml index 574d465c0..d6c686ff9 100644 --- a/components/openstack-secrets.tpl.yaml +++ b/components/openstack-secrets.tpl.yaml @@ -31,6 +31,9 @@ endpoints: # this user is the service account that cinder uses cinder: password: "${CINDER_KEYSTONE_PASSWORD}" + # this user is the service account that octavia uses + octavia: + password: "${OCTAVIA_KEYSTONE_PASSWORD}" # set our public facing URL host_fqdn_override: @@ -70,6 +73,9 @@ endpoints: # this is what the cinder service uses to connect to MariaDB cinder: password: "${CINDER_DB_PASSWORD}" + # this is what the octavia service uses to connect to MariaDB + octavia: + password: "${OCTAVIA_DB_PASSWORD}" # 'oslo_db_api' is for MariaDB specific for nova oslo_db_api: @@ -104,6 +110,9 @@ endpoints: # this is what the cinder service uses to connect to RabbitMQ cinder: password: "${CINDER_RABBITMQ_PASSWORD}" + # this is what the octavia service uses to connect to RabbitMQ + octavia: + password: "${OCTAVIA_RABBITMQ_PASSWORD}" # 'baremetal' is the ironic service baremetal: @@ -153,4 +162,10 @@ endpoints: host_fqdn_override: public: host: cinder.${DNS_ZONE} + # 'octavia' is the load balancer service + load_balancer: + # set our public facing URL + host_fqdn_override: + public: + host: octavia.${DNS_ZONE} ... diff --git a/containers/octavia/Dockerfile b/containers/octavia/Dockerfile new file mode 100644 index 000000000..60d8b0007 --- /dev/null +++ b/containers/octavia/Dockerfile @@ -0,0 +1,15 @@ +# syntax=docker/dockerfile:1 + +ARG OPENSTACK_VERSION="required_argument" +FROM quay.io/airshipit/octavia:${OPENSTACK_VERSION}-ubuntu_jammy + +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + patch \ + quilt \ + libunbound-dev \ + libunwind-dev \ + python3-unbound \ + && apt-get clean && rm -rf /var/lib/apt/lists/* + +RUN pip install -U ovn-octavia-provider ovsdbapp diff --git a/scripts/gitops-secrets-gen.sh b/scripts/gitops-secrets-gen.sh index 93653b35a..3ae6145dc 100755 --- a/scripts/gitops-secrets-gen.sh +++ b/scripts/gitops-secrets-gen.sh @@ -299,7 +299,7 @@ create_os_secret() { ## OpenStack component secret generation ## each openstack component is very similar to collapse this ## into a loop to generate the same thing for each -for component in keystone ironic placement neutron nova glance cinder; do +for component in keystone ironic placement neutron nova glance cinder octavia; do echo "Checking ${component}" mkdir -p "${DEST_DIR}/${component}/" # keystone service account username