From d650600d3265d2094d98379ae0b9a1697aed1a34 Mon Sep 17 00:00:00 2001 From: Steven Blatzheim Date: Wed, 26 Aug 2026 22:16:02 +0300 Subject: [PATCH 1/3] Add OpenStack server hostID as k8s node label --- .../using-openstack-cloud-controller-manager.md | 4 ++++ pkg/openstack/instances.go | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md b/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md index cdb8663dcd..c888e67659 100644 --- a/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md +++ b/docs/openstack-cloud-controller-manager/using-openstack-cloud-controller-manager.md @@ -358,3 +358,7 @@ Refer to [Metrics for openstack-cloud-controller-manager](../metrics.md) ### OpenStack availability zone must not contain blank `topology.kubernetes.io/zone` is used to label node and its value comes from availability zone of the node, according to [label spec](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set) it does not support blank (' ') but OpenStack availability zone supports blank. So your OpenStack availability zone must not contain blank otherwise it will lead to node that belongs to this availability zone register failure, see [#1379](https://github.com/kubernetes/cloud-provider-openstack/issues/1379) for further information. + +### OpenStack HostID label + +`topology.openstack.org/host-id` is used to label node and its value comes from the host ID. The host ID represents the physical host your server runs on. This is a hashed value so will not actually look like a hostname, and is hashed with data from the project_id, so the same physical host as seen by two different project_ids, will be different. It is useful when within the same project you need to determine if two instances are on the same or different physical hosts for the purposes of availability or performance. Please be aware that real host ID can change in time, e.g. due to live migrations of the nodes, so take this label as only the "initial" host ID because it won't be reconciled. diff --git a/pkg/openstack/instances.go b/pkg/openstack/instances.go index f9b617736f..e3516059ad 100644 --- a/pkg/openstack/instances.go +++ b/pkg/openstack/instances.go @@ -42,6 +42,7 @@ import ( const ( RegionalProviderIDEnv = "OS_CCM_REGIONAL" instanceShutoff = "SHUTOFF" + labelHostID = "topology.openstack.org/host-id" ) // InstancesV2 encapsulates an implementation of InstancesV2 for OpenStack. @@ -147,6 +148,7 @@ func (i *InstancesV2) InstanceMetadata(ctx context.Context, node *v1.Node) (*clo NodeAddresses: addresses, Zone: availabilityZone, Region: i.region, + AdditionalLabels: getAdditionalLabels(&server), }, nil } @@ -285,6 +287,16 @@ func srvInstanceType(ctx context.Context, client *gophercloud.ServiceClient, srv return "", fmt.Errorf("flavor original_name/id not found") } +func getAdditionalLabels(srv *servers.Server) map[string]string { + if srv.HostID == "" { + return nil + } + + return map[string]string{ + labelHostID: srv.HostID, + } +} + func isValidLabelValue(v string) bool { if errs := validation.IsValidLabelValue(v); len(errs) != 0 { return false From 235aa7c5efd667f549e9ec086a9495481732e515 Mon Sep 17 00:00:00 2001 From: Steven Blatzheim Date: Thu, 27 Aug 2026 07:22:11 +0300 Subject: [PATCH 2/3] fix format --- pkg/openstack/instances.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/openstack/instances.go b/pkg/openstack/instances.go index e3516059ad..cc0f0363b2 100644 --- a/pkg/openstack/instances.go +++ b/pkg/openstack/instances.go @@ -143,11 +143,11 @@ func (i *InstancesV2) InstanceMetadata(ctx context.Context, node *v1.Node) (*clo availabilityZone := util.SanitizeLabel(server.AvailabilityZone) return &cloudprovider.InstanceMetadata{ - ProviderID: i.makeInstanceID(&server), - InstanceType: instanceType, - NodeAddresses: addresses, - Zone: availabilityZone, - Region: i.region, + ProviderID: i.makeInstanceID(&server), + InstanceType: instanceType, + NodeAddresses: addresses, + Zone: availabilityZone, + Region: i.region, AdditionalLabels: getAdditionalLabels(&server), }, nil } From 0223e2ac5a5e448bacf2ff298c60f93e795b6bbc Mon Sep 17 00:00:00 2001 From: Steven Blatzheim <71639670+stblatzheim@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:53:33 +0300 Subject: [PATCH 3/3] Update pkg/openstack/instances.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: pýrus --- pkg/openstack/instances.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pkg/openstack/instances.go b/pkg/openstack/instances.go index cc0f0363b2..6832a1b6a1 100644 --- a/pkg/openstack/instances.go +++ b/pkg/openstack/instances.go @@ -288,12 +288,13 @@ func srvInstanceType(ctx context.Context, client *gophercloud.ServiceClient, srv } func getAdditionalLabels(srv *servers.Server) map[string]string { - if srv.HostID == "" { + hostID := util.SanitizeLabel(srv.HostID) + if hostID == "" { return nil } return map[string]string{ - labelHostID: srv.HostID, + labelHostID: hostID, } }