Я воспроизвел ваш сценарий в своей учетной записи GCP и не получил тот же результат, поэтому я публикую свои шаги по устранению неполадок каждого компонента, чтобы убедиться, что все они работают должным образом. В резюме, похоже, основная проблема заключается в том, как приложение обрабатывает paths
или host
.
Kubernetes: 1.15.3 (GKE) Nginx Вход: установлен после официальных документов
Исходя из вашего yaml, я удалил зонды readiness
и liveness
, а также среды envs для тестирования и изменил изображение на nginx
(на порту 80):
apiVersion: v1
kind: Service
metadata:
name: test-service
labels:
app.kubernetes.io/name: test-service
helm.sh/chart: test-service-0.1.0
app.kubernetes.io/instance: test-service
app.kubernetes.io/managed-by: Helm
annotations:
service.beta.kubernetes.io/azure-load-balancer-internal: '"true"'
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: test-service
app.kubernetes.io/instance: test-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-service
labels:
app.kubernetes.io/name: test-service
helm.sh/chart: test-service-0.1.0
app.kubernetes.io/instance: test-service
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: test-service
app.kubernetes.io/instance: test-service
template:
metadata:
labels:
app.kubernetes.io/name: test-service
app.kubernetes.io/instance: test-service
spec:
containers:
- name: test-service
image: nginx
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
После применения мы можем проверить, работают ли оба (развертывание и служба), как ожидалось, прежде чем применять входную скорость c.
Чтобы проверить это, мы можем использовать изображение curl
для curl destination или dnsutil
контейнер от официальных kubernetes docs . В этом случае я использовал curlimages/curl
do test:
apiVersion: v1
kind: Pod
metadata:
name: curl
namespace: default
spec:
containers:
- name: curl
image: curlimages/curl
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
restartPolicy: Always
При работающем контейнере curl мы можем сначала проверить, правильно ли работает контейнер нашего nginx образа и отвечает ли на запросы "curling" напрямую их IP.
Команда ниже создаст переменную с именем $pod
из модуля с меткой app.kubernetes.io/name=test-service
с IP-адресом модуля.
$ pod=$(kubectl get pods -ojsonpath='{.items[*].status.podIP}' -l app.kubernetes.io/name=test-service)
$ echo $pod
192.168.109.12
Использование curl
pod create Ранее мы могли проверить, обрабатывает ли модуль запросы:
$ kubectl exec curl -- curl -Is $pod
HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Tue, 24 Mar 2020 09:08:21 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
Connection: keep-alive
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes
См. ответ HTTP / 1.1 200 OK , давайте продолжим тестировать службу:
$ kubectl exec curl -- curl -Is test-service
HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Tue, 24 Mar 2020 09:11:13 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
Connection: keep-alive
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes
То же самое здесь, HTTP / 1.1 200 OK для обслуживания.
Давайте go продолжим и развернем входной nginx без TLS, чтобы выполнить тест до и после:
Создание и применение сертификата:
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=apiexample.centralus.cloudapp.azure.com/O=apiexample.centralus.cloudapp.azure.com"
...
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created
Вход без TLS (я изменил на порт 80, чтобы соответствовать моему nginx образу):
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-service
labels:
app.kubernetes.io/name: test-service
helm.sh/chart: test-service-0.1.0
app.kubernetes.io/instance: test-service
app.kubernetes.io/managed-by: Helm
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: "apiexample.centralus.cloudapp.azure.com"
http:
paths:
- path: /testservice(/|$)(.*)
backend:
serviceName: test-service
servicePort: 80
Тестирование с моего рабочего стола на inte rnet с использованием IP (не указан), предоставленного GCP:
$ curl -ILH "Host: apiexample.centralus.cloudapp.azure.com" http://34.77.xxx.xx/testservice
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Tue, 24 Mar 2020 10:41:21 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes
Пока здесь все работает нормально. Теперь мы можем добавить TLS для входа в spe c и повторить попытку:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-service
labels:
app.kubernetes.io/name: test-service
helm.sh/chart: test-service-0.1.0
app.kubernetes.io/instance: test-service
app.kubernetes.io/managed-by: Helm
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
tls:
- hosts:
- apiexample.centralus.cloudapp.azure.com
secretName: tls-secret
rules:
- host: "apiexample.centralus.cloudapp.azure.com"
http:
paths:
- path: /testservice(/|$)(.*)
backend:
serviceName: test-service
servicePort: 80
Тестирование с использованием curl:
curl -ILH "Host: apiexample.centralus.cloudapp.azure.com" https://34.77.147.74/testservice -k
HTTP/2 200
server: nginx/1.17.8
date: Tue, 24 Mar 2020 10:45:25 GMT
content-type: text/html
content-length: 612
vary: Accept-Encoding
last-modified: Tue, 03 Mar 2020 14:32:47 GMT
etag: "5e5e6a8f-264"
accept-ranges: bytes
strict-transport-security: max-age=15724800; includeSubDomains
Хорошо, так что это работает с TLS, поэтому на основе из этого мы можем сделать вывод, что ваш yaml spe c работает, и, возможно, вы столкнулись с некоторой проблемой с path
во входных определениях и вашем приложении:
Вы используете аннотацию nginx.ingress.kubernetes.io/rewrite-target: /$2
и путь /testservice(/|$)(.*)
Это означает, что любые символы, захваченные (.*)
, будут назначены заполнителю $2
, который затем используется в качестве параметра в аннотации rewrite-target
.
В зависимости от вашего входа path
регулярное выражение:
apiexample.centralus.cloudapp.azure.com/testservice
переписывает в apiexample.centralus.cloudapp.azure.com/
apiexample.centralus.cloudapp.azure.com/testservice/
переписывает в apiexample.centralus.cloudapp.azure.com/
apiexample.centralus.cloudapp.azure.com/testservice/tenant/api/v1/endpoint
перезаписывает в apiexample.centralus.cloudapp.azure.com/tenant/api/v1/endpoint
При включении в nginx журналах модуля вы можете увидеть запрошенный URL после перезаписи:
2020/03/24 10:59:33 [error] 7#7: *186 open() "/usr/share/nginx/html/tenant/api/v1/endpoint" failed (2: No such file or directory), client: 10.20.1.61, server: localhost, request: "HEAD /tenant/api/v1/endpoint HTTP/1.1", host: "apiexample.centralus.cloudapp.azure.com"
Итак, с помощью этого теста я мог заключить, что ваше развертывание, обслуживание и вход работает и не содержит опечаток или форматирования. нг проблемы. Поэтому я советую дважды проверить приложение
- Убедитесь, что ваше приложение правильно обрабатывает
path
; - Если ваши приложения выполняют некоторую проверку URL, убедитесь, что они могут обработать http и https;
- Если вы включили CORS, настройте вход, как указано здесь .
Поскольку вы не разместили ни одного приложения в качестве примера для Воспроизведите, мои тесты были ограничены универсальным c приложением в качестве бэкэнда. Если вы могли бы предоставить более подробную информацию о бэкэнд-приложении или о каком-либо универсальном c приложении, которое производит то же поведение, пожалуйста, дайте мне знать и с удовольствием уточню мой ответ с более подробной информацией.
Ссылки:
https://kubernetes.github.io/ingress-nginx/deploy/
https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/
https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/