mirror of https://github.com/k3s-io/k3s
Fix AWS DHCP option set domain names causing garbled InternalDNS or Hostname addresses on Node
parent
c5a761cc6e
commit
34170a18ae
|
@ -1351,14 +1351,17 @@ func (c *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.No
|
|||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeExternalIP, Address: externalIP})
|
||||
}
|
||||
|
||||
internalDNS, err := c.metadata.GetMetadata("local-hostname")
|
||||
if err != nil || len(internalDNS) == 0 {
|
||||
localHostname, err := c.metadata.GetMetadata("local-hostname")
|
||||
if err != nil || len(localHostname) == 0 {
|
||||
//TODO: It would be nice to be able to determine the reason for the failure,
|
||||
// but the AWS client masks all failures with the same error description.
|
||||
klog.V(4).Info("Could not determine private DNS from AWS metadata.")
|
||||
} else {
|
||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: internalDNS})
|
||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeHostName, Address: internalDNS})
|
||||
hostname, internalDNS := parseMetadataLocalHostname(localHostname)
|
||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeHostName, Address: hostname})
|
||||
for _, d := range internalDNS {
|
||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: d})
|
||||
}
|
||||
}
|
||||
|
||||
externalDNS, err := c.metadata.GetMetadata("public-hostname")
|
||||
|
@ -1380,6 +1383,26 @@ func (c *Cloud) NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.No
|
|||
return extractNodeAddresses(instance)
|
||||
}
|
||||
|
||||
// parseMetadataLocalHostname parses the output of "local-hostname" metadata.
|
||||
// If a DHCP option set is configured for a VPC and it has multiple domain names, GetMetadata
|
||||
// returns a string containing first the hostname followed by additional domain names,
|
||||
// space-separated. For example, if the DHCP option set has:
|
||||
// domain-name = us-west-2.compute.internal a.a b.b c.c d.d;
|
||||
// $ curl http://169.254.169.254/latest/meta-data/local-hostname
|
||||
// ip-192-168-111-51.us-west-2.compute.internal a.a b.b c.c d.d
|
||||
func parseMetadataLocalHostname(metadata string) (string, []string) {
|
||||
localHostnames := strings.Fields(metadata)
|
||||
hostname := localHostnames[0]
|
||||
internalDNS := []string{hostname}
|
||||
|
||||
privateAddress := strings.Split(hostname, ".")[0]
|
||||
for _, h := range localHostnames[1:] {
|
||||
internalDNSAddress := privateAddress + "." + h
|
||||
internalDNS = append(internalDNS, internalDNSAddress)
|
||||
}
|
||||
return hostname, internalDNS
|
||||
}
|
||||
|
||||
// extractNodeAddresses maps the instance information from EC2 to an array of NodeAddresses
|
||||
func extractNodeAddresses(instance *ec2.Instance) ([]v1.NodeAddress, error) {
|
||||
// Not clear if the order matters here, but we might as well indicate a sensible preference order
|
||||
|
|
|
@ -681,6 +681,41 @@ func TestNodeAddressesWithMetadata(t *testing.T) {
|
|||
testHasNodeAddress(t, addrs, v1.NodeExternalIP, "2.3.4.5")
|
||||
}
|
||||
|
||||
func TestParseMetadataLocalHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
metadata string
|
||||
hostname string
|
||||
internalDNS []string
|
||||
}{
|
||||
{
|
||||
"single hostname",
|
||||
"ip-172-31-16-168.us-west-2.compute.internal",
|
||||
"ip-172-31-16-168.us-west-2.compute.internal",
|
||||
[]string{"ip-172-31-16-168.us-west-2.compute.internal"},
|
||||
},
|
||||
{
|
||||
"dhcp options set with three additional domain names",
|
||||
"ip-172-31-16-168.us-west-2.compute.internal example.com example.ca example.org",
|
||||
"ip-172-31-16-168.us-west-2.compute.internal",
|
||||
[]string{"ip-172-31-16-168.us-west-2.compute.internal", "ip-172-31-16-168.example.com", "ip-172-31-16-168.example.ca", "ip-172-31-16-168.example.org"},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
hostname, internalDNS := parseMetadataLocalHostname(test.metadata)
|
||||
if hostname != test.hostname {
|
||||
t.Errorf("got hostname %v, expected %v", hostname, test.hostname)
|
||||
}
|
||||
for i, v := range internalDNS {
|
||||
if v != test.internalDNS[i] {
|
||||
t.Errorf("got an internalDNS %v, expected %v", v, test.internalDNS[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetRegion(t *testing.T) {
|
||||
aws := mockAvailabilityZone("us-west-2e")
|
||||
zones, ok := aws.Zones()
|
||||
|
|
Loading…
Reference in New Issue