Skip to content

[vnc]/server_listen is hardcoded to 0.0.0.0, breaking VNC in IPv6-only setups

Summary

noVNC console for deployments using IPv6 only for the data plane does not work. One can get a noVNC link, open it in a browser but after a few seconds the error message

Something went wrong, connection is closed

is presented to the user.

Detailed Description

For noVNC console and KVM, the qemu processes of the OpenStack instances will listen on port, e.g. 0.0.0.0:5xxx. The noVNC proxy service of Nova will connect to <compute-node-address>:5xxx, in order to serve that noVNC console to the user. However, on IPv6 deployments, <compute-node-address> will be an IPv6 address. Thus the VNC server of the corresponding qemu process is not reachable (because it is listening on IPv4 only).

This can be changed by setting [vnc]/server_listen to something like ::. However when trying to change that configuration parameter via NovaDeployment manifest, the ComputeNodes end up in ReconcileFailed. Example output of kubectl describe:

Status:
  Conditions:
    Last Transition Time:  2025-03-05T12:36:17Z
    Last Update Time:      2025-03-05T12:44:57Z
    Message:               cuelang output: Cue: stderr: conf.vnc.server_listen: 1 errors in empty disjunction:
conf.vnc.server_listen: conflicting values "::1" and "0.0.0.0":
    ./input.cue:7:5
    ./input.cue:30:16
    ./pkg/yaook.cloud/novacompute/defaults.cue:100:18
. 
Template content: 
import (
    "yaook.cloud/novacompute"
)

conf: {
    novacompute.novacompute_conf_spec
DEFAULT: {
debug: false
disk_allocation_ratio: 1
enable_instance_password: false
instance_usage_audit: true
instance_usage_audit_period: "hour"
ram_allocation_ratio: 1
source_is_ipv6: true
}
keystone_authtoken: {
os_region_name: "conway"
}
notifications: {
notify_on_state_change: "vm_and_task_state"
}
os_vif_ovs: {
ovsdb_connection: "unix:/run/openvswitch/db.sock"
}
oslo_messaging_notifications: {
driver: ["messagingv2"]
}
vnc: {
server_listen: "::1"
}
libvirt: {
inject_key: false
inject_partition: -2
inject_password: false
live_migration_permit_auto_converge: true
virt_type: "kvm"
}
DEFAULT: {
cpu_allocation_ratio: 4
}
vnc: {
novncproxy_base_url: "https://vnc.api.iaas.conway.qa.stoi.sx.stackit.cloud/vnc_lite.html"
}
keystone_authtoken: {
auth_type: "password"
username: "nova-compute-cmp-pedu-6768-r6w6b.yaook.cluster.local"
password: "-gEy0V_urgpZZ41cOxBUR4dhwBQ8LsogdzY3vUSCjRsaA1!"
project_name: "service"
project_domain_name: "Default"
user_domain_name: "Default"
}
keystone_authtoken: {
valid_interfaces: ["internal"]
auth_url: "https://keystone.yaook.svc:5000/v3"
auth_version: "3"
interface: "internal"
}
cinder: {
auth_type: "password"
username: "nova-compute-cmp-pedu-6768-r6w6b.yaook.cluster.local"
password: "-gEy0V_urgpZZ41cOxBUR4dhwBQ8LsogdzY3vUSCjRsaA1!"
project_name: "service"
project_domain_name: "Default"
user_domain_name: "Default"
}
cinder: {
valid_interfaces: ["internal"]
auth_url: "https://keystone.yaook.svc:5000/v3"
auth_version: "3"
}
neutron: {
auth_type: "password"
username: "nova-compute-cmp-pedu-6768-r6w6b.yaook.cluster.local"
password: "-gEy0V_urgpZZ41cOxBUR4dhwBQ8LsogdzY3vUSCjRsaA1!"
project_name: "service"
project_domain_name: "Default"
user_domain_name: "Default"
}
neutron: {
valid_interfaces: ["internal"]
auth_url: "https://keystone.yaook.svc:5000/v3"
auth_version: "3"
}
placement: {
auth_type: "password"
username: "nova-compute-cmp-pedu-6768-r6w6b.yaook.cluster.local"
password: "-gEy0V_urgpZZ41cOxBUR4dhwBQ8LsogdzY3vUSCjRsaA1!"
project_name: "service"
project_domain_name: "Default"
user_domain_name: "Default"
}
placement: {
valid_interfaces: ["internal"]
auth_url: "https://keystone.yaook.svc:5000/v3"
auth_version: "3"
}
keystone_authtoken: {
memcache_servers: ["inet6:[nova-hkx9q-cache-0.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-1.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-2.nova-hkx9q-cache.yaook.svc]:11211"]
memcached_servers: ["inet6:[nova-hkx9q-cache-0.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-1.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-2.nova-hkx9q-cache.yaook.svc]:11211"]
}
cache: {
memcache_servers: ["inet6:[nova-hkx9q-cache-0.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-1.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-2.nova-hkx9q-cache.yaook.svc]:11211"]
memcached_servers: ["inet6:[nova-hkx9q-cache-0.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-1.nova-hkx9q-cache.yaook.svc]:11211", "inet6:[nova-hkx9q-cache-2.nova-hkx9q-cache.yaook.svc]:11211"]
}
DEFAULT: {
#transport_url_hosts: ["nova-nova-cell1-mq-frontend.yaook"]
#transport_url_username: "compute-cmp-pedu-6768"
#transport_url_password: "wMjIdOmbeIRnEFASjMWS3Xbd87wjiMzhZ73ENwW9bD0aA1!"
#transport_url_vhost: ""
}
keystone_authtoken: {
region_name: "conway"
os_region_name: "conway"
}
glance: {
region_name: "conway"
os_region_name: "conway"
}
cinder: {
region_name: "conway"
os_region_name: "conway"
}
neutron: {
region_name: "conway"
os_region_name: "conway"
}
placement: {
region_name: "conway"
os_region_name: "conway"
}

The conflict seems to originate from the configuration parameter hard coded here.

Steps to reproduce the issue

To reproduce the error shown by the noVNC console:

  1. You need a deployment that uses IPv6 only for the data plane.
  2. Create a OpenStack instance (or pick a existing one)
  3. Get an noVNC link, e.g.: openstack console url show <instance>
  4. Open the link in a browser

You will see the error message:

Something went wrong, connection is closed

To reproduce that changing the configuration parameter [vnc]/server_listen does not work:

  1. Apply a manifest or change a NovaDeployment to specify spec.compute.configTemplates.nodeSelectors[].novaComputeConfig.vnc.server_listen to e.g. ::1
  2. Check NovaCompute node resources or Nova operator logs to find the above shown error.

Result

Configuration is not applied. NovaDeployment resources end up in ReconcileFailed.

Expected Result

The configuration change should be end up in /etc/nova/nova.conf in the Nova compute pods.

Proposal

To not hard code the value of [vnc]/server_listen via CUE. Instead specify the current hard coded value as default and allow to override via NovaCompute resource.

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this issue are to be interpreted in the spirit of RFC 2119, even though we're not technically doing protocol design.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information