将 Google Kubernetes 入口重定向到 HTTPS

Redirect Google Kubernetes Ingress to HTTPS

我有一个 Angular 应用程序,运行 在 nginx docker 容器中,即 运行 在 Google Kubernetes 和 Google 具有 Google 托管证书的 Kubernetes Ingress。如果请求来自 HTTP/端口 80,我似乎无法让 Ingress 自动重定向到 HTTPS。

显然 Google Ingress "can't do it" 所以我一直在尝试让 nginx 实例为我做这件事。但我认为在那种情况下我需要实际的证书,我也不知道如何摆脱 Google.

但是......必须有一个简单的方法来做到这一点。 HTTPS 在网站上运行良好,我只是无法将其从 HTTP 重定向到 HTTPS...

这是我的 Ingress YAML:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ui-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: my-ip 
    networking.gke.io/managed-certificates: my-certificate
spec:
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          serviceName: web-ui
          servicePort: 80

我的 nginx.conf 带有注释掉的重定向无效:

worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen 80 default_server;
        server_name example.com;

        root   /usr/share/nginx/html;
        index  index.html index.htm;
        include /etc/nginx/mime.types;

        gzip on;
        gzip_min_length 1000;
        gzip_proxied expired no-cache no-store private auth;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location / {
            try_files $uri $uri/ /index.html;
        }

        #if ($scheme = http) {
        #    return 301 https://$server_name$request_uri;
        #}
    }
}

我也尝试了更长的时间 nginx.conf 导致 Google / Ingress:

出现 502 错误
worker_processes  1;

events {
    worker_connections  1024;
}

http {

    server {
        listen 80;
        server_name example.com;

        return 301 https://example.com$request_uri;
    }

    server {
        listen 443 ssl http2;
        server_name example.com;

        return 301 $scheme://example.com$request_uri;
    }

    server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        server_name example.com;

        root   /usr/share/nginx/html;
        index  index.html index.htm;
        include /etc/nginx/mime.types;

        gzip on;
        gzip_min_length 1000;
        gzip_proxied expired no-cache no-store private auth;
        gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        location / {
            try_files $uri $uri/ /index.html;
        }


    }
}

pod 的错误是寻找要安装的证书,但我不知道如何从 Google 托管证书中获取证书以复制到 nginx 映像:

"textPayload": "2019/05/08 21:02:13 [emerg] 1#1: no \"ssl_certificate\" is defined for the \"listen ... ssl\" directive in /etc/nginx/nginx.conf:27\n"

你是对的,目前,Google 云 HTTPS 负载均衡器不允许 http-->https 重定向。

I don't know how to get the certificate out of Google Managed Certs to copy to the nginx image.

你不能。 Google 管理证书并为您续订。因此,您将无法访问您的 TLS 密钥。

并且由于 Google 云 HTTPS LB 可以侦听 HTTPS 或 HTTP,您不能从 HTTP 重定向到 HTTPS。

我建议以最快的方式完成这项工作:

  • nginx-ingress 控制器安装到您的 GKE 集群,并将它提供的 https 重定向注释放在您的 Ingress 对象上。
  • 这将创建 L3 (TCP/IP) 负载均衡器而不是 HTTPS 负载均衡器,因此您可以同时处理 HTTP 和 HTTPS 流量。
  • 安装和使用 cert-manager controller to get certificates for your Ingress (not GKE ingress, Nginx ingress). This will provide the tls key + cert files for you as Secret (my gke-letsencrypt 教程可能会有所帮助)。
  • 然后您可以从您的 nginx Ingress 的 tls: 字段中 mount/use 这个 Secret,nginx-ingress 控制器将在其 nginx.conf 上配置该字段。

我正在阅读有关设置其他负载平衡器的内容,偶然发现了我正在寻找的答案。不是基于 nginx 中的 $scheme 重定向,而是必须在 $http_x_forwarded_proto 上重定向。这可以防止 Google 健康检查失败,因为它们没有通过 http_x_forwarded_proto header,因此它在健康检查时永远不会命中该重定向。

if ($http_x_forwarded_proto = "http") {
    return 301 https://$host$request_uri;
}

对于像我一样仍然遇到这个问题的人,现在有一个官方方法可以做到这一点:

您可以编写和部署一个 FrontendConfig 文件,其中设置了 redirectToHttps 参数,并将此文件作为前端配置添加到您的入口。这会自动将 HTTP 流量重定向到 HTTPS。

前端配置:

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: PERMANENT_REDIRECT

入口

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-name
  annotations:
    [...]
    networking.gke.io/v1beta1.FrontendConfig: my-frontend-config
  namespace: default
spec:
[...]

这仅适用于版本 >= 1 的集群。17.x

参见:https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#https_redirect