Generating a redirect with traefik ingress on k3s?

Viewed 485

I'm running prometheus and grafana under k3s, accessible (respectively) at http://monitoring.internal/prometheus and http://monitoring.internal/grafana. The grafana Ingress object, for example, looks like:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: monitoring.internal
      http:
        paths:
          - path: /grafana
            pathType: Prefix
            backend:
              service:
                name: grafana
                port:
                  number: 3000

This works fine, except that if you land at http://monitoring.internal/, you get a 404 error. I would like requests for http://monitoring.internal/ to redirect to http://monitoring.internal/grafana. I could perhaps create another service that runs something like darkhttpd ... --forward-all http://monitoring.internal/grafana, and create an Ingress object that would map / to that service, but it seems like there ought to be a way to do this with Traefik itself.

It looks like I'm running Traefik 2.4.8 locally:

$ kubectl -n kube-system exec -it deployment/traefik -- traefik version
Version:      2.4.8
Codename:     livarot
Go version:   go1.16.2
Built:        2021-03-23T15:48:39Z
OS/Arch:      linux/amd64

I've found this documentation for 1.7 that suggests there is an annotation for exactly this purpose:

  • traefik.ingress.kubernetes.io/app-root: "/index.html": Redirects all requests for / to the defined path.

But setting that on the grafana ingress object doesn't appear to have any impact, and I haven't been able to find similar docs for 2.x (I've looked around here, for example).

What's the right way to set up this sort of redirect?

1 Answers

Since I haven't been able to figure out traefik yet, I thought I'd post my solution here in case anyone else runs into the same situation. I am hoping someone comes along who knows The Right Way to to do this, and if I figure out I'll update this answer.

I added a new deployment that runs darkhttpd as a simple director:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redirector
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: redirector
          image: docker.io/alpinelinux/darkhttpd
          ports:
            - containerPort: 8080
          args:
            - --forward-all
            - http://monitoring.internal/grafana

A corresponding Service:

apiVersion: v1
kind: Service
metadata:
  name: redirector
spec:
  ports:
    - port: 8080
      protocol: TCP
      targetPort: 8080

And the following Ingress object:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: redirector
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
    - host: monitoring.internal
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: redirector
                port:
                  number: 8080

These are all deployed with kustomize, which takes care of adding labels and selectors in the appropriate places. The kustomization.yaml look like:

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- deployment.yaml
- ingress.yaml
- service.yaml

commonLabels:
  component: redirector

With all this in place, requests to http://monitoring.internal/ hit the redirector pod.

Related