mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 17:46:57 +02:00
Support dns-controller compat mode for pod source
This commit is contained in:
parent
7a16ab46fa
commit
73469a0852
@ -284,7 +284,7 @@ Here's a rough outline on what is to come (subject to change):
|
|||||||
|
|
||||||
- [ ] Ability to replace Kops' [DNS Controller](https://github.com/kubernetes/kops/tree/HEAD/dns-controller)
|
- [ ] Ability to replace Kops' [DNS Controller](https://github.com/kubernetes/kops/tree/HEAD/dns-controller)
|
||||||
- [x] Add support for pod source
|
- [x] Add support for pod source
|
||||||
- [ ] Add support for DNS Controller annotations for pod, ingress, and service sources
|
- [x] Add support for DNS Controller annotations for pod and service sources
|
||||||
- [ ] Add support for kOps gossip provider
|
- [ ] Add support for kOps gossip provider
|
||||||
- [x] Ability to replace Zalando's [Mate](https://github.com/linki/mate)
|
- [x] Ability to replace Zalando's [Mate](https://github.com/linki/mate)
|
||||||
- [x] Ability to replace Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes)
|
- [x] Ability to replace Molecule Software's [route53-kubernetes](https://github.com/wearemolecule/route53-kubernetes)
|
||||||
|
@ -34,14 +34,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type podSource struct {
|
type podSource struct {
|
||||||
client kubernetes.Interface
|
client kubernetes.Interface
|
||||||
namespace string
|
namespace string
|
||||||
podInformer coreinformers.PodInformer
|
podInformer coreinformers.PodInformer
|
||||||
nodeInformer coreinformers.NodeInformer
|
nodeInformer coreinformers.NodeInformer
|
||||||
|
compatibility string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPodSource creates a new podSource with the given config.
|
// NewPodSource creates a new podSource with the given config.
|
||||||
func NewPodSource(kubeClient kubernetes.Interface, namespace string) (Source, error) {
|
func NewPodSource(kubeClient kubernetes.Interface, namespace string, compatibility string) (Source, error) {
|
||||||
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace))
|
informerFactory := kubeinformers.NewSharedInformerFactoryWithOptions(kubeClient, 0, kubeinformers.WithNamespace(namespace))
|
||||||
podInformer := informerFactory.Core().V1().Pods()
|
podInformer := informerFactory.Core().V1().Pods()
|
||||||
nodeInformer := informerFactory.Core().V1().Nodes()
|
nodeInformer := informerFactory.Core().V1().Nodes()
|
||||||
@ -71,10 +72,11 @@ func NewPodSource(kubeClient kubernetes.Interface, namespace string) (Source, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &podSource{
|
return &podSource{
|
||||||
client: kubeClient,
|
client: kubeClient,
|
||||||
podInformer: podInformer,
|
podInformer: podInformer,
|
||||||
nodeInformer: nodeInformer,
|
nodeInformer: nodeInformer,
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
|
compatibility: compatibility,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +116,28 @@ func (ps *podSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ps.compatibility == "dns-controller" {
|
||||||
|
if domain, ok := pod.Annotations[dnsControllerInternalHostnameAnnotationKey]; ok {
|
||||||
|
if _, ok := domains[domain]; !ok {
|
||||||
|
domains[domain] = []string{}
|
||||||
|
}
|
||||||
|
domains[domain] = append(domains[domain], pod.Status.PodIP)
|
||||||
|
}
|
||||||
|
|
||||||
|
if domain, ok := pod.Annotations[dnsControllerHostnameAnnotationKey]; ok {
|
||||||
|
if _, ok := domains[domain]; !ok {
|
||||||
|
domains[domain] = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
node, _ := ps.nodeInformer.Lister().Get(pod.Spec.NodeName)
|
||||||
|
for _, address := range node.Status.Addresses {
|
||||||
|
if address.Type == corev1.NodeExternalIP {
|
||||||
|
domains[domain] = append(domains[domain], address.Address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
endpoints := []*endpoint.Endpoint{}
|
endpoints := []*endpoint.Endpoint{}
|
||||||
for domain, targets := range domains {
|
for domain, targets := range domains {
|
||||||
|
@ -32,6 +32,7 @@ func TestPodSource(t *testing.T) {
|
|||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
title string
|
title string
|
||||||
targetNamespace string
|
targetNamespace string
|
||||||
|
compatibility string
|
||||||
expected []*endpoint.Endpoint
|
expected []*endpoint.Endpoint
|
||||||
expectError bool
|
expectError bool
|
||||||
nodes []*corev1.Node
|
nodes []*corev1.Node
|
||||||
@ -40,6 +41,7 @@ func TestPodSource(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"create records based on pod's external and internal IPs",
|
"create records based on pod's external and internal IPs",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
[]*endpoint.Endpoint{
|
[]*endpoint.Endpoint{
|
||||||
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA},
|
||||||
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}, RecordType: endpoint.RecordTypeA},
|
||||||
@ -106,9 +108,80 @@ func TestPodSource(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"create records based on pod's external and internal IPs using DNS Controller annotations",
|
||||||
|
"",
|
||||||
|
"dns-controller",
|
||||||
|
[]*endpoint.Endpoint{
|
||||||
|
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}, RecordType: endpoint.RecordTypeA},
|
||||||
|
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}, RecordType: endpoint.RecordTypeA},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
[]*corev1.Node{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "my-node1",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Addresses: []corev1.NodeAddress{
|
||||||
|
{Type: corev1.NodeExternalIP, Address: "54.10.11.1"},
|
||||||
|
{Type: corev1.NodeInternalIP, Address: "10.0.1.1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "my-node2",
|
||||||
|
},
|
||||||
|
Status: corev1.NodeStatus{
|
||||||
|
Addresses: []corev1.NodeAddress{
|
||||||
|
{Type: corev1.NodeExternalIP, Address: "54.10.11.2"},
|
||||||
|
{Type: corev1.NodeInternalIP, Address: "10.0.1.2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[]*corev1.Pod{
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "my-pod1",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
dnsControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org",
|
||||||
|
dnsControllerHostnameAnnotationKey: "a.foo.example.org",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
HostNetwork: true,
|
||||||
|
NodeName: "my-node1",
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
PodIP: "10.0.1.1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "my-pod2",
|
||||||
|
Namespace: "kube-system",
|
||||||
|
Annotations: map[string]string{
|
||||||
|
dnsControllerInternalHostnameAnnotationKey: "internal.a.foo.example.org",
|
||||||
|
dnsControllerHostnameAnnotationKey: "a.foo.example.org",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
HostNetwork: true,
|
||||||
|
NodeName: "my-node2",
|
||||||
|
},
|
||||||
|
Status: corev1.PodStatus{
|
||||||
|
PodIP: "10.0.1.2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"create multiple records",
|
"create multiple records",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
[]*endpoint.Endpoint{
|
[]*endpoint.Endpoint{
|
||||||
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
||||||
{DNSName: "b.foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "b.foo.example.org", Targets: endpoint.Targets{"54.10.11.2"}, RecordType: endpoint.RecordTypeA},
|
||||||
@ -176,6 +249,7 @@ func TestPodSource(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"pods with hostNetwore=false should be ignored",
|
"pods with hostNetwore=false should be ignored",
|
||||||
"",
|
"",
|
||||||
|
"",
|
||||||
[]*endpoint.Endpoint{
|
[]*endpoint.Endpoint{
|
||||||
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
||||||
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA},
|
||||||
@ -245,6 +319,7 @@ func TestPodSource(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"only watch a given namespace",
|
"only watch a given namespace",
|
||||||
"kube-system",
|
"kube-system",
|
||||||
|
"",
|
||||||
[]*endpoint.Endpoint{
|
[]*endpoint.Endpoint{
|
||||||
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "a.foo.example.org", Targets: endpoint.Targets{"54.10.11.1"}, RecordType: endpoint.RecordTypeA},
|
||||||
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA},
|
{DNSName: "internal.a.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}, RecordType: endpoint.RecordTypeA},
|
||||||
@ -332,7 +407,7 @@ func TestPodSource(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := NewPodSource(kubernetes, tc.targetNamespace)
|
client, err := NewPodSource(kubernetes, tc.targetNamespace, tc.compatibility)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
endpoints, err := client.Endpoints(ctx)
|
endpoints, err := client.Endpoints(ctx)
|
||||||
|
@ -193,7 +193,7 @@ func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, err
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewPodSource(client, cfg.Namespace)
|
return NewPodSource(client, cfg.Namespace, cfg.Compatibility)
|
||||||
case "istio-gateway":
|
case "istio-gateway":
|
||||||
kubernetesClient, err := p.KubeClient()
|
kubernetesClient, err := p.KubeClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user