I know this is topic that comes up every once in a while. I did read many of the existing posts and answers, bit wasn't able to figure it out.
What I need is nginx-ingress to redirect from www.foo.bar to just foo.bar. I set up a test environment on Minikube by installing the nginx ingress the minikube way: minikube addons enable ingress and put the following ingress manifest in place:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'www.foo.bar') {
return 301 https://foo.bar;
}
nginx.ingress.kubernetes.io/proxy-body-size: 600m
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.org/client-max-body-size: 600m
name: foo-ingress
spec:
rules:
- host: api.foo.bar
http:
paths:
- backend:
service:
name: identity
port:
number: 80
path: /identity
pathType: ImplementationSpecific
- backend:
service:
name: catalog
port:
number: 80
path: /catalog
pathType: ImplementationSpecific
- backend:
service:
name: marketing
port:
number: 80
path: /marketing
pathType: ImplementationSpecific
- backend:
service:
name: marketplace
port:
number: 80
path: /marketplace
pathType: ImplementationSpecific
- backend:
service:
name: notification
port:
number: 80
path: /notification
pathType: ImplementationSpecific
- backend:
service:
name: provider
port:
number: 80
path: /provider
pathType: ImplementationSpecific
- host: www.foo.bar
http:
paths:
- backend:
service:
name: frontend
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: foo.bar
http:
paths:
- backend:
service:
name: frontend
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: blog.foo.bar
http:
paths:
- backend:
service:
name: wordpress
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- foo.bar
- api.foo.bar
- blog.foo.bar
secretName: foo-cert
And it works:
➜ ~ curl -k -v -o /dev/null https://www.foo.bar
...
> GET / HTTP/2
> Host: www.foo.bar
> user-agent: curl/7.68.0
> accept: */*
>
< HTTP/2 301
< date: Sat, 27 Mar 2021 16:37:50 GMT
< content-type: text/html
< content-length: 162
< location: https://foo.bar
Now, let me get to the problem: I have a production cluster on GCP (GKE) on which I installed nginx-ingress via Helm:
helm -n nginx-ingress ls
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
nginx-ingress nginx-ingress 2 2021-03-27 15:05:41.229254628 +0000 UTC deployed nginx-ingress-0.8.1 1.10.1
The Ingress manifest I have is (I don't see a relevant difference to the one above):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.allow-http: "false"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'www.foo.bar') {
return 301 https://foo.bar;
}
nginx.ingress.kubernetes.io/proxy-body-size: 600m
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.org/client-max-body-size: 600m
name: foo-ingress
spec:
rules:
- host: api.foo.bar
http:
paths:
- backend:
service:
name: identity
port:
number: 80
path: /identity
pathType: ImplementationSpecific
- backend:
service:
name: catalog
port:
number: 80
path: /catalog
pathType: ImplementationSpecific
- backend:
service:
name: marketing
port:
number: 80
path: /marketing
pathType: ImplementationSpecific
- backend:
service:
name: marketplace
port:
number: 80
path: /marketplace
pathType: ImplementationSpecific
- backend:
service:
name: notification
port:
number: 80
path: /notification
pathType: ImplementationSpecific
- backend:
service:
name: provider
port:
number: 80
path: /provider
pathType: ImplementationSpecific
- host: foo.bar
http:
paths:
- backend:
service:
name: frontend
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: www.foo.bar
http:
paths:
- backend:
service:
name: frontend
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: blog.foo.bar
http:
paths:
- backend:
service:
name: wordpress
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- foo.bar
- api.foo.bar
- www.foo.bar
- blog.foo.bar
secretName: foo-cert
You can see, the redirect is not working:
➜ ~ curl -v -o /dev/null https://www.foo.bar
> GET / HTTP/1.1
> Host: www.foo.bar
> User-Agent: curl/7.68.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.19.8
< Date: Sat, 27 Mar 2021 16:42:18 GMT
< Content-Type: text/html
< Content-Length: 671097
< Connection: keep-alive
< Last-Modified: Tue, 09 Mar 2021 11:51:47 GMT
< ETag: "60476153-a3d79"
< Expires: Thu, 01 Jan 1970 00:00:01 GMT
< Cache-Control: no-cache
< Accept-Ranges: bytes
I noticed, that prod and Minikube deploy different images but don't really know what the difference is if there's any.
Prod:
➜ ~ kubectl -n nginx-ingress get pod nginx-ingress-nginx-ingress-68f5bc7654-kffnm -o json | jq ".spec.containers[0].image"
"nginx/nginx-ingress:1.10.1"
Minikube:
➜ ~ kubectl -n kube-system get pod ingress-nginx-controller-65cf89dc4f-xkdtn -o json | jq ".spec.containers[0].image"
"us.gcr.io/k8s-artifacts-prod/ingress-nginx/controller:v0.40.2@sha256:46ba23c3fbaafd9e5bd01ea85b2f921d9f2217be082580edc22e6c704a83f02f"
Any ideas what's going on?