diff --git a/Makefile b/Makefile index d2a3583e752f1..5dc8167aade45 100644 --- a/Makefile +++ b/Makefile @@ -357,7 +357,7 @@ push: crossbuild-nodeup .PHONY: push-gce-dry push-gce-dry: push - ssh ${TARGET} sudo /tmp/nodeup --conf=metadata://gce/config --dryrun --v=8 + ssh ${TARGET} sudo /tmp/nodeup --conf=metadata://gce/instance/attributes/config --dryrun --v=8 .PHONY: push-gce-dry push-aws-dry: push diff --git a/pkg/model/components/kubelet.go b/pkg/model/components/kubelet.go index 1fe79a8dc7006..2d5c17431342b 100644 --- a/pkg/model/components/kubelet.go +++ b/pkg/model/components/kubelet.go @@ -153,6 +153,12 @@ func (b *KubeletOptionsBuilder) BuildOptions(o interface{}) error { } clusterSpec.CloudConfig.Multizone = fi.Bool(true) clusterSpec.CloudConfig.NodeTags = fi.String(GCETagForRole(b.Context.ClusterName, kops.InstanceGroupRoleNode)) + + // Use the hostname from the GCE metadata service + // if hostnameOverride is not set. + if clusterSpec.Kubelet.HostnameOverride == "" { + clusterSpec.Kubelet.HostnameOverride = "@gce" + } } if cloudProvider == kops.CloudProviderVSphere { diff --git a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-a-ha-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-a-ha-gce-example-com_metadata_startup-script index c9357b2f05cf0..575fee7ccbe4d 100644 --- a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-a-ha-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-a-ha-gce-example-com_metadata_startup-script @@ -226,6 +226,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 @@ -244,6 +245,7 @@ masterKubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-b-ha-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-b-ha-gce-example-com_metadata_startup-script index ab141c7dee7bd..678fc00553099 100644 --- a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-b-ha-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-b-ha-gce-example-com_metadata_startup-script @@ -226,6 +226,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 @@ -244,6 +245,7 @@ masterKubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-c-ha-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-c-ha-gce-example-com_metadata_startup-script index b81d0b01606c4..8866e58645aaf 100644 --- a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-c-ha-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_master-us-test1-c-ha-gce-example-com_metadata_startup-script @@ -226,6 +226,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 @@ -244,6 +245,7 @@ masterKubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_nodes-ha-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_nodes-ha-gce-example-com_metadata_startup-script index 4681498b13614..88770d4a3852f 100644 --- a/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_nodes-ha-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/ha_gce/data/google_compute_instance_template_nodes-ha-gce-example-com_metadata_startup-script @@ -162,6 +162,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_master-us-test1-a-minimal-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_master-us-test1-a-minimal-gce-example-com_metadata_startup-script index 64611028bb6b7..960b402120740 100644 --- a/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_master-us-test1-a-minimal-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_master-us-test1-a-minimal-gce-example-com_metadata_startup-script @@ -226,6 +226,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 @@ -244,6 +245,7 @@ masterKubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_nodes-minimal-gce-example-com_metadata_startup-script b/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_nodes-minimal-gce-example-com_metadata_startup-script index ced79d8362e30..b1482df8dbbb4 100644 --- a/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_nodes-minimal-gce-example-com_metadata_startup-script +++ b/tests/integration/update_cluster/minimal_gce/data/google_compute_instance_template_nodes-minimal-gce-example-com_metadata_startup-script @@ -162,6 +162,7 @@ kubelet: featureGates: ExperimentalCriticalPodAnnotation: "true" hairpinMode: promiscuous-bridge + hostnameOverride: '@gce' kubeconfigPath: /var/lib/kubelet/kubeconfig logLevel: 2 networkPluginMTU: 9001 diff --git a/upup/pkg/fi/nodeup/command.go b/upup/pkg/fi/nodeup/command.go index 1473bfcbaa8cf..c9c4a2fba159b 100644 --- a/upup/pkg/fi/nodeup/command.go +++ b/upup/pkg/fi/nodeup/command.go @@ -491,6 +491,21 @@ func evaluateHostnameOverride(hostnameOverride string) (string, error) { return *(result.Reservations[0].Instances[0].PrivateDnsName), nil } + if k == "@gce" { + // We recognize @gce as meaning the hostname from the GCE metadata service + // This lets us tolerate broken hostnames (i.e. systemd) + b, err := vfs.Context.ReadFile("metadata://gce/instance/hostname") + if err != nil { + return "", fmt.Errorf("error reading hostname from GCE metadata: %v", err) + } + + // We only want to use the first portion of the fully-qualified name + // e.g. foo.c.project.internal => foo + fullyQualified := string(b) + bareHostname := strings.Split(fullyQualified, ".")[0] + return bareHostname, nil + } + if k == "@digitalocean" { // @digitalocean means to use the private ipv4 address of a droplet as the hostname override vBytes, err := vfs.Context.ReadFile("metadata://digitalocean/interfaces/private/0/ipv4/address") diff --git a/util/pkg/vfs/context.go b/util/pkg/vfs/context.go index 0dbb48a173861..f8c3bf7139607 100644 --- a/util/pkg/vfs/context.go +++ b/util/pkg/vfs/context.go @@ -97,7 +97,7 @@ func (c *VFSContext) ReadFile(location string, options ...VFSOption) ([]byte, er case "metadata": switch u.Host { case "gce": - httpURL := "http://169.254.169.254/computeMetadata/v1/instance/attributes/" + u.Path + httpURL := "http://169.254.169.254/computeMetadata/v1/" + u.Path httpHeaders := make(map[string]string) httpHeaders["Metadata-Flavor"] = "Google" return c.readHTTPLocation(httpURL, httpHeaders, opts)