From 56fe023a12a6fc6225593149eea95cb5db3f5045 Mon Sep 17 00:00:00 2001 From: Rene Treffer Date: Fri, 22 Jun 2018 16:54:03 +0200 Subject: [PATCH] Allow any kubernetes ingressClass value --- docs/configuration/backends/kubernetes.md | 2 - docs/user-guide/kubernetes.md | 8 +-- provider/kubernetes/kubernetes.go | 6 --- provider/kubernetes/kubernetes_test.go | 63 ++++++++++++++++++++--- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/docs/configuration/backends/kubernetes.md b/docs/configuration/backends/kubernetes.md index cd4ea8fbb..fe66aa245 100644 --- a/docs/configuration/backends/kubernetes.md +++ b/docs/configuration/backends/kubernetes.md @@ -54,8 +54,6 @@ See also [Kubernetes user guide](/user-guide/kubernetes). # If the parameter is non-empty, only Ingresses containing an annotation with the same value are processed. # Otherwise, Ingresses missing the annotation, having an empty value, or the value `traefik` are processed. # -# Note : `ingressClass` option must begin with the "traefik" prefix. -# # Optional # Default: empty # diff --git a/docs/user-guide/kubernetes.md b/docs/user-guide/kubernetes.md index 2cd6f2c5f..22edc4f73 100644 --- a/docs/user-guide/kubernetes.md +++ b/docs/user-guide/kubernetes.md @@ -859,12 +859,14 @@ Sometimes Træfik runs along other Ingress controller implementations. One such The `kubernetes.io/ingress.class` annotation can be attached to any Ingress object in order to control whether Træfik should handle it. If the annotation is missing, contains an empty value, or the value `traefik`, then the Træfik controller will take responsibility and process the associated Ingress object. -If the annotation contains any other value (usually the name of a different Ingress controller), Træfik will ignore the object. -It is also possible to set the `ingressClass` option in Træfik to a particular value. -If that's the case and the value contains a `traefik` prefix, then only those Ingress objects matching the same value will be processed. +It is also possible to set the `ingressClass` option in Træfik to a particular value. Træfik will only process matching Ingress objects. For instance, setting the option to `traefik-internal` causes Træfik to process Ingress objects with the same `kubernetes.io/ingress.class` annotation value, ignoring all other objects (including those with a `traefik` value, empty value, and missing annotation). +!!! note + Letting multiple ingress controllers handle the same ingress objects can lead to unintended behavior. + It is recommended to prefix all ingressClass values with `traefik` to avoid unintended collisions with other ingress implementations. + ### Between multiple Træfik Deployments Sometimes multiple Træfik Deployments are supposed to run concurrently. diff --git a/provider/kubernetes/kubernetes.go b/provider/kubernetes/kubernetes.go index 63384de65..8a6f3d019 100644 --- a/provider/kubernetes/kubernetes.go +++ b/provider/kubernetes/kubernetes.go @@ -100,12 +100,6 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s return err } - // We require that IngressClasses start with `traefik` to reduce chances of - // conflict with other Ingress Providers - if len(p.IngressClass) > 0 && !strings.HasPrefix(p.IngressClass, traefikDefaultIngressClass) { - return fmt.Errorf("value for IngressClass has to be empty or start with the prefix %q, instead found %q", traefikDefaultIngressClass, p.IngressClass) - } - log.Debugf("Using Ingress label selector: %q", p.LabelSelector) k8sClient, err := p.newK8sClient(p.LabelSelector) if err != nil { diff --git a/provider/kubernetes/kubernetes_test.go b/provider/kubernetes/kubernetes_test.go index 6313023a0..5974e5139 100644 --- a/provider/kubernetes/kubernetes_test.go +++ b/provider/kubernetes/kubernetes_test.go @@ -1165,8 +1165,17 @@ func TestIngressClassAnnotation(t *testing.T) { iAnnotation(annotationKubernetesIngressClass, traefikDefaultIngressClass+"-other"), iRules( iRule( - iHost("herp"), - iPaths(onePath(iPath("/derp"), iBackend("service1", intstr.FromInt(80))))), + iHost("foo"), + iPaths(onePath(iPath("/bar"), iBackend("service1", intstr.FromInt(80))))), + ), + ), + buildIngress( + iNamespace("testing"), + iAnnotation(annotationKubernetesIngressClass, "custom"), + iRules( + iRule( + iHost("foo"), + iPaths(onePath(iPath("/bar"), iBackend("service2", intstr.FromInt(80))))), ), ), } @@ -1182,12 +1191,32 @@ func TestIngressClassAnnotation(t *testing.T) { sExternalName("example.com"), sPorts(sPort(80, "http"))), ), + buildService( + sName("service2"), + sNamespace("testing"), + sUID("2"), + sSpec( + clusterIP("10.0.0.2"), + sPorts(sPort(80, "http"))), + ), + } + + endpoints := []*corev1.Endpoints{ + buildEndpoint( + eName("service2"), + eUID("1"), + eNamespace("testing"), + subset( + eAddresses(eAddress("10.10.0.1")), + ePorts(ePort(80, "http"))), + ), } watchChan := make(chan interface{}) client := clientMock{ ingresses: ingresses, services: services, + endpoints: endpoints, watchChan: watchChan, } @@ -1247,19 +1276,39 @@ func TestIngressClassAnnotation(t *testing.T) { provider: Provider{IngressClass: traefikDefaultRealm + "-other"}, expected: buildConfiguration( backends( - backend("herp/derp", + backend("foo/bar", servers( - server("http://example.com", weight(1)), server("http://example.com", weight(1))), lbMethod("wrr"), ), ), frontends( - frontend("herp/derp", + frontend("foo/bar", passHostHeader(), routes( - route("/derp", "PathPrefix:/derp"), - route("herp", "Host:herp")), + route("/bar", "PathPrefix:/bar"), + route("foo", "Host:foo")), + ), + ), + ), + }, + { + desc: "Provided IngressClass annotation", + provider: Provider{IngressClass: "custom"}, + expected: buildConfiguration( + backends( + backend("foo/bar", + servers( + server("http://10.10.0.1:80", weight(1))), + lbMethod("wrr"), + ), + ), + frontends( + frontend("foo/bar", + passHostHeader(), + routes( + route("/bar", "PathPrefix:/bar"), + route("foo", "Host:foo")), ), ), ),