Как перенаправить URL-адрес на основе заголовка http при входе nginx? - PullRequest
0 голосов
/ 03 августа 2020

Мои запросы передаются через Cloudflare, который устанавливает заголовок с указанием страны в заголовке http на основе IP-адреса. Я хочу перенаправить запросы с определенными путями на основе этого заголовка в контроллере входа Nginx. Как мне это сделать?

1 Ответ

1 голос
/ 12 августа 2020

В настоящее время определение ресурса Ingress для nginx-ingress не поддерживает маршрутизацию на основе заголовков.

Я нашел обходной путь для маршрутизации запроса по его заголовку ( Я включил шаги ниже) со следующей аннотацией:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }

Другие возможные решения / обходные пути:

Что касается обходного пути :

Предполагается, что (для примера):

  • Есть 2 развертывания: hello, goodbye
  • Оба связаны со своими службами с именами: hello-service, goodbye-service

Ресурс Ingress будет настроен таким образом, что hello должен всегда отвечать, но с добавлением configuration-snippet трафик c будет перенаправлен на goodbye.

Ответы этого развертывания:

|     hello      |    goodbye     |
|----------------|----------------|
| Hello, world!  | Hello, world!  |
| Version: 2.0.0 | Version: 1.0.0 | # notice the version

Пример развертывания hello с подключенной службой на него:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  selector:
    matchLabels:
      app: hello
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"
---
apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  selector:
    app: hello
  ports:
    - name: hello-port
      port: 5678 # IMPORTANT
      targetPort: 50001
  type: NodePort

Чтобы получить развертывание goodbye, замените hello на goodbye и измените версию образа на 1.0.

Определение входа, чтобы перенаправить запрос по заголовку выглядит так:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hello-ingress 
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }
spec:
  rules:
  - host: 
    http:
      paths:
      - path: /
        backend:
          serviceName: hello-service 
          servicePort: hello-port

По умолчанию это определение Ingress без configuration-snippet всегда будет направлять трафик c в hello-service, а затем в hello поды. Добавив:

    nginx.ingress.kubernetes.io/configuration-snippet: |
      if ($http_LocationHeader = "PL") { proxy_pass http://goodbye-service.default.svc.cluster.local:5678; }

, он проверит, присутствует ли заголовок с именем LocationHeader и соответствует ли он PL. Если это так, он отправит запрос на goodbye-service по его DNS-имени.

Фокус на:

После применения этого ресурса Ingress вы сможете отправить запрос с помощью LocationHeader=PL (например, с Postman ) и получить ответ:

Hello, world!
Version: 1.0.0
Hostname: goodbye-5758448754-wr64c

Когда я пытался использовать директиву map, я получал следующие сообщения:

  • nginx: [emerg] "map" directive is not allowed here in /tmp/nginx-OMMITED
...