приложение по пути вместо root не работает для Kubernetes Ingress - PullRequest
2 голосов
/ 21 июня 2020

У меня проблема при работе с K8s Ingress, и я буду использовать здесь поддельные примеры, чтобы проиллюстрировать свою точку зрения. Предположим, у меня есть приложение под названием Tweeta, а моя компания называется AB C. В настоящее время мое приложение находится на tweeta.ab c .com. Но мы хотим перенести наше приложение на app.ab c .com / tweeta.

Мой текущий вход в K8s выглядит следующим образом:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress
spec:
  rules:
  - host: tweeta.abc.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /api
        backend:
          serviceName: tweeta-backend
          servicePort: 80

Для миграции я добавил второй ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress-v2
spec:
  rules:
  - host: app.abc.com
    http:
      paths:
      - path: /tweeta
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /tweeta/api
        backend:
          serviceName: tweeta-backend
          servicePort: 80

Для обеспечения непрерывности я хотел бы, чтобы 2 входа одновременно указывали на мои службы. Когда новый домен будет готов и заработает, мне просто нужно будет удалить старый входящий трафик.

Однако мне не повезло с новым доменом с этим входом. Это потому, что он размещен на пути, а вход k8s должен размещаться на root? Или это конфигурация, которую мне нужно сделать на стороне nginx?

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Я предполагаю, что ваш frontend Pod ожидает путь /, а backend Pod ожидает путь /api

Первая входящая конфигурация не преобразует запрос и переходит во фронтенд (Fpod) / backend (Bpod) Pods как есть:

http://tweeta.abc.com/     -> ingress -> svc -> Fpod: [ http://tweeta.abc.com/    ] 
http://tweeta.abc.com/api  -> ingress -> svc -> Bpod: [ http://tweeta.abc.com/api ] 

, но при втором входе он не работает должным образом:

http://app.abc.com/tweeta      -> ingress -> svc -> Fpod: [ http://app.abc.com/tweeta    ] 
http://app.abc.com/tweeta/api  -> ingress -> svc -> Bpod: [ http://app.abc.com/tweeta/api    ] 

Путь запроса Pod изменен с / на /tweeta и от /api до /tweeta/api. Я думаю, это не ожидаемое поведение. Обычно приложение в Pods не заботится о заголовке Host, но Path должен быть правильным. Если ваши модули не предназначены для ответа на дополнительный путь tweeta\, они, вероятно, ответят 404 (Not Found), когда используется второй вход.

Чтобы исправить это, вам нужно добавить перезаписать аннотацию для удаления tweeta пути из запроса Pods:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress-v2
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - host: app.abc.com
    http:
      paths:
      - path: /tweeta(/|$)(.*)
        backend:
          serviceName: tweeta-frontend
          servicePort: 80
      - path: /tweeta(/)(api$|api/.*)
        backend:
          serviceName: tweeta-backend
          servicePort: 80

Результат будет следующим, как и должно быть:

http://app.abc.com/tweeta            -> ingress -> svc -> Fpod: [ http://app.abc.com/    ] 
http://app.abc.com/tweeta/blabla     -> ingress -> svc -> Fpod: [ http://app.abc.com/blabla    ] 

http://app.abc.com/tweeta/api        -> ingress -> svc -> Bpod: [ http://app.abc.com/api    ] 
http://app.abc.com/tweeta/api/blabla -> ingress -> svc -> Bpod: [ http://app.abc.com/api/blabla    ] 

Чтобы проверить вход -контроллерные журналы и конфигурация используют соответственно:

$ kubectl logs -n ingress-controller-namespace ingress-controller-pods-name

$ kubectl exec -it -n ingress-controller-namespace ingress-controller-pods-name -- cat /etc/nginx/nginx.conf > local-file-name.txt && less local-file-name.txt
0 голосов
/ 22 июня 2020

Насколько я ни старался, мне не удалось воспроизвести вашу проблему. Поэтому я решил описать, как я пытался воспроизвести это, чтобы вы могли выполнить те же действия, и в зависимости от того, где / если вы потерпите неудачу, мы сможем найти причину проблемы.

Прежде всего, убедитесь, что вы используют NGINX Ingress , поскольку он более мощный.

Я установил свой NGINX Ingress с помощью Helm, выполнив следующие шаги:

$ curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
$ helm repo add stable https://kubernetes-charts.storage.googleapis.com
$ helm repo update
$ helm install nginx-ingress stable/nginx-ingress

Для развертывания мы собираемся использовать пример из здесь .

Развертывание приложения hello, world

  1. Создайте развертывание, используя следующую команду:

    kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
    

    Вывод:

    deployment.apps/web created
    
  2. Раскрытие развертывания:

    kubectl expose deployment web --type=NodePort --port=8080
    

    Вывод:

    service/web exposed
    

Создать второе развертывание

  1. Создайте развертывание v2 с помощью следующей команды:

    kubectl create deployment web2 --image=gcr.io/google-samples/hello-app:2.0
    

    Вывод:

    deployment.apps/web2 created
    
  2. Показать развертывание:

    kubectl expose deployment web2 --port=8080 --type=NodePort
    

    Вывод:

    service/web2 exposed
    

На этом этапе у нас запущены развертывания и службы:

* 10 55 *
$ kubectl get service
NAME                            TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
kubernetes                      ClusterIP      10.96.0.1        <none>        443/TCP                      5d5h
nginx-ingress-controller        LoadBalancer   10.111.183.151   <pending>     80:31974/TCP,443:32396/TCP   54m
nginx-ingress-default-backend   ClusterIP      10.104.30.84     <none>        80/TCP                       54m
web                             NodePort       10.102.38.233    <none>        8080:31887/TCP               24m
web2                            NodePort       10.108.203.191   <none>        8080:32405/TCP               23m

Для входа мы собираемся использовать тот, который указан в вопросе, но нам нужно изменить бэкенды:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress
spec:
  rules:
  - host: tweeta.abc.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web
          servicePort: 8080
      - path: /api
        backend:
          serviceName: web2
          servicePort: 8080          
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tweeta-ingress-v2
spec:
  rules:
  - host: app.abc.com
    http:
      paths:
      - path: /tweeta
        backend:
          serviceName: web
          servicePort: 8080
      - path: /tweeta/api
        backend:
          serviceName: web2
          servicePort: 8080     

Теперь давайте протестируем наши входы:

$ curl tweeta.abc.com
Hello, world!
Version: 1.0.0
Hostname: web-6785d44d5-j8bgk

$ curl tweeta.abc.com/api
Hello, world!
Version: 2.0.0
Hostname: web2-8474c56fd-lx55n

$ curl app.abc.com/tweeta
Hello, world!
Version: 1.0.0
Hostname: web-6785d44d5-j8bgk

$ curl app.abc.com/tweeta/api
Hello, world!
Version: 2.0.0
Hostname: web2-8474c56fd-lx55n

Как видно, все работает нормально без модов в ваших ингрессах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...