Skip to content

Commit

Permalink
Revert "IPv6 internal node IPs are usable externally"
Browse files Browse the repository at this point in the history
This reverts commit 683663e.
  • Loading branch information
jonasbadstuebner committed Jun 24, 2024
1 parent 8245b89 commit c45b53b
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 66 deletions.
5 changes: 2 additions & 3 deletions docs/tutorials/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
This tutorial describes how to configure ExternalDNS to use the cluster nodes as source.
Using nodes (`--source=node`) as source is possible to synchronize a DNS zone with the nodes of a cluster.

The node source adds an `A` record per each node `externalIP` (if not found, any IPv4 `internalIP` is used instead).
It also adds an `AAAA` record per each node IPv6 `internalIP`.
The TTL of the records can be set with the `external-dns.alpha.kubernetes.io/ttl` node annotation.
The node source adds `A` and `AAAA` record per each node `externalIP` (if not found, node's `internalIP`s are used).
The TTL record can be set with the `external-dns.alpha.kubernetes.io/ttl` node annotation.

## Manifest (for cluster without RBAC enabled)

Expand Down
3 changes: 1 addition & 2 deletions source/compatibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ func legacyEndpointsFromDNSControllerNodePortService(svc *v1.Service, sc *servic
}
for _, address := range node.Status.Addresses {
recordType := suitableType(address.Address)
// IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well.
if isExternal && (address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA)) {
if isExternal && address.Type == v1.NodeExternalIP {
endpoints = append(endpoints, endpoint.NewEndpoint(hostname, recordType, address.Address))
}
if isInternal && address.Type == v1.NodeInternalIP {
Expand Down
7 changes: 1 addition & 6 deletions source/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,18 +169,13 @@ func (ns *nodeSource) nodeAddresses(node *v1.Node) ([]string, error) {
v1.NodeExternalIP: {},
v1.NodeInternalIP: {},
}
var ipv6Addresses []string

for _, addr := range node.Status.Addresses {
addresses[addr.Type] = append(addresses[addr.Type], addr.Address)
// IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well.
if addr.Type == v1.NodeInternalIP && suitableType(addr.Address) == endpoint.RecordTypeAAAA {
ipv6Addresses = append(ipv6Addresses, addr.Address)
}
}

if len(addresses[v1.NodeExternalIP]) > 0 {
return append(addresses[v1.NodeExternalIP], ipv6Addresses...), nil
return addresses[v1.NodeExternalIP], nil
}

if len(addresses[v1.NodeInternalIP]) > 0 {
Expand Down
4 changes: 2 additions & 2 deletions source/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func testNodeSourceEndpoints(t *testing.T) {
title: "node with fqdn template returns two endpoints with dual-stack IP addresses and expanded hostname",
fqdnTemplate: "{{.Name}}.example.org",
nodeName: "node1",
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeExternalIP, Address: "2001:DB8::8"}},
expected: []*endpoint.Endpoint{
{RecordType: "A", DNSName: "node1.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{RecordType: "AAAA", DNSName: "node1.example.org", Targets: endpoint.Targets{"2001:DB8::8"}},
Expand All @@ -176,7 +176,7 @@ func testNodeSourceEndpoints(t *testing.T) {
{
title: "node with both external, internal, and IPv6 IP returns endpoints with external IPs",
nodeName: "node1",
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeInternalIP, Address: "2001:DB8::8"}},
nodeAddresses: []v1.NodeAddress{{Type: v1.NodeExternalIP, Address: "1.2.3.4"}, {Type: v1.NodeInternalIP, Address: "2.3.4.5"}, {Type: v1.NodeExternalIP, Address: "2001:DB8::8"}},
expected: []*endpoint.Endpoint{
{RecordType: "A", DNSName: "node1", Targets: endpoint.Targets{"1.2.3.4"}},
{RecordType: "AAAA", DNSName: "node1", Targets: endpoint.Targets{"2001:DB8::8"}},
Expand Down
12 changes: 4 additions & 8 deletions source/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,8 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error
if len(targets) == 0 {
node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName)
for _, address := range node.Status.Addresses {
recordType := suitableType(address.Address)
// IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well.
if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) {
addToEndpointMap(endpointMap, domain, recordType, address.Address)
if address.Type == corev1.NodeExternalIP {
addToEndpointMap(endpointMap, domain, suitableType(address.Address), address.Address)
}
}
} else {
Expand All @@ -137,10 +135,8 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error
for _, domain := range domainList {
node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName)
for _, address := range node.Status.Addresses {
recordType := suitableType(address.Address)
// IPv6 addresses are labeled as NodeInternalIP despite being usable externally as well.
if address.Type == corev1.NodeExternalIP || (address.Type == corev1.NodeInternalIP && recordType == endpoint.RecordTypeAAAA) {
addToEndpointMap(endpointMap, domain, recordType, address.Address)
if address.Type == corev1.NodeExternalIP {
addToEndpointMap(endpointMap, domain, suitableType(address.Address), address.Address)
}
}
}
Expand Down
108 changes: 99 additions & 9 deletions source/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ func TestPodSource(t *testing.T) {
"",
"",
[]*endpoint.Endpoint{
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2", "2001:DB8::3", "2001:DB8::4"}, RecordType: endpoint.RecordTypeAAAA},
},
false,
[]*corev1.Node{
Expand All @@ -196,7 +196,7 @@ func TestPodSource(t *testing.T) {
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::1"},
{Type: corev1.NodeExternalIP, Address: "2001:DB8::1"},
},
},
},
Expand All @@ -206,7 +206,18 @@ func TestPodSource(t *testing.T) {
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::2"},
{Type: corev1.NodeExternalIP, Address: "2001:DB8::2"},
{Type: corev1.NodeInternalIP, Address: "2001:DB8::3"},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-node3",
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::4"},
},
},
},
Expand Down Expand Up @@ -246,15 +257,49 @@ func TestPodSource(t *testing.T) {
PodIP: "2001:DB8::2",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-pod3",
Namespace: "kube-system",
Annotations: map[string]string{
internalHostnameAnnotationKey: "internal.a.foo.example.org",
hostnameAnnotationKey: "a.foo.example.org",
},
},
Spec: corev1.PodSpec{
HostNetwork: true,
NodeName: "my-node2",
},
Status: corev1.PodStatus{
PodIP: "2001:DB8::3",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-pod4",
Namespace: "kube-system",
Annotations: map[string]string{
internalHostnameAnnotationKey: "internal.a.foo.example.org",
hostnameAnnotationKey: "a.foo.example.org",
},
},
Spec: corev1.PodSpec{
HostNetwork: true,
NodeName: "my-node3",
},
Status: corev1.PodStatus{
PodIP: "2001:DB8::4",
},
},
},
},
{
"create IPv6 records based on pod's external and internal IPs using DNS Controller annotations",
"",
"kops-dns-controller",
[]*endpoint.Endpoint{
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2", "2001:DB8::2"}, RecordType: endpoint.RecordTypeAAAA},
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"2001:DB8::1", "2001:DB8::2", "2001:DB8::3", "2001:DB8::4"}, RecordType: endpoint.RecordTypeAAAA},
},
false,
[]*corev1.Node{
Expand All @@ -264,7 +309,7 @@ func TestPodSource(t *testing.T) {
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::1"},
{Type: corev1.NodeExternalIP, Address: "2001:DB8::1"},
},
},
},
Expand All @@ -274,7 +319,18 @@ func TestPodSource(t *testing.T) {
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::2"},
{Type: corev1.NodeExternalIP, Address: "2001:DB8::2"},
{Type: corev1.NodeInternalIP, Address: "2001:DB8::3"},
},
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-node3",
},
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeInternalIP, Address: "2001:DB8::4"},
},
},
},
Expand Down Expand Up @@ -314,6 +370,40 @@ func TestPodSource(t *testing.T) {
PodIP: "2001:DB8::2",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-pod3",
Namespace: "kube-system",
Annotations: map[string]string{
kopsDNSControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org",
kopsDNSControllerHostnameAnnotationKey: "a.foo.example.org",
},
},
Spec: corev1.PodSpec{
HostNetwork: true,
NodeName: "my-node2",
},
Status: corev1.PodStatus{
PodIP: "2001:DB8::3",
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "my-pod4",
Namespace: "kube-system",
Annotations: map[string]string{
kopsDNSControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org",
kopsDNSControllerHostnameAnnotationKey: "a.foo.example.org",
},
},
Spec: corev1.PodSpec{
HostNetwork: true,
NodeName: "my-node3",
},
Status: corev1.PodStatus{
PodIP: "2001:DB8::4",
},
},
},
},
{
Expand Down Expand Up @@ -406,7 +496,7 @@ func TestPodSource(t *testing.T) {
Status: corev1.NodeStatus{
Addresses: []corev1.NodeAddress{
{Type: corev1.NodeExternalIP, Address: "54.10.11.1"},
{Type: corev1.NodeInternalIP, Address: "2001:DB8::1"},
{Type: corev1.NodeExternalIP, Address: "2001:DB8::1"},
{Type: corev1.NodeInternalIP, Address: "10.0.1.1"},
},
},
Expand Down
10 changes: 3 additions & 7 deletions source/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
return endpoints
}
for _, address := range node.Status.Addresses {
if address.Type == v1.NodeExternalIP || (address.Type == v1.NodeInternalIP && suitableType(address.Address) == endpoint.RecordTypeAAAA) {
if address.Type == v1.NodeExternalIP {
targets = append(targets, address.Address)
log.Debugf("Generating matching endpoint %s with NodeExternalIP %s", headlessDomain, address.Address)
}
Expand Down Expand Up @@ -579,7 +579,6 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe
var (
internalIPs endpoint.Targets
externalIPs endpoint.Targets
ipv6IPs endpoint.Targets
nodes []*v1.Node
err error
)
Expand Down Expand Up @@ -650,22 +649,19 @@ func (sc *serviceSource) extractNodePortTargets(svc *v1.Service) (endpoint.Targe
externalIPs = append(externalIPs, address.Address)
case v1.NodeInternalIP:
internalIPs = append(internalIPs, address.Address)
if suitableType(address.Address) == endpoint.RecordTypeAAAA {
ipv6IPs = append(ipv6IPs, address.Address)
}
}
}
}

access := getAccessFromAnnotations(svc.Annotations)
if access == "public" {
return append(externalIPs, ipv6IPs...), nil
return externalIPs, nil
}
if access == "private" {
return internalIPs, nil
}
if len(externalIPs) > 0 {
return append(externalIPs, ipv6IPs...), nil
return externalIPs, nil
}
return internalIPs, nil
}
Expand Down
Loading

0 comments on commit c45b53b

Please sign in to comment.