Maxim Ivanov
63802fda51
feat(service): add support for fqdn-template when generating per-pod DNS entries.
...
Allows further customization of a generated per-pod DNS name
with `--fqdn-template` parameter if it is set.
diff --git c/docs/sources/service.md i/docs/sources/service.md
index 7f03426e..1c30eba7 100644
--- c/docs/sources/service.md
+++ i/docs/sources/service.md
@@ -34,7 +34,8 @@ For each domain name created for the Service, the additional DNS entry for the P
the value of the Pod's `spec.hostname` field and a `.`.
Another way to create per-pod DNS entries is to annotate headless service with
-`external-dns.alpha.kubernetes.io/service-pod-endpoints: true`, this will prefix service domain name with pod name.
+`external-dns.alpha.kubernetes.io/service-pod-endpoints` and values `pod-name` or `fqdn-template`. Former prefixes
+service domain name with pod name, latter uses `--fqdn-template` to generate the domain name for each pod in the service.
## Targets
diff --git c/source/service.go i/source/service.go
index 0186a102..d913cfe1 100644
--- c/source/service.go
+++ i/source/service.go
@@ -279,7 +279,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
endpointsType := getEndpointsTypeFromAnnotations(svc.Annotations)
- _, perPodDNS := svc.Annotations[servicePodEndpointsKey]
+ perPodDNSMode, perPodDNS := svc.Annotations[servicePodEndpointsKey]
targetsByHeadlessDomainAndType := make(map[endpoint.EndpointKey]endpoint.Targets)
for _, subset := range endpointsObject.Subsets {
@@ -312,7 +312,18 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
}
if perPodDNS {
- headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ if perPodDNSMode == ServicePodEndpointsPodName {
+ headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ } else if perPodDNSMode == ServicePodEndpointsFqdnTemplate {
+ if hostnames, err := execTemplate(sc.fqdnTemplate, pod); err == nil {
+ headlessDomains = append(headlessDomains, hostnames...)
+ } else {
+ log.Errorf("Error executing template for pod %s: %v", pod.Name, err)
+ }
+ } else {
+ log.Errorf("Unknown `service-pod-endpoints` value %s", perPodDNSMode)
+ return endpoints
+ }
}
for _, headlessDomain := range headlessDomains {
diff --git c/source/service_test.go i/source/service_test.go
index c25e2f29..c64adcc4 100644
--- c/source/service_test.go
+++ i/source/service_test.go
@@ -2903,7 +2903,7 @@ func TestHeadlessServices(t *testing.T) {
false,
map[string]string{"component": "foo"},
map[string]string{
- servicePodEndpointsKey: "true",
+ servicePodEndpointsKey: ServicePodEndpointsPodName,
hostnameAnnotationKey: "service.example.org",
endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
},
@@ -2947,6 +2947,91 @@ func TestHeadlessServices(t *testing.T) {
},
false,
},
+ {
+ "annotated Headless services create DNS name for each pod using fqdn template",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "{{ .Name }}-{{ .Namespace }}.example.org",
+ false,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: ServicePodEndpointsFqdnTemplate,
+ hostnameAnnotationKey: "service.example.org",
+ endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{
+ {
+ Status: v1.NodeStatus{
+ Addresses: []v1.NodeAddress{
+ {
+ Type: v1.NodeExternalIP,
+ Address: "1.2.3.4",
+ },
+ {
+ Type: v1.NodeInternalIP,
+ Address: "2001:db8::4",
+ },
+ },
+ },
+ },
+ },
+ []*endpoint.Endpoint{
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo1-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo1-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo2-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo2-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo3-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo3-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ },
+ false,
+ },
+ {
+ "annotated Headless service returns error if incorrect `service-pod-endpoints` value is set",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "",
+ false,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: "not-valid",
+ hostnameAnnotationKey: "service.example.org",
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{{}},
+ []*endpoint.Endpoint{},
+ false,
+ },
{
"annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set",
"",
diff --git c/source/source.go i/source/source.go
index 0df189bb..37f9016e 100644
--- c/source/source.go
+++ i/source/source.go
@@ -52,6 +52,11 @@ const (
EndpointsTypeHostIP = "HostIP"
)
+const (
+ ServicePodEndpointsPodName = "pod-name"
+ ServicePodEndpointsFqdnTemplate = "fqdn-template"
+)
+
// Source defines the interface Endpoint sources should implement.
type Source interface {
Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error)
diff --git c/docs/sources/service.md i/docs/sources/service.md
index 7f03426e..1c30eba7 100644
--- c/docs/sources/service.md
+++ i/docs/sources/service.md
@@ -34,7 +34,8 @@ For each domain name created for the Service, the additional DNS entry for the P
the value of the Pod's `spec.hostname` field and a `.`.
Another way to create per-pod DNS entries is to annotate headless service with
-`external-dns.alpha.kubernetes.io/service-pod-endpoints: true`, this will prefix service domain name with pod name.
+`external-dns.alpha.kubernetes.io/service-pod-endpoints` and values `pod-name` or `fqdn-template`. Former prefixes
+service domain name with pod name, latter uses `--fqdn-template` to generate the domain name for each pod in the service.
## Targets
diff --git c/source/service.go i/source/service.go
index 8adb25ea..12e295db 100644
--- c/source/service.go
+++ i/source/service.go
@@ -281,7 +281,7 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
endpointsType := getEndpointsTypeFromAnnotations(svc.Annotations)
- _, perPodDNS := svc.Annotations[servicePodEndpointsKey]
+ perPodDNSMode, perPodDNS := svc.Annotations[servicePodEndpointsKey]
targetsByHeadlessDomainAndType := make(map[endpoint.EndpointKey]endpoint.Targets)
for _, subset := range endpointsObject.Subsets {
@@ -314,7 +314,18 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
}
if perPodDNS {
- headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ if perPodDNSMode == ServicePodEndpointsPodName {
+ headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ } else if perPodDNSMode == ServicePodEndpointsFqdnTemplate {
+ if hostnames, err := execTemplate(sc.fqdnTemplate, pod); err == nil {
+ headlessDomains = append(headlessDomains, hostnames...)
+ } else {
+ log.Errorf("Error executing template for pod %s: %v", pod.Name, err)
+ }
+ } else {
+ log.Errorf("Unknown `service-pod-endpoints` value %s", perPodDNSMode)
+ return endpoints
+ }
}
for _, headlessDomain := range headlessDomains {
diff --git c/source/service_test.go i/source/service_test.go
index ddfc2b59..b759aeac 100644
--- c/source/service_test.go
+++ i/source/service_test.go
@@ -2975,7 +2975,7 @@ func TestHeadlessServices(t *testing.T) {
true,
map[string]string{"component": "foo"},
map[string]string{
- servicePodEndpointsKey: "true",
+ servicePodEndpointsKey: ServicePodEndpointsPodName,
hostnameAnnotationKey: "service.example.org",
endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
},
@@ -3019,6 +3019,93 @@ func TestHeadlessServices(t *testing.T) {
},
false,
},
+ {
+ "annotated Headless services create DNS name for each pod using fqdn template",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "{{ .Name }}-{{ .Namespace }}.example.org",
+ false,
+ true,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: ServicePodEndpointsFqdnTemplate,
+ hostnameAnnotationKey: "service.example.org",
+ endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{
+ {
+ Status: v1.NodeStatus{
+ Addresses: []v1.NodeAddress{
+ {
+ Type: v1.NodeExternalIP,
+ Address: "1.2.3.4",
+ },
+ {
+ Type: v1.NodeInternalIP,
+ Address: "2001:db8::4",
+ },
+ },
+ },
+ },
+ },
+ []*endpoint.Endpoint{
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo1-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo1-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo2-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo2-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo3-testing.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo3-testing.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ },
+ false,
+ },
+ {
+ "annotated Headless service returns error if incorrect `service-pod-endpoints` value is set",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "",
+ false,
+ true,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: "not-valid",
+ hostnameAnnotationKey: "service.example.org",
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{{}},
+ []*endpoint.Endpoint{},
+ false,
+ },
{
"annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set and exposeInternalIPv6 flag set",
"",
diff --git c/source/source.go i/source/source.go
index bcb96fb7..b93304a7 100644
--- c/source/source.go
+++ i/source/source.go
@@ -46,6 +46,9 @@ const (
EndpointsTypeNodeExternalIP = "NodeExternalIP"
EndpointsTypeHostIP = "HostIP"
+
+ ServicePodEndpointsPodName = "pod-name"
+ ServicePodEndpointsFqdnTemplate = "fqdn-template"
)
// Source defines the interface Endpoint sources should implement.
2025-07-22 13:11:22 +01:00
Maxim Ivanov
14ccac056c
feat(service): optionally create DNS entry for each pod
...
headless service already supported mode where DNS entry is created for
each pod when `spec.hostName` is present. Not all controllers populate that
field, but it is sometimes desireable to create DNS entry per pod nevertheless.
This commit adds new annotation `service-pod-endpoints` , which when set
on a headless service makes external-dns to create endpoint per pod using pod name as a prefix.
diff --git c/docs/sources/service.md i/docs/sources/service.md
index ec39aa7f..7f03426e 100644
--- c/docs/sources/service.md
+++ i/docs/sources/service.md
@@ -33,6 +33,10 @@ a Pod that has a non-empty `spec.hostname` field, additional DNS entries are cre
For each domain name created for the Service, the additional DNS entry for the Pod has that domain name prefixed with
the value of the Pod's `spec.hostname` field and a `.`.
+Another way to create per-pod DNS entries is to annotate headless service with
+`external-dns.alpha.kubernetes.io/service-pod-endpoints: true`, this will prefix service domain name with pod name.
+
+
## Targets
If the Service has an `external-dns.alpha.kubernetes.io/target` annotation, uses
diff --git c/source/service.go i/source/service.go
index 2c33dcea..0186a102 100644
--- c/source/service.go
+++ i/source/service.go
@@ -279,6 +279,8 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
endpointsType := getEndpointsTypeFromAnnotations(svc.Annotations)
+ _, perPodDNS := svc.Annotations[servicePodEndpointsKey]
+
targetsByHeadlessDomainAndType := make(map[endpoint.EndpointKey]endpoint.Targets)
for _, subset := range endpointsObject.Subsets {
addresses := subset.Addresses
@@ -309,6 +311,10 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Spec.Hostname, hostname))
}
+ if perPodDNS {
+ headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ }
+
for _, headlessDomain := range headlessDomains {
targets := annotations.TargetsFromTargetAnnotation(pod.Annotations)
if len(targets) == 0 {
diff --git c/source/service_test.go i/source/service_test.go
index 5e9948ab..c25e2f29 100644
--- c/source/service_test.go
+++ i/source/service_test.go
@@ -2892,6 +2892,61 @@ func TestHeadlessServices(t *testing.T) {
},
false,
},
+ {
+ "annotated Headless services create DNS name for each pod",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "",
+ false,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: "true",
+ hostnameAnnotationKey: "service.example.org",
+ endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{
+ {
+ Status: v1.NodeStatus{
+ Addresses: []v1.NodeAddress{
+ {
+ Type: v1.NodeExternalIP,
+ Address: "1.2.3.4",
+ },
+ {
+ Type: v1.NodeInternalIP,
+ Address: "2001:db8::4",
+ },
+ },
+ },
+ },
+ },
+ []*endpoint.Endpoint{
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo2.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo2.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo3.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo3.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ },
+ false,
+ },
{
"annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set",
"",
diff --git c/source/source.go i/source/source.go
index 414ff1ad..0df189bb 100644
--- c/source/source.go
+++ i/source/source.go
@@ -46,6 +46,7 @@ const (
ingressHostnameSourceKey = annotations.IngressHostnameSourceKey
controllerAnnotationValue = annotations.ControllerValue
internalHostnameAnnotationKey = annotations.InternalHostnameKey
+ servicePodEndpointsKey = annotations.ServicePodEndpoints
EndpointsTypeNodeExternalIP = "NodeExternalIP"
EndpointsTypeHostIP = "HostIP"
# Conflicts:
# source/service_test.go
diff --git c/docs/sources/service.md i/docs/sources/service.md
index ec39aa7f..7f03426e 100644
--- c/docs/sources/service.md
+++ i/docs/sources/service.md
@@ -33,6 +33,10 @@ a Pod that has a non-empty `spec.hostname` field, additional DNS entries are cre
For each domain name created for the Service, the additional DNS entry for the Pod has that domain name prefixed with
the value of the Pod's `spec.hostname` field and a `.`.
+Another way to create per-pod DNS entries is to annotate headless service with
+`external-dns.alpha.kubernetes.io/service-pod-endpoints: true`, this will prefix service domain name with pod name.
+
+
## Targets
If the Service has an `external-dns.alpha.kubernetes.io/target` annotation, uses
diff --git c/source/annotations/annotations.go i/source/annotations/annotations.go
index abfce135..9fd2cd4c 100644
--- c/source/annotations/annotations.go
+++ i/source/annotations/annotations.go
@@ -55,4 +55,6 @@ const (
ControllerValue = "dns-controller"
// The annotation used for defining the desired hostname
InternalHostnameKey = AnnotationKeyPrefix + "internal-hostname"
+ // When set on a service, per-pod DNS entries will be created.
+ ServicePodEndpoints = AnnotationKeyPrefix + "service-pod-endpoints"
)
diff --git c/source/service.go i/source/service.go
index a339b192..2bb23e11 100644
--- c/source/service.go
+++ i/source/service.go
@@ -323,6 +323,8 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
publishPodIPs := endpointsType != EndpointsTypeNodeExternalIP && endpointsType != EndpointsTypeHostIP && !sc.publishHostIP
publishNotReadyAddresses := svc.Spec.PublishNotReadyAddresses || sc.alwaysPublishNotReadyAddresses
+ _, perPodDNS := svc.Annotations[servicePodEndpointsKey]
+
targetsByHeadlessDomainAndType := make(map[endpoint.EndpointKey]endpoint.Targets)
for _, endpointSlice := range endpointSlices {
for _, ep := range endpointSlice.Endpoints {
@@ -359,6 +361,10 @@ func (sc *serviceSource) extractHeadlessEndpoints(svc *v1.Service, hostname stri
headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Spec.Hostname, hostname))
}
+ if perPodDNS {
+ headlessDomains = append(headlessDomains, fmt.Sprintf("%s.%s", pod.Name, hostname))
+ }
+
for _, headlessDomain := range headlessDomains {
targets := annotations.TargetsFromTargetAnnotation(pod.Annotations)
if len(targets) == 0 {
diff --git c/source/service_test.go i/source/service_test.go
index dd21331e..f8f14f4d 100644
--- c/source/service_test.go
+++ i/source/service_test.go
@@ -3036,6 +3036,62 @@ func TestHeadlessServices(t *testing.T) {
},
false,
},
+ {
+ "annotated Headless services create DNS name for each pod",
+ "",
+ "testing",
+ "foo",
+ v1.ServiceTypeClusterIP,
+ "",
+ "",
+ false,
+ true,
+ map[string]string{"component": "foo"},
+ map[string]string{
+ servicePodEndpointsKey: "true",
+ hostnameAnnotationKey: "service.example.org",
+ endpointsTypeAnnotationKey: EndpointsTypeNodeExternalIP,
+ },
+ map[string]string{},
+ v1.ClusterIPNone,
+ []string{"1.1.1.1", "1.1.1.2", "1.1.1.3"},
+ []string{"", "", ""},
+ map[string]string{
+ "component": "foo",
+ },
+ []string{},
+ []string{"foo1", "foo2", "foo3"},
+ []string{"", "", ""},
+ []bool{true, true, true},
+ false,
+ []v1.Node{
+ {
+ Status: v1.NodeStatus{
+ Addresses: []v1.NodeAddress{
+ {
+ Type: v1.NodeExternalIP,
+ Address: "1.2.3.4",
+ },
+ {
+ Type: v1.NodeInternalIP,
+ Address: "2001:db8::4",
+ },
+ },
+ },
+ },
+ },
+ []*endpoint.Endpoint{
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo1.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo2.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo2.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ {DNSName: "foo3.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
+ {DNSName: "foo3.service.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::4"}},
+ },
+ false,
+ },
{
"annotated Headless services return dual-stack targets from node external IP if endpoints-type annotation is set and exposeInternalIPv6 flag set",
"",
diff --git c/source/source.go i/source/source.go
index aaa2d1dc..6be7d031 100644
--- c/source/source.go
+++ i/source/source.go
@@ -38,6 +38,7 @@ const (
ingressHostnameSourceKey = annotations.IngressHostnameSourceKey
controllerAnnotationValue = annotations.ControllerValue
internalHostnameAnnotationKey = annotations.InternalHostnameKey
+ servicePodEndpointsKey = annotations.ServicePodEndpoints
EndpointsTypeNodeExternalIP = "NodeExternalIP"
EndpointsTypeHostIP = "HostIP"
2025-07-22 13:11:19 +01:00