Skip to content

Deploy Octavia

OpenStack Octavia is the load balancing service within the OpenStack ecosystem, providing scalable and automated load balancing for cloud applications. Octavia is designed to ensure high availability and reliability by distributing incoming network traffic across multiple instances of an application, preventing any single instance from becoming a bottleneck or point of failure. It supports various load balancing algorithms, health monitoring, and SSL termination, making it a versatile tool for managing traffic within cloud environments. In this document, we will explore the deployment of OpenStack Octavia using Genestack. By leveraging Genestack, the deployment of Octavia is streamlined, ensuring that load balancing is seamlessly incorporated into both private and public cloud environments, enhancing the performance and resilience of cloud applications.

Create secrets

Information about the secretes used

Manual secret generation is only required if you haven't run the create-secrets.sh script located in /opt/genestack/bin.

Example secret generation
kubectl --namespace openstack \
        create secret generic octavia-rabbitmq-password \
        --type Opaque \
        --from-literal=username="octavia" \
        --from-literal=password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-64};echo;)"
kubectl --namespace openstack \
        create secret generic octavia-db-password \
        --type Opaque \
        --from-literal=password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)"
kubectl --namespace openstack \
        create secret generic octavia-admin \
        --type Opaque \
        --from-literal=password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)"
kubectl --namespace openstack \
        create secret generic octavia-certificates \
        --type Opaque \
        --from-literal=password="$(< /dev/urandom tr -dc _A-Za-z0-9 | head -c${1:-32};echo;)"

Prerequisite

Before you can deploy octavia, it requires a few things to be setup ahead of time:

  • Quota check/update
  • Certificate creation
  • Security group configuration
  • Amphora management network
  • Port creation for health manager pods
  • Amphora image creation
  • and more

In order to automate these tasks, we have provided an ansible role and a playbook. The playbook, octavia-preconf-main.yaml, is located in the ansible/playbook directory. You will need to update the variables in the playbook to match your deployment.

Make sure to udpate the octavia-preconf-main.yaml with the correct region, auth url, and password.

Tip

The playbook requires a few pip packages to run properly. While the dependencies for this playbook should be installed by default, the playbook runtime can be isolated in a virtualenv if needed.

Example

apt-get install python3-venv python3-pip
mkdir -p ~/.venvs
python3 -m venv --system-site-packages ~/.venvs/octavia_preconf
source .venvs/octavia_preconf/bin/activate
pip install --upgrade pip
pip install "ansible>=2.9" "openstacksdk>=1.0.0" "python-openstackclient==6.2.0" kubernetes

Review the role values

The default values are in /opt/genestack/ansible/playbooks/roles/octavia_preconf/defaults/main.yml

Review the settings and adjust as necessary. Depending on the size of your cluster, you may want to adjust the lb_mgmt_subnet settings or block icmp and ssh access to the amphora vms.

Run the playbook

You can get the Keystone url and region with the following command.

openstack --os-cloud=default endpoint list --service keystone --interface public -c Region -c URL -f value

You can get the admin password by using kubectl.

kubectl get secrets keystone-admin -n openstack -o jsonpath='{.data.password}' | base64 -d

Run the playbook

cd /opt/genestack/ansible/playbooks
ansible-playbook octavia-preconf-main.yaml

Dynamic values

Running the playbook can be fully dynamic by using the following command:

Run the playbook with dynamic values

ansible-playbook /opt/genestack/ansible/playbooks/octavia-preconf-main.yaml \
                -e octavia_os_password=$(kubectl get secrets keystone-admin -n openstack -o jsonpath='{.data.password}' | base64 -d) \
                -e octavia_os_region_name=$(openstack --os-cloud=default endpoint list --service keystone --interface public -c Region -f value) \
                -e octavia_os_auth_url=$(openstack --os-cloud=default endpoint list --service keystone --interface public -c URL -f value)

Once everything is complete, a new file will be created in your home directory called octavia_amphora_provider.yaml, this file contains the necessary information to deploy Octavia via helm. Move this file into the /etc/genestack/helm-configs/octavia directory to have it automatically included when running the Octavia deployment script.

mv ~/octavia_amphora_provider.yaml /etc/genestack/helm-configs/octavia/

Run the Helm deployment

Run the Octavia deployment Script /opt/genestack/bin/install-octavia.sh

#!/bin/bash

GLOBAL_OVERRIDES_DIR="/etc/genestack/helm-configs/global_overrides"
SERVICE_CONFIG_DIR="/etc/genestack/helm-configs/octavia"
BASE_OVERRIDES="/opt/genestack/base-helm-configs/octavia/octavia-helm-overrides.yaml"

pushd /opt/genestack/submodules/openstack-helm || exit 1

HELM_CMD="helm upgrade --install octavia openstack-helm/octavia --version 2024.2.30+13651f45-628a320c \
    --namespace=openstack \
    --timeout 120m"

HELM_CMD+=" -f ${BASE_OVERRIDES}"

for dir in "$GLOBAL_OVERRIDES_DIR" "$SERVICE_CONFIG_DIR"; do
  if compgen -G "${dir}/*.yaml" > /dev/null; then
    for yaml_file in "${dir}"/*.yaml; do
      # Avoid re-adding the base override file if it appears in the service directory
      if [ "${yaml_file}" != "${BASE_OVERRIDES}" ]; then
        HELM_CMD+=" -f ${yaml_file}"
      fi
    done
  fi
done

HELM_CMD+=" --set endpoints.identity.auth.admin.password=\"\$(kubectl --namespace openstack get secret keystone-admin -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.identity.auth.octavia.password=\"\$(kubectl --namespace openstack get secret octavia-admin -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.oslo_db.auth.admin.password=\"\$(kubectl --namespace openstack get secret mariadb -o jsonpath='{.data.root-password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.oslo_db.auth.octavia.password=\"\$(kubectl --namespace openstack get secret octavia-db-password -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.oslo_messaging.auth.admin.password=\"\$(kubectl --namespace openstack get secret rabbitmq-default-user -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.oslo_messaging.auth.octavia.password=\"\$(kubectl --namespace openstack get secret octavia-rabbitmq-password -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set endpoints.oslo_cache.auth.memcache_secret_key=\"\$(kubectl --namespace openstack get secret os-memcached -o jsonpath='{.data.memcache_secret_key}' | base64 -d)\""
HELM_CMD+=" --set conf.octavia.keystone_authtoken.memcache_secret_key=\"\$(kubectl --namespace openstack get secret os-memcached -o jsonpath='{.data.memcache_secret_key}' | base64 -d)\""
HELM_CMD+=" --set conf.octavia.database.slave_connection=\"mysql+pymysql://octavia:\$(kubectl --namespace openstack get secret octavia-db-password -o jsonpath='{.data.password}' | base64 -d)@mariadb-cluster-secondary.openstack.svc.cluster.local:3306/octavia\""
HELM_CMD+=" --set conf.octavia.certificates.ca_private_key_passphrase=\"\$(kubectl --namespace openstack get secret octavia-certificates -o jsonpath='{.data.password}' | base64 -d)\""
HELM_CMD+=" --set conf.octavia.ovn.ovn_nb_connection=\"tcp:\$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')\""
HELM_CMD+=" --set conf.octavia.ovn.ovn_sb_connection=\"tcp:\$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')\""

HELM_CMD+=" --post-renderer /etc/genestack/kustomize/kustomize.sh"
HELM_CMD+=" --post-renderer-args octavia/overlay $*"

helm repo add openstack-helm https://tarballs.opendev.org/openstack/openstack-helm
helm repo update

echo "Executing Helm command:"
echo "${HELM_CMD}"
eval "${HELM_CMD}"

popd || exit 1

Make sure to include the file when you run the script by adding a -f /<HOME_DIRECTORY>/octavia_amphora_provider.yaml

Example

/opt/genestack/bin/install-octavia.sh

Tip

You may need to provide custom values to configure your openstack services, for a simple single region or lab deployment you can supply an additional overrides flag using the example found at base-helm-configs/aio-example-openstack-overrides.yaml. In other cases such as a multi-region deployment you may want to view the Multi-Region Support guide to for a workflow solution.

Demo

asciicast