Traefik, K8S and an External Service

Hi all,

I've been banging my head against a wall and just need a sanity check that what I am trying to do will work.

I've configured Traefik as the only ingress controller in a K8S install on my MAC - and so far everything is great - I can see the dashboard and can create deployments and services and ingresses to the K8S install and route to them correctly using the Traefik ingress controller. Fantastic

One of the things, however when use all this knowledge in my production work is the ability to route to EXTERNAL sources as we have not started migrating all of them to containers etc just yet.

So first things first - I have a REAL cert in the local K8S environment - it's a wildcard cert and so ALL of my traffic is going to https://internal.myserver.cloud/ - note that myserver is NOT the realname :slight_smile:

I created a test.yaml that looks like this

---
kind: Service
apiVersion: v1
metadata:
  name: pm1-external  
spec:
  type: ExternalName
  ports:
  - name: https    
    port: 443   
  externalName: subdomain.otherservice.cloud

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: pm1-external-ingress  
  annotations:
    kubernetes.io/ingress.class: traefik 
    traefik.frontend.passHostHeader: "false"    
spec:    
    rules:
    - host: internal.myserver.cloud
      http:
        paths:
        - path: /pm1
          backend:
            serviceName: pm1-external
            servicePort: https

I can see that Traefik (in the dashboard at least) has added this as a frontend and is pointing to my other domain - however when I try and use it I get a 502 (bad gateway) issue.

So I thought I would try something really easy (or so I thought) and create an external service just essentially redirecting to GOOGLE


---
kind: Service
apiVersion: v1
metadata:
  name: google-external  
spec:
  type: ExternalName
  ports:
  - name: https    
    port: 443    
    targetPort: 80
  externalName: google.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: google-ingress  
  annotations:
    kubernetes.io/ingress.class: traefik 
    traefik.frontend.passHostHeader: "false"
spec:    
    rules:
    - host: internal.myserver.cloud
      http:
        paths:
        - path: /google
          backend:
            serviceName: google-external
            servicePort: https

But that gives me the same error - 502.

Am I doing something stupendously stupid here - or maybe it just does not work quite right using docker-desktop K8S - anyone point me in the right direction.

I've read everything I can find about externalNames and Traefik ingress with external names etc. and I just can't get this one piece working

Thanks in advance

1 Like

I got this working in the end - it turns out that the service part is almost irrelevant you just need to add the correct ANNOTATIONS to the ingress - for example

annotations:
    kubernetes.io/ingress.class: traefik 
    traefik.frontend.passHostHeader: "false"
    traefik.ingress.kubernetes.io/redirect-regex: ^https://internal.myserver.cloud/pm1/(.*)    
    traefik.ingress.kubernetes.io/redirect-replacement: https://subdomain.otherservice.cloud/pm1/$1
    traefik.ingress.kubernetes.io/redirect-permanent: "false"

So it's all done in the THREE redirect statements - the first is what to look FOR - i.e. this is what the 'user' will actually use as the URL, the second is where it should redirect too and the last indicates whether the server returns a 301 or 302

I think the original way should indeed work. Could any expert from Traefik check why bad gateway is the answer?

I researched a bit more. The problem with the redirect approach is that in that case the browser will be redirected directly to the new domain.

In my case this was wrong. I need to use Traefik as a proxy.
It turned out that if the externalName is an IP, Traefik will route the request there without a problem.
502 only happens if the externalName in the service definition is a domain.

Interestingly also in the case when externalName is a domain, Traeifk seams to generate the correct config. The 502 response is really strange.

Maybe it can help others if I add my use case:
My use-case was forwarding requests from inside minikube back to my host computer so that angular's express server by ng serve can run on my development machine directly.

This was my solution:

kind: Service
apiVersion: v1
metadata:
  name: hostngserve
spec:
  type: ExternalName
  ports:
    - name: http
      port: 4200
      targetPort: 4200
  externalName: 172.17.0.1
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: hostngserve-ingress
spec:
  entryPoints:
    - https
  routes:
    - match: Host(`app.nyomio.local`)
      kind: Rule
      priority: 1
      services:
        - name: hostngserve
          port: 4200
  tls:
    secretName: certsecret

where 172.17.0.1 is the local of my host computer on the interface created by docker (I use minikube with the docker driver)

I'll try by using an external IP - the issue I am going to face is that I have a wildcard certificate on the ingress and it's routing to an external service which is behind a DIFFERENT wildcard cert - so hence I needed to perform a real redirect - but in the future this might not be the case. Will let you know what I find