Commit b8f084a6 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #45034 from shashidharatd/federation-service-controller-3

Automatic merge from submit-queue (batch tested with PRs 45247, 45810, 45034, 45898, 45899) [Federation] Segregate DNS related code to separate controller **What this PR does / why we need it**: This is the continuation of service controller re-factor work as outlined in #41253 This PR segregates DNS related code from service controller to another controller `service-dns controller` which manages the DNS records on the configured DNS provider. `service-dns controller` monitors the federated services for the ingress annotations and create/update/delete DNS records accordingly. `service-dns controller` can be optionally disabled and DNS record management could be done by third party components by monitoring the ingress annotations on federated services. (This would enable something like federation middleware for CoreDNS where federation api server could be used as a backend to CoreDNS eliminating the need for etcd storage.) **Special notes for your reviewer**: **Release note**: ``` Federation: A new controller for managing DNS records is introduced which can be optionally disabled to enable third party components to manage DNS records for federated services. ``` cc @kubernetes/sig-federation-pr-reviews
parents 79dae5c0 c9454f81
...@@ -18,7 +18,6 @@ go_library( ...@@ -18,7 +18,6 @@ go_library(
deps = [ deps = [
"//federation/client/clientset_generated/federation_clientset:go_default_library", "//federation/client/clientset_generated/federation_clientset:go_default_library",
"//federation/cmd/federation-controller-manager/app/options:go_default_library", "//federation/cmd/federation-controller-manager/app/options:go_default_library",
"//federation/pkg/dnsprovider:go_default_library",
"//federation/pkg/dnsprovider/providers/aws/route53:go_default_library", "//federation/pkg/dnsprovider/providers/aws/route53:go_default_library",
"//federation/pkg/dnsprovider/providers/coredns:go_default_library", "//federation/pkg/dnsprovider/providers/coredns:go_default_library",
"//federation/pkg/dnsprovider/providers/google/clouddns:go_default_library", "//federation/pkg/dnsprovider/providers/google/clouddns:go_default_library",
......
...@@ -35,7 +35,6 @@ import ( ...@@ -35,7 +35,6 @@ import (
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset" federationclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset"
"k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options" "k8s.io/kubernetes/federation/cmd/federation-controller-manager/app/options"
"k8s.io/kubernetes/federation/pkg/dnsprovider"
"k8s.io/kubernetes/federation/pkg/federatedtypes" "k8s.io/kubernetes/federation/pkg/federatedtypes"
clustercontroller "k8s.io/kubernetes/federation/pkg/federation-controller/cluster" clustercontroller "k8s.io/kubernetes/federation/pkg/federation-controller/cluster"
deploymentcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/deployment" deploymentcontroller "k8s.io/kubernetes/federation/pkg/federation-controller/deployment"
...@@ -137,17 +136,20 @@ func StartControllers(s *options.CMServer, restClientCfg *restclient.Config) err ...@@ -137,17 +136,20 @@ func StartControllers(s *options.CMServer, restClientCfg *restclient.Config) err
clustercontroller.StartClusterController(restClientCfg, stopChan, s.ClusterMonitorPeriod.Duration) clustercontroller.StartClusterController(restClientCfg, stopChan, s.ClusterMonitorPeriod.Duration)
if controllerEnabled(s.Controllers, serverResources, servicecontroller.ControllerName, servicecontroller.RequiredResources, true) { if controllerEnabled(s.Controllers, serverResources, servicecontroller.ControllerName, servicecontroller.RequiredResources, true) {
dns, err := dnsprovider.InitDnsProvider(s.DnsProvider, s.DnsConfigFile) if controllerEnabled(s.Controllers, serverResources, servicecontroller.DNSControllerName, servicecontroller.RequiredResources, true) {
if err != nil { serviceDNScontrollerClientset := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, servicecontroller.DNSUserAgentName))
glog.Fatalf("Cloud provider could not be initialized: %v", err) serviceDNSController, err := servicecontroller.NewServiceDNSController(serviceDNScontrollerClientset, s.DnsProvider, s.DnsConfigFile, s.FederationName, s.ServiceDnsSuffix, s.ZoneName, s.ZoneID)
if err != nil {
glog.Fatalf("Failed to start service dns controller: %v", err)
} else {
go serviceDNSController.DNSControllerRun(s.ConcurrentServiceSyncs, wait.NeverStop)
}
} }
glog.V(3).Infof("Loading client config for service controller %q", servicecontroller.UserAgentName) glog.V(3).Infof("Loading client config for service controller %q", servicecontroller.UserAgentName)
scClientset := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, servicecontroller.UserAgentName)) scClientset := federationclientset.NewForConfigOrDie(restclient.AddUserAgent(restClientCfg, servicecontroller.UserAgentName))
servicecontroller := servicecontroller.New(scClientset, dns, s.FederationName, s.ServiceDnsSuffix, s.ZoneName, s.ZoneID) serviceController := servicecontroller.New(scClientset)
glog.V(3).Infof("Running service controller") go serviceController.Run(s.ConcurrentServiceSyncs, wait.NeverStop)
if err := servicecontroller.Run(s.ConcurrentServiceSyncs, wait.NeverStop); err != nil {
glog.Fatalf("Failed to start service controller: %v", err)
}
} }
if controllerEnabled(s.Controllers, serverResources, namespacecontroller.ControllerName, namespacecontroller.RequiredResources, true) { if controllerEnabled(s.Controllers, serverResources, namespacecontroller.ControllerName, namespacecontroller.RequiredResources, true) {
......
...@@ -19,7 +19,6 @@ go_library( ...@@ -19,7 +19,6 @@ go_library(
deps = [ deps = [
"//federation/apis/federation:go_default_library", "//federation/apis/federation:go_default_library",
"//federation/apis/federation/v1beta1:go_default_library", "//federation/apis/federation/v1beta1:go_default_library",
"//federation/client/cache:go_default_library",
"//federation/client/clientset_generated/federation_clientset:go_default_library", "//federation/client/clientset_generated/federation_clientset:go_default_library",
"//federation/pkg/dnsprovider:go_default_library", "//federation/pkg/dnsprovider:go_default_library",
"//federation/pkg/dnsprovider/rrstype:go_default_library", "//federation/pkg/dnsprovider/rrstype:go_default_library",
......
...@@ -50,13 +50,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -50,13 +50,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithSingleLBIngress", name: "ServiceWithSingleLBIngress",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
Annotations: map[string]string{ AddEndpoints(cluster2Name, []string{}).
FederatedServiceIngressAnnotation: NewFederatedServiceIngress(). String()},
AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -73,10 +71,7 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -73,10 +71,7 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "withname", name: "withname",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{},
Name: "servicename",
Namespace: "servicenamespace",
},
}, },
expected: []string{ expected: []string{
"example.com:"+globalDNSName+":A:180:[198.51.100.1]", "example.com:"+globalDNSName+":A:180:[198.51.100.1]",
...@@ -88,9 +83,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -88,9 +83,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithNoLBIngress", name: "ServiceWithNoLBIngress",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{}).
AddEndpoints(cluster2Name, []string{}).
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -103,14 +100,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -103,14 +100,11 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithMultipleLBIngress", name: "ServiceWithMultipleLBIngress",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
Annotations: map[string]string{ AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
FederatedServiceIngressAnnotation: NewFederatedServiceIngress(). String()},
AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -124,14 +118,12 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -124,14 +118,12 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithLBIngressAndServiceDeleted", name: "ServiceWithLBIngressAndServiceDeleted",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
String()},
DeletionTimestamp: &metav1.Time{Time: time.Now()}, DeletionTimestamp: &metav1.Time{Time: time.Now()},
Annotations: map[string]string{
FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -145,15 +137,12 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -145,15 +137,12 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithMultipleLBIngressAndOneLBIngressGettingRemoved", name: "ServiceWithMultipleLBIngressAndOneLBIngressGettingRemoved",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
Annotations: map[string]string{ AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
FederatedServiceIngressAnnotation: NewFederatedServiceIngress(). RemoveEndpoint(cluster2Name, "198.51.200.1").
AddEndpoints(cluster1Name, []string{"198.51.100.1"}). String()},
AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
RemoveEndpoint(cluster2Name, "198.51.200.1").
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -167,16 +156,13 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -167,16 +156,13 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
{ {
name: "ServiceWithMultipleLBIngressAndAllLBIngressGettingRemoved", name: "ServiceWithMultipleLBIngressAndAllLBIngressGettingRemoved",
service: v1.Service{ service: v1.Service{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{
Name: "servicename", FederatedServiceIngressAnnotation: NewFederatedServiceIngress().
Namespace: "servicenamespace", AddEndpoints(cluster1Name, []string{"198.51.100.1"}).
Annotations: map[string]string{ AddEndpoints(cluster2Name, []string{"198.51.200.1"}).
FederatedServiceIngressAnnotation: NewFederatedServiceIngress(). RemoveEndpoint(cluster1Name, "198.51.100.1").
AddEndpoints(cluster1Name, []string{"198.51.100.1"}). RemoveEndpoint(cluster2Name, "198.51.200.1").
AddEndpoints(cluster2Name, []string{"198.51.200.1"}). String()},
RemoveEndpoint(cluster1Name, "198.51.100.1").
RemoveEndpoint(cluster2Name, "198.51.200.1").
String()},
}, },
}, },
expected: []string{ expected: []string{
...@@ -195,22 +181,30 @@ func TestServiceController_ensureDnsRecords(t *testing.T) { ...@@ -195,22 +181,30 @@ func TestServiceController_ensureDnsRecords(t *testing.T) {
} }
fakeClient := &fakefedclientset.Clientset{} fakeClient := &fakefedclientset.Clientset{}
RegisterFakeClusterGet(&fakeClient.Fake, &v1beta1.ClusterList{Items: []v1beta1.Cluster{*cluster1, *cluster2}}) RegisterFakeClusterGet(&fakeClient.Fake, &v1beta1.ClusterList{Items: []v1beta1.Cluster{*cluster1, *cluster2}})
serviceController := ServiceController{ d := ServiceDNSController{
federationClient: fakeClient, federationClient: fakeClient,
dns: fakedns, dns: fakedns,
dnsZones: fakednsZones, dnsZones: fakednsZones,
serviceDnsSuffix: "federation.example.com", serviceDNSSuffix: "federation.example.com",
zoneName: "example.com", zoneName: "example.com",
federationName: "myfederation", federationName: "myfederation",
} }
err := serviceController.ensureDnsRecords(cluster1Name, &test.service) dnsZones, err := getDNSZones(d.zoneName, d.zoneID, d.dnsZones)
if err != nil { if err != nil {
t.Errorf("Test failed for %s, unexpected error %v", test.name, err) t.Errorf("Test failed for %s, Get DNS Zones failed: %v", test.name, err)
} }
err = serviceController.ensureDnsRecords(cluster2Name, &test.service) d.dnsZone = dnsZones[0]
test.service.Name = "servicename"
test.service.Namespace = "servicenamespace"
ingress, err := ParseFederatedServiceIngress(&test.service)
if err != nil { if err != nil {
t.Errorf("Test failed for %s, unexpected error %v", test.name, err) t.Errorf("Error in parsing lb ingress for service %s/%s: %v", test.service.Namespace, test.service.Name, err)
return
}
for _, clusterIngress := range ingress.Items {
d.ensureDNSRecords(clusterIngress.Cluster, &test.service)
} }
zones, err := fakednsZones.List() zones, err := fakednsZones.List()
......
...@@ -32,7 +32,6 @@ import ( ...@@ -32,7 +32,6 @@ import (
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
"k8s.io/kubernetes/federation/apis/federation/v1beta1" "k8s.io/kubernetes/federation/apis/federation/v1beta1"
fakefedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset/fake" fakefedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_clientset/fake"
"k8s.io/kubernetes/federation/pkg/dnsprovider/providers/google/clouddns" // Only for unit testing purposes.
fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util" fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
. "k8s.io/kubernetes/federation/pkg/federation-controller/util/test" . "k8s.io/kubernetes/federation/pkg/federation-controller/util/test"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
...@@ -101,8 +100,7 @@ func TestServiceController(t *testing.T) { ...@@ -101,8 +100,7 @@ func TestServiceController(t *testing.T) {
} }
} }
fakedns, _ := clouddns.NewFakeInterface() sc := New(fedClient)
sc := New(fedClient, fakedns, "myfederation", "federation.example.com", "example.com", "")
ToFederatedInformerForTestOnly(sc.federatedInformer).SetClientFactory(fedInformerClientFactory) ToFederatedInformerForTestOnly(sc.federatedInformer).SetClientFactory(fedInformerClientFactory)
ToFederatedInformerForTestOnly(sc.endpointFederatedInformer).SetClientFactory(fedInformerClientFactory) ToFederatedInformerForTestOnly(sc.endpointFederatedInformer).SetClientFactory(fedInformerClientFactory)
sc.clusterAvailableDelay = 100 * time.Millisecond sc.clusterAvailableDelay = 100 * time.Millisecond
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment