Kubernetes Ingress annotation doesn't force HTTPS to backend pods

According to the documentation on the Kubernetes Ingress provide, there are three ways to tell Traefik to use HTTPS to talk to the backend pods. I can't get the third technique to work:

  1. If the ingress spec includes the annotation ingress.kubernetes.io/protocol: https.

When I include that annotation in my Ingress object, Traefik still registers the server using HTTP, not HTTPS. If I name my Kubernetes Service port "https," then Traefik uses HTTPS to talk to the pods, regardless of the presence of the annotation.

I'm using Traefik version 2.0.0-beta1. Is this documentation supposed to apply to this version?

Looking in file pkg/provider/kubernetes/ingress/kubernetes.go at the loadService function, I don't see this annotation taken into account when determining the protocol with which to contact the backend servers.

That file reference does cover Traefik version 2; it refers to the wrong branch. The location for the "v2.0" branch is here. Unfortunately, it looks like this variant still only supports the first two predicates:

  • The Endpoints port is 443
  • The Service port name starts with "https"

By the way, I think I may have written this elsewhere, but I find the first predicate rule to be surprising, and not as convenient as it could be. It's looking at the Endpoints port (which is usually the target container port), and not at the Service port. We usually deny our pods the ability to bind to privileged ports, so we'll find pods listening on, say, port 8443, with a Service in front of them listening on port 443, forwarding to port 8443.

When Traefik finds such an Endpoint, it decides that it doesn't look like it's using HTTPS, because port 8443 is obviously not port 443. However, if Traefik were to look at the Service—which it's watching and caching in memory—it could see that the Service port is 443, which is a strong hint that its clients are expecting to use HTTPS.

Was this design discussed publicly? I'm wondering if this alternate predicate was debated. I understand that Traefik is ultimately routing to Endpoints, and not Services, but for this situation the intention is better represented in the Service.

The first predicate mentioned here reads as follows:

  1. If the service port defined in the ingress spec is 443 (note that you can still use targetPort to use a different port on your pod).

That tells me that the current implementation is mistaken; the Ingress port matches the Service's front-end port, and not the port mentioned in the Endpoints. In other words, this code block is looking at the wrong port value. At line 218, the port value it's capturing is the Service's target port (the port on which the container is listening). The "portSpec" variable in scope and assigned at line 185 could be consulted instead.

Hello @seh,

The documentation is versioned. The default version of the documentation is for the latest stable version (currently 1.7.12). If you want a different version, there is a version selector on the left hand side of the documentation.

As for the forcing of https communication with backend pods:

As per the documentation for 1.7: ( https://docs.traefik.io/v1.7/configuration/backends/kubernetes/#tls-communication-between-traefik-and-backend-pods)

There are 3 ways to configure Traefik to use https to communicate with backend pods:

  1. If the service port defined in the ingress spec is 443 (note that you can still use targetPort to use a different port on your pod).
  2. If the service port defined in the ingress spec has a name that starts with https (such as https-api , https-web or just https ).
  3. If the ingress spec includes the annotation ingress.kubernetes.io/protocol: https .

All 3 of these are extensively tested, and confirmed.

For Traefik version 2, the provider has been rewritten. If you feel there is a bug in the code, feel free to open a github ticket, and reference the issue you are encountering.

Please see issue 5164.