From 9d69fd8c36c6cd5055781c9514d03b197197489c Mon Sep 17 00:00:00 2001 From: Nicholas Kuechler Date: Fri, 6 Mar 2026 11:38:26 -0600 Subject: [PATCH] feat(nova): Allow users to set 'host' for scheduler and conductor services Allows users to set custom 'host' values for nova conductor and scheduler services. This may be useful for kubernetes users, where new deploys of scheduler and conductor use the pod names, leaaving stale compute service entries which are eventually cleaned by the nova-service-cleaner job. Ref: https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.host Change-Id: Ib790d04c1fe8cd623b42c719e67861b0eeec341a Signed-off-by: Nicholas Kuechler --- nova/templates/bin/_health-probe.py.tpl | 3 + nova/templates/bin/_nova-conductor.sh.tpl | 1 + nova/templates/deployment-conductor.yaml | 2 +- nova/templates/deployment-scheduler.yaml | 2 +- nova/templates/statefulset-conductor.yaml | 189 ++++++++++++++++++ nova/templates/statefulset-scheduler.yaml | 189 ++++++++++++++++++ nova/values.yaml | 6 + releasenotes/notes/nova-69cb1a01b6f5c561.yaml | 9 + 8 files changed, 399 insertions(+), 2 deletions(-) create mode 100644 nova/templates/statefulset-conductor.yaml create mode 100644 nova/templates/statefulset-scheduler.yaml create mode 100644 releasenotes/notes/nova-69cb1a01b6f5c561.yaml diff --git a/nova/templates/bin/_health-probe.py.tpl b/nova/templates/bin/_health-probe.py.tpl index 384f99c5c3..c8fa0c7fa1 100644 --- a/nova/templates/bin/_health-probe.py.tpl +++ b/nova/templates/bin/_health-probe.py.tpl @@ -53,6 +53,9 @@ tcp_established = "ESTABLISHED" def _get_hostname(topic, use_fqdn): + configured_host = cfg.CONF.host + if configured_host: + return configured_host if use_fqdn and topic == "compute": return socket.getfqdn() return socket.gethostname() diff --git a/nova/templates/bin/_nova-conductor.sh.tpl b/nova/templates/bin/_nova-conductor.sh.tpl index bb04f2b495..30d28c43b2 100644 --- a/nova/templates/bin/_nova-conductor.sh.tpl +++ b/nova/templates/bin/_nova-conductor.sh.tpl @@ -15,6 +15,7 @@ limitations under the License. */}} set -x + exec nova-conductor \ --config-file /etc/nova/nova.conf \ --config-dir /etc/nova/nova.conf.d diff --git a/nova/templates/deployment-conductor.yaml b/nova/templates/deployment-conductor.yaml index be21012aff..b91ab5dc59 100644 --- a/nova/templates/deployment-conductor.yaml +++ b/nova/templates/deployment-conductor.yaml @@ -39,7 +39,7 @@ exec: - conductor {{- end }} -{{- if .Values.manifests.deployment_conductor }} +{{- if and .Values.manifests.deployment_conductor (not .Values.manifests.statefulset_conductor) }} {{- $envAll := . }} {{- $mounts_nova_conductor := .Values.pod.mounts.nova_conductor.nova_conductor }} diff --git a/nova/templates/deployment-scheduler.yaml b/nova/templates/deployment-scheduler.yaml index 26e8a621db..25742c64fb 100644 --- a/nova/templates/deployment-scheduler.yaml +++ b/nova/templates/deployment-scheduler.yaml @@ -39,7 +39,7 @@ exec: - scheduler {{- end }} -{{- if .Values.manifests.deployment_scheduler }} +{{- if and .Values.manifests.deployment_scheduler (not .Values.manifests.statefulset_scheduler) }} {{- $envAll := . }} {{- $mounts_nova_scheduler := .Values.pod.mounts.nova_scheduler.nova_scheduler }} diff --git a/nova/templates/statefulset-conductor.yaml b/nova/templates/statefulset-conductor.yaml new file mode 100644 index 0000000000..6985218e3a --- /dev/null +++ b/nova/templates/statefulset-conductor.yaml @@ -0,0 +1,189 @@ +{{/* +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. +*/}} + +{{- define "novaConductorLivenessProbeTemplate" }} +exec: + command: + - python + - /tmp/health-probe.py + - --config-file + - /etc/nova/nova.conf + - --config-dir + - /etc/nova/nova.conf.d + - --service-queue-name + - conductor + - --liveness-probe +{{- end }} + +{{- define "novaConductorReadinessProbeTemplate" }} +exec: + command: + - python + - /tmp/health-probe.py + - --config-file + - /etc/nova/nova.conf + - --config-dir + - /etc/nova/nova.conf.d + - --service-queue-name + - conductor +{{- end }} + +{{- if .Values.manifests.statefulset_conductor }} +{{- $envAll := . }} + +{{- $mounts_nova_conductor := .Values.pod.mounts.nova_conductor.nova_conductor }} +{{- $mounts_nova_conductor_init := .Values.pod.mounts.nova_conductor.init_container }} +{{- $etcSources := .Values.pod.etcSources.nova_conductor }} +{{- if eq .Values.manifests.secret_ks_etc true }} +{{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} +{{- end }} + +{{- $serviceAccountName := "nova-conductor" }} +{{ tuple $envAll "conductor" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: nova-conductor + annotations: + {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} + labels: +{{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + serviceName: nova-conductor + replicas: {{ .Values.pod.replicas.conductor }} + selector: + matchLabels: +{{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + podManagementPolicy: Parallel +{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} + template: + metadata: + labels: +{{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + annotations: +{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} + configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} + configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} +{{ tuple "nova_conductor" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} +{{ dict "envAll" $envAll "podName" "nova-conductor" "containerNames" (list "nova-conductor" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} + spec: +{{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} +{{ tuple "nova_conductor" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} + serviceAccountName: {{ $serviceAccountName }} +{{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} + affinity: +{{ tuple $envAll "nova" "conductor" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.conductor.node_selector_key }}: {{ .Values.labels.conductor.node_selector_value }} +{{ if $envAll.Values.pod.tolerations.nova.enabled }} +{{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} +{{ end }} + initContainers: +{{ tuple $envAll "conductor" $mounts_nova_conductor_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: nova-conductor +{{ tuple $envAll "nova_conductor" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} +{{ dict "envAll" $envAll "application" "nova" "container" "nova_conductor" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} +{{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "liveness" "probeTemplate" (include "novaConductorLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} +{{ dict "envAll" $envAll "component" "conductor" "container" "default" "type" "readiness" "probeTemplate" (include "novaConductorReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} + env: + - name: RPC_PROBE_TIMEOUT + value: "{{ .Values.pod.probes.rpc_timeout }}" + - name: RPC_PROBE_RETRIES + value: "{{ .Values.pod.probes.rpc_retries }}" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name +{{- if or .Values.manifests.certificates .Values.tls.identity }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} + command: + - /bin/bash + - -c + - | + set -x +{{- if empty .Values.conf.nova.DEFAULT.host }} + # When using StatefulSet, use the pod hostname for stable service names + cat > /tmp/nova-conductor-host.conf << EOF + [DEFAULT] + host = ${HOSTNAME} + EOF + exec nova-conductor --config-file /etc/nova/nova.conf --config-file /tmp/nova-conductor-host.conf --config-dir /etc/nova/nova.conf.d +{{- else }} + exec /tmp/nova-conductor.sh +{{- end }} + volumeMounts: + - name: pod-tmp + mountPath: /tmp + - name: oslo-lock-path + mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} + - name: nova-bin + mountPath: /tmp/nova-conductor.sh + subPath: nova-conductor.sh + readOnly: true + - name: nova-bin + mountPath: /tmp/health-probe.py + subPath: health-probe.py + readOnly: true + - name: nova-etc + mountPath: /etc/nova/nova.conf + subPath: nova.conf + readOnly: true + - name: nova-etc-snippets + mountPath: /etc/nova/nova.conf.d/ + readOnly: true + {{- if .Values.conf.nova.DEFAULT.log_config_append }} + - name: nova-etc + mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} + subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} + readOnly: true + {{- end }} + - name: nova-etc + mountPath: /etc/nova/policy.yaml + subPath: policy.yaml + readOnly: true +{{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" "certs" (tuple "ca.crt") | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{ if $mounts_nova_conductor.volumeMounts }}{{ toYaml $mounts_nova_conductor.volumeMounts | indent 12 }}{{ end }} + volumes: + - name: pod-tmp + emptyDir: {} + - name: oslo-lock-path + emptyDir: {} + - name: nova-bin + configMap: + name: nova-bin + defaultMode: 0555 + - name: nova-etc + secret: + secretName: nova-etc + defaultMode: 0444 + - name: nova-etc-snippets +{{- if $etcSources }} + projected: + sources: +{{ toYaml $etcSources | indent 14 }} +{{- else }} + emptyDir: {} +{{ end }} +{{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{ if $mounts_nova_conductor.volumes }}{{ toYaml $mounts_nova_conductor.volumes | indent 8 }}{{ end }} +{{- end }} diff --git a/nova/templates/statefulset-scheduler.yaml b/nova/templates/statefulset-scheduler.yaml new file mode 100644 index 0000000000..9688538d71 --- /dev/null +++ b/nova/templates/statefulset-scheduler.yaml @@ -0,0 +1,189 @@ +{{/* +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. +*/}} + +{{- define "novaSchedulerLivenessProbeTemplate" }} +exec: + command: + - python + - /tmp/health-probe.py + - --config-file + - /etc/nova/nova.conf + - --config-dir + - /etc/nova/nova.conf.d + - --service-queue-name + - scheduler + - --liveness-probe +{{- end }} + +{{- define "novaSchedulerReadinessProbeTemplate" }} +exec: + command: + - python + - /tmp/health-probe.py + - --config-file + - /etc/nova/nova.conf + - --config-dir + - /etc/nova/nova.conf.d + - --service-queue-name + - scheduler +{{- end }} + +{{- if .Values.manifests.statefulset_scheduler }} +{{- $envAll := . }} + +{{- $mounts_nova_scheduler := .Values.pod.mounts.nova_scheduler.nova_scheduler }} +{{- $mounts_nova_scheduler_init := .Values.pod.mounts.nova_scheduler.init_container }} +{{- $etcSources := .Values.pod.etcSources.nova_scheduler }} +{{- if eq .Values.manifests.secret_ks_etc true }} +{{- $etcSources = append $etcSources (dict "secret" (dict "name" "nova-ks-etc")) }} +{{- end }} + +{{- $serviceAccountName := "nova-scheduler" }} +{{ tuple $envAll "scheduler" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: nova-scheduler + annotations: + {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} + labels: +{{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + serviceName: nova-scheduler + replicas: {{ .Values.pod.replicas.scheduler }} + selector: + matchLabels: +{{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + podManagementPolicy: Parallel +{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_statefulset" | indent 2 }} + template: + metadata: + labels: +{{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + annotations: +{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} + configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} + configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} +{{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} +{{ dict "envAll" $envAll "podName" "nova-scheduler" "containerNames" (list "nova-scheduler" "init") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} + spec: +{{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} +{{ tuple "nova_scheduler" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} + serviceAccountName: {{ $serviceAccountName }} +{{ dict "envAll" $envAll "application" "nova" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} + affinity: +{{ tuple $envAll "nova" "scheduler" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.scheduler.node_selector_key }}: {{ .Values.labels.scheduler.node_selector_value }} +{{ if $envAll.Values.pod.tolerations.nova.enabled }} +{{ tuple $envAll "nova" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} +{{ end }} + initContainers: +{{ tuple $envAll "scheduler" $mounts_nova_scheduler_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: nova-scheduler +{{ tuple $envAll "nova_scheduler" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} +{{ dict "envAll" $envAll "application" "nova" "container" "nova_scheduler" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} +{{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "liveness" "probeTemplate" (include "novaSchedulerLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} +{{ dict "envAll" $envAll "component" "scheduler" "container" "default" "type" "readiness" "probeTemplate" (include "novaSchedulerReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} + env: + - name: RPC_PROBE_TIMEOUT + value: "{{ .Values.pod.probes.rpc_timeout }}" + - name: RPC_PROBE_RETRIES + value: "{{ .Values.pod.probes.rpc_retries }}" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name +{{- if or .Values.manifests.certificates .Values.tls.identity }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} + command: + - /bin/bash + - -c + - | + set -xe +{{- if empty .Values.conf.nova.DEFAULT.host }} + # When using StatefulSet, use the pod hostname for stable service names + cat > /tmp/nova-scheduler-host.conf << EOF + [DEFAULT] + host = ${HOSTNAME} + EOF + exec nova-scheduler --config-file /etc/nova/nova.conf --config-file /tmp/nova-scheduler-host.conf --config-dir /etc/nova/nova.conf.d +{{- else }} + exec /tmp/nova-scheduler.sh +{{- end }} + volumeMounts: + - name: pod-tmp + mountPath: /tmp + - name: oslo-lock-path + mountPath: {{ .Values.conf.nova.oslo_concurrency.lock_path }} + - name: nova-bin + mountPath: /tmp/nova-scheduler.sh + subPath: nova-scheduler.sh + readOnly: true + - name: nova-bin + mountPath: /tmp/health-probe.py + subPath: health-probe.py + readOnly: true + - name: nova-etc + mountPath: /etc/nova/nova.conf + subPath: nova.conf + readOnly: true + - name: nova-etc-snippets + mountPath: /etc/nova/nova.conf.d/ + readOnly: true + {{- if .Values.conf.nova.DEFAULT.log_config_append }} + - name: nova-etc + mountPath: {{ .Values.conf.nova.DEFAULT.log_config_append }} + subPath: {{ base .Values.conf.nova.DEFAULT.log_config_append }} + readOnly: true + {{- end }} + - name: nova-etc + mountPath: /etc/nova/policy.yaml + subPath: policy.yaml + readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{ if $mounts_nova_scheduler.volumeMounts }}{{ toYaml $mounts_nova_scheduler.volumeMounts | indent 12 }}{{ end }} + volumes: + - name: pod-tmp + emptyDir: {} + - name: oslo-lock-path + emptyDir: {} + - name: nova-bin + configMap: + name: nova-bin + defaultMode: 0555 + - name: nova-etc + secret: + secretName: nova-etc + defaultMode: 0444 + - name: nova-etc-snippets +{{- if $etcSources }} + projected: + sources: +{{ toYaml $etcSources | indent 14 }} +{{- else }} + emptyDir: {} +{{ end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{- dict "enabled" (or .Values.manifests.certificates .Values.tls.identity) "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{ if $mounts_nova_scheduler.volumes }}{{ toYaml $mounts_nova_scheduler.volumes | indent 8 }}{{ end }} +{{- end }} diff --git a/nova/values.yaml b/nova/values.yaml index 4dc83eac5d..d0940f5455 100644 --- a/nova/values.yaml +++ b/nova/values.yaml @@ -2711,6 +2711,12 @@ manifests: deployment_serialproxy: true deployment_spiceproxy: true deployment_scheduler: true + # NOTE: StatefulSets provide stable pod hostnames (e.g., nova-conductor-0, nova-conductor-1) + # which are used as service host names in `openstack compute service list`. + # When enabled, the corresponding deployment_* manifest is automatically disabled. + # This ensures service names remain stable across pod restarts. + statefulset_conductor: false + statefulset_scheduler: false ingress_metadata: true ingress_novncproxy: true ingress_serialproxy: true diff --git a/releasenotes/notes/nova-69cb1a01b6f5c561.yaml b/releasenotes/notes/nova-69cb1a01b6f5c561.yaml new file mode 100644 index 0000000000..00597ed42d --- /dev/null +++ b/releasenotes/notes/nova-69cb1a01b6f5c561.yaml @@ -0,0 +1,9 @@ +--- +nova: + - | + Allows users to set custom 'host' values for nova conductor and scheduler + services. This may be useful for kubernetes users, where new deploys of + scheduler and conductor use the pod names, leaaving stale compute service entries + which are eventually cleaned by the nova-service-cleaner job. + Ref: https://docs.openstack.org/nova/latest/configuration/config.html#DEFAULT.host +...