#redirect #kubernetes #kubernetes-ingress #minikube #nginx-ingress
#перенаправление #kubernetes #kubernetes-вход #minikube #nginx-вход
Вопрос:
Я знаю, что эта тема возникает время от времени. Я прочитал многие существующие сообщения и ответы, бит не смог разобраться.
Что мне нужно, так это nginx-вход для перенаправления с www.foo.bar
just на just foo.bar
. Я настроил тестовую среду на Minikube, установив вход nginx способом minikube: minikube addons enable ingress
и поместил на место следующий входной манифест:
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
И это работает:
➜ ~ 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
Теперь позвольте мне перейти к проблеме: у меня есть производственный кластер на GCP (GKE), на который я установил nginx-вход через 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
У меня есть входной манифест (я не вижу существенной разницы с приведенным выше):
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
Вы можете видеть, перенаправление не работает:
➜ ~ 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
Я заметил, что prod и Minikube развертывают разные образы, но на самом деле не знаю, в чем разница, если она есть.
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"
Есть идеи, что происходит?
Ответ №1:
Причина, по которой это происходит, заключается в том, что вы развернули другую версию входного контроллера nginx, вызываемого nginxinc
в вашем кластере GKE. Это очень распространенная ошибка, особенно если вы используете helm, который вы на самом деле не проверяете, который вы развертываете.
Таким образом, kubernetes / ingress-nginx, который вы использовали в minikube, поддерживается сообществом Kubernetes с открытым исходным кодом, а nginxinc / kubernetes-ingress поддерживается NGINX, Inc. Вы заметите много случаев, когда тот, который поддерживается Kubernetes, будет обычно называться контроллером входа в сообщество, а второй — контроллером NGINX.
Вы можете найти различия здесь, но основное, что вызывает у вас проблемы, заключается в том, что они оба используют различную формулу аннотации с разным префиксом. Например:
- Контроллер входа в сообщество использует:
nginx.ingress.kubernetes.io/server-snippet
- Использование NGINX:
nginx.org/server-snippets