diff --git a/old/provider/kubernetes/kubernetes.go b/old/provider/kubernetes/kubernetes.go index 9377eee7b..b201bd21c 100644 --- a/old/provider/kubernetes/kubernetes.go +++ b/old/provider/kubernetes/kubernetes.go @@ -357,15 +357,16 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error) continue } - if service.Spec.Type == "ExternalName" { + // We have to treat external-name service differently here b/c it doesn't have any endpoints + if service.Spec.Type == corev1.ServiceTypeExternalName { url := protocol + "://" + service.Spec.ExternalName if port.Port != 443 && port.Port != 80 { url = fmt.Sprintf("%s:%d", url, port.Port) } - + externalNameServiceWeight := weightAllocator.getWeight(r.Host, pa.Path, pa.Backend.ServiceName) templateObjects.Backends[baseName].Servers[url] = types.Server{ URL: url, - Weight: label.DefaultWeight, + Weight: externalNameServiceWeight, } } else { endpoints, exists, err := k8sClient.GetEndpoints(service.Namespace, service.Name) diff --git a/old/provider/kubernetes/kubernetes_test.go b/old/provider/kubernetes/kubernetes_test.go index b52a7ed6c..941e88dff 100644 --- a/old/provider/kubernetes/kubernetes_test.go +++ b/old/provider/kubernetes/kubernetes_test.go @@ -3232,6 +3232,7 @@ func TestPercentageWeightServiceAnnotation(t *testing.T) { buildIngress( iAnnotation(annotationKubernetesServiceWeights, ` service1: 10% +service3: 20% `), iNamespace("testing"), iRules( @@ -3240,6 +3241,7 @@ service1: 10% iPaths( onePath(iPath("/foo"), iBackend("service1", intstr.FromString("8080"))), onePath(iPath("/foo"), iBackend("service2", intstr.FromString("7070"))), + onePath(iPath("/foo"), iBackend("service3", intstr.FromString("9090"))), onePath(iPath("/bar"), iBackend("service2", intstr.FromString("7070"))), )), ), @@ -3264,6 +3266,16 @@ service1: 10% sPorts(sPort(7070, "")), ), ), + buildService( + sName("service3"), + sNamespace("testing"), + sUID("1"), + sSpec( + sType(corev1.ServiceTypeExternalName), + sExternalName("example.com"), + sPorts(sPort(9090, "")), + ), + ), } endpoints := []*corev1.Endpoints{ @@ -3311,8 +3323,9 @@ service1: 10% servers( server("http://10.10.0.1:8080", weight(int(newPercentageValueFromFloat64(0.05)))), server("http://10.10.0.2:8080", weight(int(newPercentageValueFromFloat64(0.05)))), - server("http://10.10.0.3:7070", weight(int(newPercentageValueFromFloat64(0.45)))), - server("http://10.10.0.4:7070", weight(int(newPercentageValueFromFloat64(0.45)))), + server("http://10.10.0.3:7070", weight(int(newPercentageValueFromFloat64(0.35)))), + server("http://10.10.0.4:7070", weight(int(newPercentageValueFromFloat64(0.35)))), + server("http://example.com:9090", weight(int(newPercentageValueFromFloat64(0.2)))), ), lbMethod("wrr"), ), diff --git a/old/provider/kubernetes/weight_allocator.go b/old/provider/kubernetes/weight_allocator.go index 60773256a..2748c12a5 100644 --- a/old/provider/kubernetes/weight_allocator.go +++ b/old/provider/kubernetes/weight_allocator.go @@ -7,6 +7,7 @@ import ( "github.com/containous/traefik/old/provider/label" "gopkg.in/yaml.v2" + corev1 "k8s.io/api/core/v1" extensionsv1beta1 "k8s.io/api/extensions/v1beta1" ) @@ -165,6 +166,23 @@ func getServiceInstanceCounts(ingress *extensionsv1beta1.Ingress, client Client) for _, rule := range ingress.Spec.Rules { for _, pa := range rule.HTTP.Paths { + svc, exists, err := client.GetService(ingress.Namespace, pa.Backend.ServiceName) + if err != nil { + return nil, fmt.Errorf("failed to get service %s/%s: %v", ingress.Namespace, pa.Backend.ServiceName, err) + } + if !exists { + return nil, fmt.Errorf("service not found for %s/%s", ingress.Namespace, pa.Backend.ServiceName) + } + if svc.Spec.Type == corev1.ServiceTypeExternalName { + // external-name service has only one instance b/c it will actually be interpreted as a DNS record + // instead of real server. + serviceInstanceCounts[ingressService{ + host: rule.Host, + path: pa.Path, + service: pa.Backend.ServiceName, + }] = 1 + continue + } count := 0 endpoints, exists, err := client.GetEndpoints(ingress.Namespace, pa.Backend.ServiceName) if err != nil { diff --git a/old/provider/kubernetes/weight_allocator_test.go b/old/provider/kubernetes/weight_allocator_test.go index 712d51311..d3b4a45da 100644 --- a/old/provider/kubernetes/weight_allocator_test.go +++ b/old/provider/kubernetes/weight_allocator_test.go @@ -169,6 +169,24 @@ service1: 1000% func TestComputeServiceWeights(t *testing.T) { client := clientMock{ + services: []*corev1.Service{ + buildService( + sName("service1"), + sNamespace("testing"), + ), + buildService( + sName("service2"), + sNamespace("testing"), + ), + buildService( + sName("service3"), + sNamespace("testing"), + ), + buildService( + sName("service4"), + sNamespace("testing"), + ), + }, endpoints: []*corev1.Endpoints{ buildEndpoint( eNamespace("testing"), @@ -446,8 +464,12 @@ service2: 80% if test.expectError { require.Error(t, err) } else { - for ingSvc, percentage := range test.expectedWeights { - assert.Equal(t, int(percentage), weightAllocator.getWeight(ingSvc.host, ingSvc.path, ingSvc.service)) + if err != nil { + t.Errorf("%v failed: %v", test.desc, err) + } else { + for ingSvc, percentage := range test.expectedWeights { + assert.Equal(t, int(percentage), weightAllocator.getWeight(ingSvc.host, ingSvc.path, ingSvc.service)) + } } } })