Ben Gannaway
Ben Gannaway

Reputation: 1083

Kubernetes NGINX Ingress configmap 301 redirect

Using an NGINX Ingresss in Kubernetes, I can't see a way to forward my traffic from non-www to www, or to another domain etc on a per-host basis

I've tried looking in configmap docs but can't see what I need. Maybe it can go in the ingress itself?

I've also seen an example using annotations but this seems to be ingress-wide, so I couldn't have specific redirects per host

Upvotes: 8

Views: 16077

Answers (3)

Robert Ohlídal
Robert Ohlídal

Reputation: 1

I have problem with annotations server-snippet. When the certificate is renewed, the process crashes. When I remove annotations, renewed certificate is successful. Is there another solution? For example, creating a redirect 301 in separate pod?

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt-prod
        certmanager.k8s.io/cluster-issuer: letsencrypt-prod
        ingress.kubernetes.io/ssl-redirect: "true"
        meta.helm.sh/release-name: DOMAIN
        meta.helm.sh/release-namespace: DOMAIN
        nginx.ingress.kubernetes.io/configuration-snippet: |
          location ~ ^/online-web {
            return 301 /online;
          }
          if ($host = 'DOMAIN-alias.cz') {
            return 301 https://DOMAIN.cz;
          }
          if ($host ~ ^(.+)\.DOMAIN-alias\.cz$) {
            return 301 https://$1.DOMAIN.cz$request_uri;
          }
          if ($host = 'DOMAIN-alias-2.cz') {
            return 301 https://DOMAIN.cz;
          }
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-buffer-size: 128k
    nginx.ingress.kubernetes.io/server-snippet: |
      if ($host ~ "csas.woltair.cz") {
          return 301 https://woltair.cz/zakaznik/doporuceni;
      }
............
............
  - host: csas.woltair.cz
    http:
      paths:
      - backend:
          service:
            name: woltair-cz-fe
            port:
              number: 8080
        path: /zakaznik/doporuceni
        pathType: ImplementationSpecific

Upvotes: 0

0xC0DEBA5E
0xC0DEBA5E

Reputation: 176

To redirect all traffic regardless of using HTTP or HTTPS from example.com and www.example.com to newdomain.example.com I ended up with the following solution.

In this example I'm also using cert-manager.io to request the certs for www.example.com and example.com.

The redirect is done using the annotation nginx.ingress.kubernetes.io/permanent-redirect

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: redirect-example-to-newdomain
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/permanent-redirect: https://newdomain.example.com
spec:
  tls:
    - hosts:
      - example.com
      - www.example.com
      secretName: example.com-tls
  rules:
    - host: example.com
    - host: www.example.com

Upvotes: 5

Clorichel
Clorichel

Reputation: 2070

Indeed a redirect is possible with a simple annotation:

But as you mentioned, it's "Ingress" wide and not configurable per host, per domain or even per path. So you'll have to do it yourself through the ingress.kubernetes.io/configuration-snippet annotation, which gives you a great deal of power thanks to regular expressions:

kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: self-made-redirect
  annotations:
    ingress.kubernetes.io/configuration-snippet: |
      if ($host = 'blog.yourdomain.com') {
        return 301 https://yournewblogurl.com;
      }
      if ($host ~ ^(.+)\.yourdomain\.com$) {
        return 301 https://$1.anotherdomain.com$request_uri;
      }
spec:
  rules:
  - host: ...

If you are not quite used to NGINX, you'll know more about what's possible in the snippet, particularly what is the $host variable right in the NGINX documentation.

Upvotes: 21

Related Questions