Назад | Перейти на главную страницу

X-Forwarded-Host не работает в nginx

Обновление 2. Я хочу добавить и перенаправить весь трафик на localhost/admin/ вместо того localhost/.

,

Я мог бы также использовать ingrees-nginx-controller вместо монтирующего файла.

В докере nginx.conf (или аналогично k8s)

server {
    listen 80 default_server;
    listen [::]:80 default_server;
        ...
        location /admin {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host/admin;
        proxy_pass http://<conteiner2>.docker-network;
    }
    ... 
}

Обновление1 Для кубернетов я пытаюсь настроить ingress-nginx Для этого я установил ingress-nginx-controller и я настраиваю ingress-nginx используя этот YAML:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      more_set_headers "Host $host";
      more_set_headers "X-Real-IP $remote_addr";
      more_set_headers "X-Forwarded-For $proxy_add_x_forwarded_for";
      more_set_headers "X-Forwarded-Proto $scheme";
      more_set_headers "X-Forwarded-Host $host/admin";
  name: test-ingress
  namespace: <namespace>
spec:
  rules:
    - http:
        paths:
        - path: /admin
          backend:
            serviceName: <app1>-admin
            servicePort: 8002

Итак, здесь происходит несколько вещей; самый главный:

proxy_set_header X-Forwarded-Host $host/admin;
proxy_pass http://<conteiner2>.docker-network;

неверно, потому что x-forwarded-HOST не должен содержать ури, как и с /admin: это должно быть просто $host; что вы действительно хотите, так это обновить proxy_pass содержать $request_uri как вы можете заметить, сгенерированный nginx.conf делает это при использовании контроллера nginx Ingress. Которые ждут URI местоположения /admin вместе с любыми другими совпадениями в местоположении будут переданы вверх по потоку, как ожидалось:

proxy_set_header X-Forwarded-Host $host;
proxy_pass http://<conteiner2>.docker-network$request_uri;
# or you're free to hard-code /admin if you prefer:
proxy_pass http://<conteiner2>.docker-network/admin;

Во-вторых, если вы чувствуете, что хотите configuration-snippet: применяется к одному URI, но не к обоим, затем разделите два маршрута на два отдельных ресурса Ingress, чтобы ими можно было управлять независимо:

kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # this one just applies to /api
  name: test-ingress-api
spec:
  rules:
    - http:
        paths:
        - path: /api
          backend:
            serviceName: <app2>-api
            servicePort: 8000
---
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/configuration-snippet: |
      # this one just applies for /admin
  name: test-ingress-admin
spec:
  rules:
    - http:
        paths:
        - path: /admin
          backend:
            serviceName: <app1>-admin
            servicePort: 8002

Есть идеи, как отлаживать прокси nginx?

Есть два отличных способа: во-первых, возьмите сгенерированный nginx.conf и перечитайте его, чтобы увидеть, что вы ожидали от того, что произошло:

kubectl cp ${the_nginx_controller_pod}:/etc/nginx/nginx.conf ingress-nginx.conf

Другой способ - повернуть уровень журнала nginx к debug (что может быть проблематичным, если вы пытаетесь отлаживать в производственной среде из-за абсолютно безумного количества текста, которое он будет генерировать, но он почти наверняка будет иметь фактический ответ на все, что вы пытаетесь отладить):

# the ConfigMap may be named differently in your setup:
$ kubectl edit configmap nginx-ingress-controller

# and add:
data:
   error-log-level: debug

# then wait a few seconds for nginx to notice the configmap change
# and if it doesn't, kill the controller pods to force the reload