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})
|
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeExternalIP, Address: externalIP})
|
||||||
}
|
}
|
||||||
|
|
||||||
internalDNS, err := c.metadata.GetMetadata("local-hostname")
|
localHostname, err := c.metadata.GetMetadata("local-hostname")
|
||||||
if err != nil || len(internalDNS) == 0 {
|
if err != nil || len(localHostname) == 0 {
|
||||||
//TODO: It would be nice to be able to determine the reason for the failure,
|
//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.
|
// but the AWS client masks all failures with the same error description.
|
||||||
klog.V(4).Info("Could not determine private DNS from AWS metadata.")
|
klog.V(4).Info("Could not determine private DNS from AWS metadata.")
|
||||||
} else {
|
} else {
|
||||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeInternalDNS, Address: internalDNS})
|
hostname, internalDNS := parseMetadataLocalHostname(localHostname)
|
||||||
addresses = append(addresses, v1.NodeAddress{Type: v1.NodeHostName, Address: internalDNS})
|
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")
|
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)
|
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
|
// extractNodeAddresses maps the instance information from EC2 to an array of NodeAddresses
|
||||||
func extractNodeAddresses(instance *ec2.Instance) ([]v1.NodeAddress, error) {
|
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
|
// 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")
|
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) {
|
func TestGetRegion(t *testing.T) {
|
||||||
aws := mockAvailabilityZone("us-west-2e")
|
aws := mockAvailabilityZone("us-west-2e")
|
||||||
zones, ok := aws.Zones()
|
zones, ok := aws.Zones()
|
||||||
|
|
Loading…
Reference in New Issue