[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:
- You need a deployment that uses IPv6 only for the data plane.
- Create a OpenStack instance (or pick a existing one)
- Get an noVNC link, e.g.:
openstack console url show <instance> - 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:
- Apply a manifest or change a
NovaDeploymentto specifyspec.compute.configTemplates.nodeSelectors[].novaComputeConfig.vnc.server_listento e.g.::1 - Check
NovaComputenode 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.