Merge pull request #16739 from rifelpet/hetzner-labels

Propagate IG NodeLabels to k8s nodes in Hetzner
This commit is contained in:
Kubernetes Prow Robot 2025-01-06 22:12:30 +01:00 committed by GitHub
commit 163faa94b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 53 additions and 32 deletions

View File

@ -33,6 +33,7 @@ import (
"k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks" "k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup" "k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/hetzner"
"k8s.io/kops/upup/pkg/fi/cloudup/scaleway" "k8s.io/kops/upup/pkg/fi/cloudup/scaleway"
"github.com/blang/semver/v4" "github.com/blang/semver/v4"
@ -174,8 +175,13 @@ func (b *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma
return nil, fmt.Errorf("error building node labels: %w", err) return nil, fmt.Errorf("error building node labels: %w", err)
} }
for k, v := range nodeLabels { for k, v := range nodeLabels {
switch b.Cluster.GetCloudProvider() {
case kops.CloudProviderHetzner:
labels[hetzner.TagKubernetesNodeLabelPrefix+k] = v
default:
labels[nodeidentityaws.ClusterAutoscalerNodeTemplateLabel+k] = v labels[nodeidentityaws.ClusterAutoscalerNodeTemplateLabel+k] = v
} }
}
// Apply labels for cluster autoscaler node taints // Apply labels for cluster autoscaler node taints
for _, v := range ig.Spec.Taints { for _, v := range ig.Spec.Taints {
@ -185,6 +191,12 @@ func (b *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma
} }
} }
switch b.Cluster.GetCloudProvider() {
case kops.CloudProviderHetzner:
labels[hetzner.TagKubernetesInstanceRole] = string(ig.Spec.Role)
labels[hetzner.TagKubernetesClusterName] = b.ClusterName()
labels[hetzner.TagKubernetesInstanceGroup] = ig.Name
default:
// The system tags take priority because the cluster likely breaks without them... // The system tags take priority because the cluster likely breaks without them...
if ig.Spec.Role == kops.InstanceGroupRoleControlPlane { if ig.Spec.Role == kops.InstanceGroupRoleControlPlane {
@ -205,7 +217,7 @@ func (b *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma
} }
labels[nodeidentityaws.CloudTagInstanceGroupName] = ig.Name labels[nodeidentityaws.CloudTagInstanceGroupName] = ig.Name
}
return labels, nil return labels, nil
} }
@ -259,6 +271,8 @@ func (b *KopsModelContext) CloudTags(name string, shared bool) map[string]string
} }
tags[k] = v tags[k] = v
} }
case kops.CloudProviderHetzner:
tags[hetzner.TagKubernetesClusterName] = b.ClusterName()
} }
return tags return tags
} }

View File

@ -54,11 +54,10 @@ func (b *ServerGroupModelBuilder) Build(c *fi.CloudupModelBuilderContext) error
for _, ig := range b.InstanceGroups { for _, ig := range b.InstanceGroups {
igSize := fi.ValueOf(ig.Spec.MinSize) igSize := fi.ValueOf(ig.Spec.MinSize)
labels, err := b.CloudTagsForInstanceGroup(ig)
labels := make(map[string]string) if err != nil {
labels[hetzner.TagKubernetesClusterName] = b.ClusterName() return err
labels[hetzner.TagKubernetesInstanceGroup] = ig.Name }
labels[hetzner.TagKubernetesInstanceRole] = string(ig.Spec.Role)
userData, err := b.BootstrapScriptBuilder.ResourceNodeUp(c, ig) userData, err := b.BootstrapScriptBuilder.ResourceNodeUp(c, ig)
if err != nil { if err != nil {

View File

@ -97,7 +97,8 @@ func (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*
labels := map[string]string{} labels := map[string]string{}
for key, value := range server.Labels { for key, value := range server.Labels {
if key == hetzner.TagKubernetesInstanceRole { switch {
case key == hetzner.TagKubernetesInstanceRole:
switch kops.InstanceGroupRole(value) { switch kops.InstanceGroupRole(value) {
case kops.InstanceGroupRoleControlPlane: case kops.InstanceGroupRoleControlPlane:
labels[nodelabels.RoleLabelControlPlane20] = "" labels[nodelabels.RoleLabelControlPlane20] = ""
@ -108,6 +109,8 @@ func (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*
default: default:
klog.Warningf("Unknown node role %q for server %s(%d)", value, server.Name, server.ID) klog.Warningf("Unknown node role %q for server %s(%d)", value, server.Name, server.ID)
} }
case strings.HasPrefix(key, hetzner.TagKubernetesNodeLabelPrefix):
labels[strings.TrimPrefix(key, hetzner.TagKubernetesNodeLabelPrefix)] = value
} }
} }

View File

@ -238,6 +238,9 @@ resource "hcloud_server" "master-fsn1" {
"kops.k8s.io/cluster" = "minimal.example.com" "kops.k8s.io/cluster" = "minimal.example.com"
"kops.k8s.io/instance-group" = "master-fsn1" "kops.k8s.io/instance-group" = "master-fsn1"
"kops.k8s.io/instance-role" = "ControlPlane" "kops.k8s.io/instance-role" = "ControlPlane"
"node-label.kops.k8s.io.kops.k8s.io/kops-controller-pki" = ""
"node-label.kops.k8s.io.node-role.kubernetes.io/control-plane" = ""
"node-label.kops.k8s.io.node.kubernetes.io/exclude-from-external-load-balancers" = ""
} }
location = "fsn1" location = "fsn1"
name = "master-fsn1-${count.index}" name = "master-fsn1-${count.index}"
@ -260,6 +263,7 @@ resource "hcloud_server" "nodes-fsn1" {
"kops.k8s.io/cluster" = "minimal.example.com" "kops.k8s.io/cluster" = "minimal.example.com"
"kops.k8s.io/instance-group" = "nodes-fsn1" "kops.k8s.io/instance-group" = "nodes-fsn1"
"kops.k8s.io/instance-role" = "Node" "kops.k8s.io/instance-role" = "Node"
"node-label.kops.k8s.io.node-role.kubernetes.io/node" = ""
} }
location = "fsn1" location = "fsn1"
name = "nodes-fsn1-${count.index}" name = "nodes-fsn1-${count.index}"

View File

@ -41,6 +41,7 @@ const (
TagKubernetesInstanceUserData = "kops.k8s.io/instance-userdata" TagKubernetesInstanceUserData = "kops.k8s.io/instance-userdata"
TagKubernetesInstanceNeedsUpdate = "kops.k8s.io/needs-update" TagKubernetesInstanceNeedsUpdate = "kops.k8s.io/needs-update"
TagKubernetesVolumeRole = "kops.k8s.io/volume-role" TagKubernetesVolumeRole = "kops.k8s.io/volume-role"
TagKubernetesNodeLabelPrefix = "node-label.kops.k8s.io."
) )
// HetznerCloud exposes all the interfaces required to operate on Hetzner Cloud resources // HetznerCloud exposes all the interfaces required to operate on Hetzner Cloud resources