Deploy Neutron
Run the Neutron deployment Script /opt/genestack/bin/install-neutron.sh
#!/bin/bash
# Description: Fetches the version for SERVICE_NAME from the specified
# YAML file and executes a helm upgrade/install command with dynamic values files.
# Disable SC2124 (unused array), SC2145 (array expansion issue), SC2294 (eval)
# shellcheck disable=SC2124,SC2145,SC2294
# Service
SERVICE_NAME="neutron"
SERVICE_NAMESPACE="openstack"
# Helm
HELM_REPO_NAME="openstack-helm"
HELM_REPO_URL="https://tarballs.opendev.org/openstack/openstack-helm"
# Base directories provided by the environment
GENESTACK_BASE_DIR="${GENESTACK_BASE_DIR:-/opt/genestack}"
GENESTACK_OVERRIDES_DIR="${GENESTACK_OVERRIDES_DIR:-/etc/genestack}"
# Define service-specific override directories based on the framework
SERVICE_BASE_OVERRIDES="${GENESTACK_BASE_DIR}/base-helm-configs/${SERVICE_NAME}"
SERVICE_CUSTOM_OVERRIDES="${GENESTACK_OVERRIDES_DIR}/helm-configs/${SERVICE_NAME}"
GLOBAL_OVERRIDES_DIR="${GENESTACK_OVERRIDES_DIR}/helm-configs/global_overrides"
# Read the desired chart version from VERSION_FILE
VERSION_FILE="/etc/genestack/helm-chart-versions.yaml"
if [ ! -f "$VERSION_FILE" ]; then
echo "Error: helm-chart-versions.yaml not found at $VERSION_FILE" >&2
exit 1
fi
# Extract version dynamically using the SERVICE_NAME variable
SERVICE_VERSION=$(grep "^[[:space:]]*${SERVICE_NAME}:" "$VERSION_FILE" | sed "s/.*${SERVICE_NAME}: *//")
if [ -z "$SERVICE_VERSION" ]; then
echo "Error: Could not extract version for '$SERVICE_NAME' from $VERSION_FILE" >&2
exit 1
fi
echo "Found version for $SERVICE_NAME: $SERVICE_VERSION"
# Prepare an array to collect -f arguments
overrides_args=()
# Include all YAML files from the BASE configuration directory
# NOTE: Files in this directory are included first.
if [[ -d "$SERVICE_BASE_OVERRIDES" ]]; then
echo "Including base overrides from directory: $SERVICE_BASE_OVERRIDES"
for file in "$SERVICE_BASE_OVERRIDES"/*.yaml; do
# Check that there is at least one match
if [[ -e "$file" ]]; then
echo " - $file"
overrides_args+=("-f" "$file")
fi
done
else
echo "Warning: Base override directory not found: $SERVICE_BASE_OVERRIDES"
fi
# Include all YAML files from the GLOBAL configuration directory
# NOTE: Files here override base settings and are applied before service-specific ones.
if [[ -d "$GLOBAL_OVERRIDES_DIR" ]]; then
echo "Including overrides from global config directory:"
for file in "$GLOBAL_OVERRIDES_DIR"/*.yaml; do
if [[ -e "$file" ]]; then
echo " - $file"
overrides_args+=("-f" "$file")
fi
done
else
echo "Warning: Global config directory not found: $GLOBAL_OVERRIDES_DIR"
fi
# Include all YAML files from the custom SERVICE configuration directory
# NOTE: Files here have the highest precedence.
if [[ -d "$SERVICE_CUSTOM_OVERRIDES" ]]; then
echo "Including overrides from service config directory:"
for file in "$SERVICE_CUSTOM_OVERRIDES"/*.yaml; do
if [[ -e "$file" ]]; then
echo " - $file"
overrides_args+=("-f" "$file")
fi
done
else
echo "Warning: Service config directory not found: $SERVICE_CUSTOM_OVERRIDES"
fi
echo
# --- Helm Repository and Execution ---
helm repo add "$HELM_REPO_NAME" "$HELM_REPO_URL"
helm repo update
# Collect all --set arguments, executing commands and quoting safely
# NOTE: This array contains OpenStack-specific secret retrievals and MUST be updated
# with the necessary --set arguments for your target SERVICE_NAME.
set_args=(
# Metadata proxy secret
--set "conf.metadata_agent.DEFAULT.metadata_proxy_shared_secret=$(kubectl --namespace openstack get secret metadata-shared-secret -o jsonpath='{.data.password}' | base64 -d)"
--set "conf.ovn_metadata_agent.DEFAULT.metadata_proxy_shared_secret=$(kubectl --namespace openstack get secret metadata-shared-secret -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.admin.password=$(kubectl --namespace openstack get secret keystone-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.neutron.password=$(kubectl --namespace openstack get secret neutron-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.nova.password=$(kubectl --namespace openstack get secret nova-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.placement.password=$(kubectl --namespace openstack get secret placement-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.designate.password=$(kubectl --namespace openstack get secret designate-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.identity.auth.ironic.password=$(kubectl --namespace openstack get secret ironic-admin -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.oslo_db.auth.admin.password=$(kubectl --namespace openstack get secret mariadb -o jsonpath='{.data.root-password}' | base64 -d)"
--set "endpoints.oslo_db.auth.neutron.password=$(kubectl --namespace openstack get secret neutron-db-password -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.oslo_cache.auth.memcache_secret_key=$(kubectl --namespace openstack get secret os-memcached -o jsonpath='{.data.memcache_secret_key}' | base64 -d)"
--set "conf.neutron.keystone_authtoken.memcache_secret_key=$(kubectl --namespace openstack get secret os-memcached -o jsonpath='{.data.memcache_secret_key}' | base64 -d)"
--set "endpoints.oslo_messaging.auth.admin.password=$(kubectl --namespace openstack get secret rabbitmq-default-user -o jsonpath='{.data.password}' | base64 -d)"
--set "endpoints.oslo_messaging.auth.neutron.password=$(kubectl --namespace openstack get secret neutron-rabbitmq-password -o jsonpath='{.data.password}' | base64 -d)"
--set "conf.neutron.ovn.ovn_nb_connection=tcp:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')"
--set "conf.neutron.ovn.ovn_sb_connection=tcp:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')"
--set "conf.plugins.ml2_conf.ovn.ovn_nb_connection=tcp:$(kubectl --namespace kube-system get service ovn-nb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')"
--set "conf.plugins.ml2_conf.ovn.ovn_sb_connection=tcp:$(kubectl --namespace kube-system get service ovn-sb -o jsonpath='{.spec.clusterIP}:{.spec.ports[0].port}')"
)
helm_command=(
helm upgrade --install "$SERVICE_NAME" "$HELM_REPO_NAME/$SERVICE_NAME"
--version "${SERVICE_VERSION}"
--namespace="$SERVICE_NAMESPACE"
--timeout 120m
--create-namespace
"${overrides_args[@]}"
"${set_args[@]}"
# Post-renderer configuration
--post-renderer "$GENESTACK_OVERRIDES_DIR/kustomize/kustomize.sh"
--post-renderer-args "$SERVICE_NAME/overlay"
"$@"
)
echo "Executing Helm command (arguments are quoted safely):"
printf '%q ' "${helm_command[@]}"
echo
# Execute the command directly from the array
"${helm_command[@]}"
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.
Info
The above command derives the OVN north/south bound database from our K8S environment. The insert set is making the assumption we're using tcp to connect.
Neutron MTU settings / Jumbo frames / overlay networks on instances
!!! warning You will likely need to increase the MTU as described here if you want to support creating L3 overlay networks (via any software that creates nested networks, such as Genestack itself, VPN, etc.) on your nova instances. Your physical L2 network will need jumbo frames to support this. You will likely end up with an MTU of 1280 for overlay networks on instances if you don't, and the abnormally small MTU can cause various problems, perhaps even reaching a size too small for the software to support).
Neutron documentation on MTU considerations
As an example of changing some values of interest, in a file for your Neutron Helm overrides, you can use a stanza like:
conf:
neutron:
DEFAULT:
global_physnet_mtu: 9000
plugins:
ml2_conf:
ml2:
path_mtu: 4000
physical_network_mtus: physnet1:1500
(You can see the Neutron helm overrides file in the installation command above
as -f /etc/genestack/helm-configs/neutron/neutron-helm-overrides.yaml,
but you can supply this information with a second -f switch in a separate
overrides file for your environment if desired. If so, place your second
-f after the first.)
With the settings in the example, physical networks get a default MTU of 9000 in
global_physnet_mtu. You can override this for specific networks in
physical_network_mtus, which shows physnet1 with an MTU of 1500 here, which
handles public Internet traffic in this case, which shouldn't get jumbo frames.
path_mtu sets the MTU for tenant or project networks. For path_mtu 4000 in
the example, nova instances will get an MTU of 3942 after 58 bytes of overhead.