Support canary weight for external name service
This commit is contained in:
parent
fa562dc916
commit
057498ed01
4 changed files with 61 additions and 7 deletions
|
@ -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)
|
||||
|
|
|
@ -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"),
|
||||
),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue