web-dev-qa-db-ja.com

Helmチャートnginx-ingressコントローラーTCP httpをhttpsにリダイレクト

私の環境はAWSでホストされています。ヘルムチャートstable/nginx-ingressをTCPモードでデプロイしました(TCPモードでAWS ELBが必要です。正確にELBクラシックが必要です! )、また、AWS ACM証明書とそれなしのバックエンドを使用する必要があるため、次のようになります。

TCP:80 -> TCP:30452 (Kubernetes)
SSL(TCP):443 -> TCP:31453 (Kubernetes) 

私の「nginx-ingress」は:

controller:
  name: controller
  image:
    repository: quay.io/kubernetes-ingress-controller/nginx-ingress-controller
    tag: "0.27.0"
    pullPolicy: IfNotPresent
    # www-data -> uid 101
    runAsUser: 101
    allowPrivilegeEscalation: true

  # Configures the ports the nginx-controller listens on
  containerPort:
    http: 80
    https: 80

  # Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
  config:
    allow-backend-server-header: "true"
    use-proxy-protocol: "true"
    server-tokens: "false"
    use-forwarded-headers: "true"
    ssl-redirect: "true"
    http-redirect-code: "301"
    proxy_redirect: "off"

  ingressClass: websocket

  service:
    enabled: true

    annotations:
      # Enable PROXY protocol
      service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*'
      service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '120'
      # SSL
      service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-1:123123123123:certificate/123123123123123123123"
      service.beta.kubernetes.io/aws-load-balancer-ssl-ports: 'https'
      service.beta.kubernetes.io/aws-load-balancer-backend-protocol: 'tcp'

    ports:
      http: 80
      https: 443

    targetPorts:
      http: http
      https: http

    type: LoadBalancer
    nodePorts:
      http: ""
      https: ""
      tcp: {}
      udp: {}

サービスの私のINGRESS構成:

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: websocket

  hosts:
    - Host: example.com
      paths:
        - /

HTTPからHTTPSへのリダイレクトを設定するにはどうすればよいですか?入力でnginx.ingress.kubernetes.io/force-ssl-redirect: "true"を使用すると、リダイレクトループが表示されます:(

2

これは 既知の問題 TCPモード(レイヤー4))でELB Classicと組み合わせてSSLターミネーションを使用する場合です。

次の 回避策 を使用できます。

1-以下を使用して、nginx-ingressのカスタムConfigMapを作成します http-snippet

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app: ingress-nginx
  name: nginx-configuration
  namespace: <ingress-namespace>
data:
  ssl-redirect: "false"
  hsts: "true"
  server-tokens: "false"
  # You may not want to use proxy_protocol here
  http-snippet: |
    server {
      listen 8000 proxy_protocol;
      server_tokens off;
      return 301 https://$Host$request_uri;
    }

2- this のように、上記のconfigMapを使用するようにIngressが構成されていることを確認します。

3-新しいNodePortを作成し、定義をnginx入力コンテナーとサービスに追加します。例:

コンテナ:

  - name: http
    containerPort: 80
  - name: https
    containerPort: 443
  - name: http-redirect
    containerPort: 8000

サービス:

  ports:
  # As you are using SSL termination, note that this does Service(443)-->Container(80)
  - name: https
    port: 443
    protocol: TCP
    targetPort: http # <-- Container port 80
    nodePort: 31453
  - name: http
    port: 8000
    protocol: TCP
    targetPort: http-redirect
    nodePort: 32000

4-ELBのポート80がnginxイングレスサービスのポート8000​​を指すようにします。

TCP:80 -> TCP:32000 (Kubernetes)
SSL(TCP):443 -> TCP:31453 (Kubernetes) 

これにより、リダイレクトを行うことだけが目的の追加リスナーが作成されます。一度だけ到達するので、リダイレクトループは解決されます。リクエストは次のように動作します。

ELB(80) --> Nginx Service(32000) --> Nginx Container(8000) --Redirect--> ELB(443) --> Nginx Service(31453) -- Nginx Container (80)
1