web-dev-qa-db-ja.com

X-Forwarded-Hostがnginxで機能しない

pdate 2。すべてのトラフィックをlocalhost/admin/ではなくlocalhost/に追加して転送したい。

  • アプリはこれらのパスをリッスンします:
    • localhost/(アプリケーションによってlocalhost/loginに302が割り当てられます)、
    • localhost/overview
    • localhost/books/detailsなど.
  • 管理ユーザーに次のURLを使用してほしい:
    • localhost/admin/(アプリケーションで302 localhost/admin/loginを取得するため)
    • localhost/admin/overview
    • localhost/admin/books/details
  • 私のリバースプロキシ(下記参照)を使用:
    • localhost/admin/(アプリケーションによって302 localhost/loginが返されます)

マウントファイルの代わりにingrees-nginx-controllerを使用することもできます。

Docker 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;
    }
    ... 
}

pdate1 kubernetesの場合、ingress-nginxをセットアップしようとしています。ingress-nginx-controllerをインストールし、次のYAMLを使用してingress-nginxをセットアップします。

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
1
TicJit

したがって、ここではいくつかのことが行われています。何よりも:

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

x-forwarded-Hostと同様に、/adminuriを含めないでください。これは、$Host;本当に必要なのは、proxy_passを更新して$request_uriを含めることです。これは、nginx Ingressコントローラーを使用すると、生成されたnginx.confが実行することを確認できるためです。その場所の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:を両方ではなく1つのURIに適用したい場合は、2つのルートを2つの別々の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プロキシをデバッグする方法はありますか?

2つの素晴らしい方法があります。1つ目は、生成されたnginx.confを取得し、それを読んで、何が発生するのか、何が発生するのかを確認します。

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

もう1つの方法は、 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
3
mdaniel