簡體   English   中英

nginx-ingress:啟用 force-ssl 時重定向太多

[英]nginx-ingress: Too many redirects when force-ssl is enabled

我正在使用 nginx-ingress 在 kube.netes 中設置我的第一個入口。 我像這樣設置ingress-nginx負載均衡器服務:

{
  "kind": "Service",
  "apiVersion": "v1",
  "metadata": {
    "name": "ingress-nginx",
    "namespace": "...",
    "labels": {
      "k8s-addon": "ingress-nginx.addons.k8s.io"
    },
    "annotations": {     
      "service.beta.kubernetes.io/aws-load-balancer-backend-protocol": "tcp",
      "service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*",
      "service.beta.kubernetes.io/aws-load-balancer-ssl-cert": "arn....",
      "service.beta.kubernetes.io/aws-load-balancer-ssl-ports": "443"
    }
  },
  "spec": {
    "ports": [
      {
        "name": "http",
        "protocol": "TCP",
        "port": 80,
        "targetPort": "http",
        "nodePort": 30591
      },
      {
        "name": "https",
        "protocol": "TCP",
        "port": 443,
        "targetPort": "http",
        "nodePort": 32564
      }
    ],
    "selector": {
      "app": "ingress-nginx"
    },
    "clusterIP": "...",
    "type": "LoadBalancer",
    "sessionAffinity": "None",
    "externalTrafficPolicy": "Cluster"
  },
  "status": {
    "loadBalancer": {
      "ingress": [
        {
          "hostname": "blablala.elb.amazonaws.com"
        }
      ]
    }
  }
}

請注意https端口如何將其targetPort屬性指向端口 80 (http),以便在負載均衡器處終止 ssl。

我的入口看起來像這樣:

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
  name: something
  namespace: ...
  annotations:
    ingress.kubernetes.io/ingress.class: "nginx"
    ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
  rules:
    - host: www.exapmle.com
      http:
        paths:
         - path: /
           backend:
            serviceName: some-service
            servicePort: 2100

現在,當我導航到 url 時,出現Too many redirects error 讓我感到困惑的是,當我添加以下 header "X-Forwarded-Proto: https" 時,我得到了預期的響應 ( curl https://www.example.com -v -H "X-Forwarded-Proto: https" )。

有什么想法可以解決這個問題嗎?

PS 這與ingress.kube.netes.io/force-ssl-redirect: "false"一起工作得很好而且似乎沒有任何無關的重定向。

這是 SSL 重定向的annotation與代理協議和 ELB 上 SSL 連接的終止相結合的一個已知問題。

關於它的問題已發布在GitHub 上,這里是該線程的修復程序

  1. 您應該為 Nginx-Ingress 創建自定義 ConfigMap,而不是使用force-ssl-redirect注釋,如下所示:

     apiVersion: v1 kind: ConfigMap metadata: labels: app: ingress-nginx name: nginx-ingress-configuration namespace: <ingress-namespace> data: ssl-redirect: "false" hsts: "true" server-tokens: "false" http-snippet: | server { listen 8080 proxy_protocol; server_tokens off; return 301 https://$host$request_uri; }

    該配置將創建一個額外的偵聽器,並通過簡單的重定向到 https。

  2. 然后,將該 ConfigMap 應用到您的入口控制器,將NodePort 8080 添加到其容器定義和服務中。
  3. 現在,您可以將 ELB 的 80 端口指向 Service 的 8080 端口。

有了這個額外的監聽器,它就會起作用。

我必須添加這些注釋才能在不更改入口控制器的情況下工作:

    annotations:
      kubernetes.io/ingress.class: nginx-ingress-internal # <- AWS NLB
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
      nginx.ingress.kubernetes.io/configuration-snippet: |
        if ($http_x_forwarded_proto = 'http') {
          return 301 https://$host$request_uri;
        }

另一種適用於我的環境的方法(k8s v1.16.15,rancher/nginx-ingress-controller:nginx-0.32.0-rancher1):

apiVersion: v1
data:
  compute-full-forwarded-for: "true"
  use-forwarded-headers: "true"
kind: ConfigMap
metadata:
  labels:
    app: ingress-nginx
  name: nginx-configuration
  namespace: ingress-nginx

這與應用程序入口的 force-ssl-redirect 一起使用。 入口控制器似乎沒有使用來自 ELB 的 X-Forwarded-Proto 標頭開箱即用。

Too many redirects error添加另一個原因。

在使用ingress-nginx作為某些 k8s 服務前的入口控制器時。

其中一項服務(在我的情況下為 ArgoCD)自行處理 TLS 終止並始終將 HTTP 請求重定向到 HTTPS

問題是 nginx 入口控制器也處理 TLS 終止並使用 HTTP 與后端服務通信,結果是 ArgoCD 的服務器總是響應重定向到 HTTPS,這是多次重定向的原因。

任何將相關值傳遞給下面的入口注釋的嘗試都無濟於事

annotations:
  nginx.ingress.kubernetes.io/ssl-redirect: false/true
  nginx.ingress.kubernetes.io/backend-protocol: "HTTP"/"HTTPS"

解決方案是通過將--insecure標志傳遞給 argocd-server 部署來確保服務不處理 TLS

規格:

  template:
    spec:
      containers:
      - name: argocd-server
        command:
        - argocd-server
        - --repo-server
        - argocd-repo-server:8081
        - --insecure # <-- Here

我也通過 helm chart 在Keycloak設置中遇到了這個問題。 SSL 終止是在 ELB 上完成的,以便修復它。 我對 helm 值進行了以下更改。

ingress:
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"

這幫助我修復了它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM