Route traffic to a service in a different namespace with Traefik and Kubernetes

Viewed 5039

Using Traefik as an ingress controller (on a kube cluster in GCP). Is it possible to create an ingress rule that uses a backend service from a different namespace?

We have a namespace for each of our "major" versions of code.

1-service.com -> 1-service.com ingress in the 1-service ns -> 1-service svc in the same ns

2-service.com -> 2-service.com ingress in the 2-service ns... and so on

I also would like another ingress rule in the "unversioned" namespace that will route traffic to one of the major releases.

service.com -> service.com ingress in the "service" ns -> X-service in the X-service namespace

I would like to keep major versions separate in k8s using versioned host names (1-service.com etc), but still have a "latest" that points to the latest of the releases.

I believe voyager can do cross namespace ingress -> svc. can Traefik do the same??

2 Answers

You can use a workaround like this:

  1. Create a Service with type ExternalName in your namespace when you want to create an ingress:
apiVersion: v1
kind: Service
metadata:
  name: service-1
  namespace: unversioned
spec:
  type: ExternalName
  externalName: service-1.service-1-ns.svc.cluster.local
  ports:
  - name: http
    port: 8080
    protocol: TCP
  1. Create an ingress that point to this service:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: traefik
  name: ingress-to-other-ns
  namespace: service-1-ns
spec:
  rules:
  - host: latest.example.com
    http:
      paths:
      - backend:
          serviceName: service-1
          servicePort: 8080
        path: /

Just tested with the following example on EKS. Traefik is deployed in default namespace. This is the config used for the k8s service:

---
apiVersion: v1
kind: Service
metadata:
  name: 1-service
  namespace: 1-service
  labels:
    app: 1-service
spec:
  selector:
    app: 1-service
  ports:
    - name: http
      port: 80
      targetPort: 80

And this is the config used for Traefik service that will send the request to different namespace:

      services:
        1-service:
          loadBalancer:
            servers:
               - url: http://1-service.1-service.svc.cluster.local:80
               # - url: http://1-service.1-service:80 # This should work perfectly as well, didn't test it explicitly

As you probably already get that, you can reference to services from different namespace by using SERVICE.NAMESPACE notation, instead of the SERVICE, which will automatically assume that you are referencing a service from the current namespace.

Related