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..6832a1b6a1 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. @@ -142,11 +143,12 @@ 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 } @@ -285,6 +287,17 @@ 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 { + hostID := util.SanitizeLabel(srv.HostID) + if hostID == "" { + return nil + } + + return map[string]string{ + labelHostID: hostID, + } +} + func isValidLabelValue(v string) bool { if errs := validation.IsValidLabelValue(v); len(errs) != 0 { return false