• Traefik & Kubernetes
    • Provider Configuration
      • endpoint
      • token
      • certAuthFilePath
      • namespaces
      • labelselector
      • ingressClass
      • throttleDuration
    • Resource Configuration
      • Traefik IngressRoute definition
      • Middleware
      • TLS Option
      • TLS
    • Further

    Traefik & Kubernetes

    The Kubernetes Ingress Controller, The Custom Resource Way.

    Traefik used to support Kubernetes only through the Kubernetes Ingress provider, which is a Kubernetes Ingress controller in the strict sense of the term.

    However, as the community expressed the need to benefit from Traefik features without resorting to (lots of) annotations,we ended up writing a Custom Resource Definition (alias CRD in the following) for an IngressRoute type, defined below, in order to provide a better way to configure access to a Kubernetes cluster.

    Provider Configuration

    endpoint

    Optional, Default=empty

    1. [providers.kubernetesCRD]
    2. endpoint = "http://localhost:8080"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. endpoint = "http://localhost:8080"
    4. # ...
    1. --providers.kubernetescrd.endpoint="http://localhost:8080"

    The Kubernetes server endpoint as URL.

    When deployed into Kubernetes, Traefik will read the environment variables KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT or KUBECONFIG to construct the endpoint.

    The access token will be looked up in /var/run/secrets/kubernetes.io/serviceaccount/token and the SSL CA certificate in /var/run/secrets/kubernetes.io/serviceaccount/ca.crt.Both are provided mounted automatically when deployed inside Kubernetes.

    The endpoint may be specified to override the environment variable values inside a cluster.

    When the environment variables are not found, Traefik will try to connect to the Kubernetes API server with an external-cluster client.In this case, the endpoint is required.Specifically, it may be set to the URL used by kubectl proxy to connect to a Kubernetes cluster using the granted authentication and authorization of the associated kubeconfig.

    token

    Optional, Default=empty

    1. [providers.kubernetesCRD]
    2. token = "mytoken"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. token = "mytoken"
    4. # ...
    1. --providers.kubernetescrd.token="mytoken"

    Bearer token used for the Kubernetes client configuration.

    certAuthFilePath

    Optional, Default=empty

    1. [providers.kubernetesCRD]
    2. certAuthFilePath = "/my/ca.crt"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. certAuthFilePath: "/my/ca.crt"
    4. # ...
    1. --providers.kubernetescrd.certauthfilepath="/my/ca.crt"

    Path to the certificate authority file.Used for the Kubernetes client configuration.

    namespaces

    Optional, Default: all namespaces (empty array)

    1. [providers.kubernetesCRD]
    2. namespaces = ["default", "production"]
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. namespaces:
    4. - "default"
    5. - "production"
    6. # ...
    1. --providers.kubernetescrd.namespaces="default,production"

    Array of namespaces to watch.

    labelselector

    Optional,Default: empty (process all Ingresses)

    1. [providers.kubernetesCRD]
    2. labelselector = "A and not B"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. labelselector: "A and not B"
    4. # ...
    1. --providers.kubernetescrd.labelselector="A and not B"

    By default, Traefik processes all Ingress objects in the configured namespaces.A label selector can be defined to filter on specific Ingress objects only.

    See label-selectors for details.

    ingressClass

    Optional, Default: empty

    1. [providers.kubernetesCRD]
    2. ingressClass = "traefik-internal"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. ingressClass: "traefik-internal"
    4. # ...
    1. --providers.kubernetescrd.ingressclass="traefik-internal"

    Value of kubernetes.io/ingress.class annotation that identifies Ingress objects to be processed.

    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.

    throttleDuration

    Optional, Default: 0 (no throttling)

    1. [providers.kubernetesCRD]
    2. throttleDuration = "10s"
    3. # ...
    1. providers:
    2. kubernetesCRD:
    3. throttleDuration: "10s"
    4. # ...
    1. --providers.kubernetescrd.throttleDuration="10s"

    Resource Configuration

    If you're in a hurry, maybe you'd rather go through the dynamic configuration reference.

    Traefik IngressRoute definition

    1. apiVersion: apiextensions.k8s.io/v1beta1
    2. kind: CustomResourceDefinition
    3. metadata:
    4. name: ingressroutes.traefik.containo.us
    5. spec:
    6. group: traefik.containo.us
    7. version: v1alpha1
    8. names:
    9. kind: IngressRoute
    10. plural: ingressroutes
    11. singular: ingressroute
    12. scope: Namespaced
    13. ---
    14. apiVersion: apiextensions.k8s.io/v1beta1
    15. kind: CustomResourceDefinition
    16. metadata:
    17. name: ingressroutetcps.traefik.containo.us
    18. spec:
    19. group: traefik.containo.us
    20. version: v1alpha1
    21. names:
    22. kind: IngressRouteTCP
    23. plural: ingressroutetcps
    24. singular: ingressroutetcp
    25. scope: Namespaced

    That IngressRoute kind can then be used to define an IngressRoute object, such as in:

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: IngressRoute
    3. metadata:
    4. name: ingressroutefoo
    5. spec:
    6. entryPoints:
    7. - web
    8. routes:
    9. # Match is the rule corresponding to an underlying router.
    10. # Later on, match could be the simple form of a path prefix, e.g. just "/bar",
    11. # but for now we only support a traefik style matching rule.
    12. - match: Host(`foo.com`) && PathPrefix(`/bar`)
    13. # kind could eventually be one of "Rule", "Path", "Host", "Method", "Header",
    14. # "Parameter", etc, to support simpler forms of rule matching, but for now we
    15. # only support "Rule".
    16. kind: Rule
    17. # (optional) Priority disambiguates rules of the same length, for route matching.
    18. priority: 12
    19. services:
    20. - name: whoami
    21. port: 80
    22. # (default 1) A weight used by the weighted round-robin strategy (WRR).
    23. weight: 1
    24. # (default true) PassHostHeader controls whether to leave the request's Host
    25. # Header as it was before it reached the proxy, or whether to let the proxy set it
    26. # to the destination (backend) host.
    27. passHostHeader: true
    28. responseForwarding:
    29. # (default 100ms) Interval between flushes of the buffered response body to the client.
    30. flushInterval: 100ms
    31. ---
    32. apiVersion: traefik.containo.us/v1alpha1
    33. kind: IngressRouteTCP
    34. metadata:
    35. name: ingressroutetcpfoo.crd
    36. spec:
    37. entryPoints:
    38. - footcp
    39. routes:
    40. # Match is the rule corresponding to an underlying router.
    41. - match: HostSNI(`*`)
    42. services:
    43. - name: whoamitcp
    44. port: 8080

    Middleware

    Additionally, to allow for the use of middlewares in an IngressRoute, we defined the CRD below for the Middleware kind.

    1. apiVersion: apiextensions.k8s.io/v1beta1
    2. kind: CustomResourceDefinition
    3. metadata:
    4. name: middlewares.traefik.containo.us
    5. spec:
    6. group: traefik.containo.us
    7. version: v1alpha1
    8. names:
    9. kind: Middleware
    10. plural: middlewares
    11. singular: middleware
    12. scope: Namespaced

    Once the Middleware kind has been registered with the Kubernetes cluster, it can then be used in IngressRoute definitions, such as:

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: Middleware
    3. metadata:
    4. name: stripprefix
    5. namespace: foo
    6. spec:
    7. stripPrefix:
    8. prefixes:
    9. - /stripit
    10. ---
    11. apiVersion: traefik.containo.us/v1alpha1
    12. kind: IngressRoute
    13. metadata:
    14. name: ingressroutebar
    15. spec:
    16. entryPoints:
    17. - web
    18. routes:
    19. - match: Host(`bar.com`) && PathPrefix(`/stripit`)
    20. kind: Rule
    21. services:
    22. - name: whoami
    23. port: 80
    24. middlewares:
    25. - name: stripprefix
    26. namespace: foo

    Cross-provider namespace

    As Kubernetes also has its own notion of namespace, one should not confuse the kubernetes namespace of a resource

    (in the reference to the middleware) with the provider namespace,when the definition of the middleware is from another provider.In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored.

    More information about available middlewares in the dedicated middlewares section.

    TLS Option

    Additionally, to allow for the use of TLS options in an IngressRoute, we defined the CRD below for the TLSOption kind.More information about TLS Options is available in the dedicated TLS Configuration Options.

    1. apiVersion: apiextensions.k8s.io/v1beta1
    2. kind: CustomResourceDefinition
    3. metadata:
    4. name: tlsoptions.traefik.containo.us
    5. spec:
    6. group: traefik.containo.us
    7. version: v1alpha1
    8. names:
    9. kind: TLSOption
    10. plural: tlsoptions
    11. singular: tlsoption
    12. scope: Namespaced

    Once the TLSOption kind has been registered with the Kubernetes cluster or defined in the File Provider, it can then be used in IngressRoute definitions, such as:

    1. apiVersion: traefik.containo.us/v1alpha1
    2. kind: TLSOption
    3. metadata:
    4. name: mytlsoption
    5. namespace: default
    6. spec:
    7. minVersion: VersionTLS12
    8. ---
    9. apiVersion: traefik.containo.us/v1alpha1
    10. kind: IngressRoute
    11. metadata:
    12. name: ingressroutebar
    13. spec:
    14. entryPoints:
    15. - web
    16. routes:
    17. - match: Host(`bar.com`) && PathPrefix(`/stripit`)
    18. kind: Rule
    19. services:
    20. - name: whoami
    21. port: 80
    22. tls:
    23. options:
    24. name: mytlsoption
    25. namespace: default

    References and namespaces

    If the optional namespace attribute is not set, the configuration will be applied with the namespace of the IngressRoute.

    Additionally, when the definition of the TLS option is from another provider,

    the cross-provider syntax ([email protected]) should be used to refer to the TLS option,just as in the middleware case.Specifying a namespace attribute in this case would not make any sense, and will be ignored.

    TLS

    To allow for TLS, we made use of the Secret kind, as it was already defined, and it can be directly used in an IngressRoute:

    1. apiVersion: v1
    2. kind: Secret
    3. metadata:
    4. name: supersecret
    5. data:
    6. tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
    7. tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
    8. ---
    9. apiVersion: traefik.containo.us/v1alpha1
    10. kind: IngressRoute
    11. metadata:
    12. name: ingressroutetls
    13. spec:
    14. entryPoints:
    15. - web
    16. routes:
    17. - match: Host(`foo.com`) && PathPrefix(`/bar`)
    18. kind: Rule
    19. services:
    20. - name: whoami
    21. port: 443
    22. tls:
    23. secretName: supersecret

    Further

    Also see the full example with Let's Encrypt.