簡體   English   中英

http -> https 在 Google Kubernetes 引擎中重定向

[英]http -> https redirect in Google Kubernetes Engine

我正在尋找重定向所有流量

http://example.com -> https://example.Z4D236D9A2D102C50FE6AD1C50DAB幾乎所有網站都這樣做。

我查看了這個鏈接但沒有成功: Kubernetes HTTPS Ingress in Google Container Engine

並在我的 ingress.yaml 文件中嘗試了以下注釋。

nginx.ingress.kubernetes.io/configuration-snippet: |
  if ($http_x_forwarded_proto != 'https') {
    return 301 https://$host$request_uri;
  }
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.allow-http: "false"

一切都沒有成功。 To be clear, I can access https://example.com and http://example.com without any errors, I need the http call to redirect to https.

謝謝

GKE 使用 GCE L7。 您在示例中引用的規則不受支持,應在應用程序級別控制 HTTP 到 HTTPS 重定向。

L7 插入x-forwarded-proto標頭,您可以使用它來了解前端流量是使用 HTTP 還是 HTTPS 來的。 看這里: 將 HTTP 重定向到 HTTPS

該鏈接中還有一個 Nginx 示例(為方便起見復制):

# Replace '_' with your hostname.
server_name _;
if ($http_x_forwarded_proto = "http") {
    return 301 https://$host$request_uri;
}

目前,關於如何正確執行此操作的文檔(注釋、SSL/HTTPS、健康檢查等)嚴重缺乏,而且已經太久了。 我懷疑這是因為他們更喜歡你使用 App Engine,這很神奇但價格昂貴。 對於 GKE,這里有兩個選項:

  • 帶有谷歌管理的 SSL 證書和在您的應用程序/站點前面的附加 NGINX 服務器配置的入口
  • 具有自我管理/第三方 SSL 證書的 NGINX 入口控制器

以下是使用前者進行工作設置的步驟。

1 應用的大門

nginx.conf:(省略號代表其他不相關的非強制設置)

user  nginx;
worker_processes  auto;

events {
    worker_connections  1024;
}

http {
    ...

    keepalive_timeout  620s;

    ## Logging ##
    ...
    ## MIME Types ##
    ...
    ## Caching ##
    ...
    ## Security Headers ##
    ...
    ## Compression ##
    ....

    server {
        listen 80;

        ## HTTP Redirect ##
        if ($http_x_forwarded_proto = "http") {
            return 301 https://[YOUR DOMAIN]$request_uri;
        }

        location /health/liveness {
            access_log off;
            default_type text/plain;
            return 200 'Server is LIVE!';
        }

        location /health/readiness {
            access_log off;
            default_type text/plain;
            return 200 'Server is READY!';
        }

        root /usr/src/app/www;
        index index.html index.htm;
        server_name [YOUR DOMAIN] www.[YOUR DOMAIN];

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

注意:只有一個服務端口 全局轉發規則將http_x_forwarded_proto標頭添加到通過它的所有流量。 因為現在進入您域的所有流量都通過此規則(請記住,容器、服務和入口上的一個端口),因此將(至關重要!)始終設置此標頭。 請注意上面的檢查和重定向:如果標頭值為“https”,它只會繼續提供服務。 根和索引以及位置值可能因您的項目而異(這是一個 angular 項目)。 keepalive_timeout 設置為google 推薦的值。 我更喜歡使用主 nginx.conf 文件,但大多數人會在 /etc/nginx/conf.d 中添加 custom.conf 文件; 如果您這樣做,只需確保使用包含語句將文件導入到主 nginx.conf http 塊中。 注釋突出顯示了在一切正常時您可能想要添加的其他設置的位置,例如 gzip/brotli、安全標頭、保存日志的位置等。

Dockerfile:

...
COPY nginx.conf /etc/nginx/nginx.conf
CMD ["nginx", "-g", "daemon off;"]

注意:只有最后兩行。 不需要指定 EXPOSE 端口。 COPY 將默認的 nginx.conf 替換為修改后的 nginx.conf。 CMD 啟動輕服務器。

2 創建部署清單並應用/創建

部署.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: uber-dp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: uber
  template:
    metadata:
      labels:
        app: uber
    spec:
      containers:
        - name: uber-ctr
          image: gcr.io/uber/beta:v1 // or some other registry
          livenessProbe:
            failureThreshold: 3
            initialDelaySeconds: 60
            httpGet:
              path: /health/liveness
              port: 80
              scheme: HTTP
          readinessProbe:
            failureThreshold: 3
            initialDelaySeconds: 30
            httpGet:
              path: /health/readiness
              port: 80
              scheme: HTTP
          ports:
            - containerPort: 80
          imagePullPolicy: Always

注意:只需要一個指定的端口,因為我們要將所有(HTTP 和 HTTPS)流量指向它。 為簡單起見,我們對 liveness 和 readiness 探針使用相同的路徑; 這些檢查將在 NGINX 服務器上處理,但您可以並且應該添加檢查應用程序本身的健康狀況的檢查(例如,如果健康,則返回 200 的專用頁面)。 GCE 也將接收就緒性探測器,默認情況下,它有自己不可移除的健康檢查。

3 創建服務清單並應用/創建

服務.yaml:

apiVersion: v1
kind: Service
metadata:
  name: uber-svc
  labels:
    app: uber
spec:
  ports:
    - name: default-port
      port: 80
  selector:
    app: uber
  sessionAffinity: None
  type: NodePort

注意:default-port 指定容器上的端口 80。

4 獲取靜態IP地址

在漢堡包菜單中的 GCP 上:VPC 網絡 -> 外部 IP 地址。 轉換您自動生成的臨時 IP 或創建一個新 IP。 記下姓名和地址。

5 創建 SSL 證書和默認區域

在漢堡菜單中:網絡服務->負載平衡->點擊'高級菜單'->證書->創建SSL證書。 按照說明創建或上傳證書,並記下名稱。 然后,從菜單中:Cloud DNS -> 創建區域。 按照說明,為您的域創建一個默認區域 添加一個 CNAME 記錄,其中 www 作為 DNS 名稱,您的域作為規范名稱。 添加具有空 DNS 名稱值和靜態 IP 作為 IPV4 的 A 記錄。 保存。

6 創建入口清單並應用/創建

入口.yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: mypt-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: [NAME OF YOUR STATIC IP ADDRESS]
    kubernetes.io/ingress.allow-http: "true"
    ingress.gcp.kubernetes.io/pre-shared-cert: [NAME OF YOUR GOOGLE-MANAGED SSL]
spec:
  backend:
    serviceName: mypt-svc
    servicePort: 80

注意:后端屬性指向服務,該服務指向容器,其中包含由服務器“保護”的應用程序。 注釋將您的應用程序與 SSL 連接起來,並強制允許 http 進行健康檢查。 結合起來,服務和入口配置G7 負載平衡器(結合全局轉發規則、后端和前端“服務”、SSL 證書和目標代理等)。

7 泡杯茶什么的

一切都需要大約 10 分鍾來配置。 使用各種瀏覽器(Tor、Opera、Safari、IE 等)清除緩存並測試您的域。 一切都將通過 https 提供服務。

NGINX 入口控制器怎么樣? 我已經看到討論它更好,因為它更便宜/使用更少的資源並且更靈活。 它並不便宜:它需要額外的部署/工作負載和服務 (GCE L4)。 而且你需要做更多的配置。 是不是更靈活? 是的。 但是在處理大部分工作時,第一個選項為您提供了一種更重要的靈活性——即允許您處理更緊迫的事情。

對於像我這樣大約每個月搜索一次這個問題的每個人,Google 已經響應了我們的請求,並且正在他們的負載均衡器上測試 HTTP->HTTPS SSL 重定向。 他們的最新回答是,它應該在 2020 年 1 月底之前的某個時間處於 Alpha 狀態。

他們的評論:

感謝您對這個問題的耐心等待。 該功能目前正在測試中,我們預計將在 1 月底之前進入 Alpha 階段。 隨着我們接近 Alpha 發布,我們的 PM 團隊將發布包含更多詳細信息的公告。

更新:HTTP 到 HTTPS 重定向現已普遍可用: https : //cloud.google.com/load-balancing/docs/features#routing_and_traffic_management

GKE 使用自己的 Ingress Controller,不支持強制使用 https。

這就是您必須自己管理 NGINX Ingress Controller 的原因。

請參閱有關如何在 GKE 上執行此操作的帖子

希望它有幫助。

無論如何,我最終在 NGINX 中使用了反向代理。

  1. 您需要創建機密並將它們同步到您的容器中
  2. 您需要使用 nginx 配置在 nginx 中創建一個 configmap,以及引用此附加配置文件的默認配置。

這是我的配置:

worker_processes  1;

events {
    worker_connections  1024;
}


http {

default_type  application/octet-stream;

# Logging Configs
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile        on;
keepalive_timeout  65;

# Puntdoctor Proxy Config
include /path/to/config-file.conf;

# PubSub allows 10MB Files. lets allow 11 to give some space
client_max_body_size 11M;

}

然后,config.conf

server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}

server {

listen 443;
server_name example.com;

ssl_certificate           /certs/tls.crt;
ssl_certificate_key       /certs/tls.key;

ssl on;
ssl_session_cache  builtin:1000  shared:SSL:10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:AES128-GCM-SHA256:HIGH:!RC4:!MD5:!aNULL:!EDH:!CAMELLIA;
ssl_prefer_server_ciphers on;

location / {

  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 $http_host;

  # Fix the “It appears that your reverse proxy set up is broken" error.
  proxy_pass          http://deployment-name:8080/;
  proxy_read_timeout  90;

  proxy_redirect      http://deployment-name:8080/ https://example.com/;
}
}
  1. 創建部署:

這是 .yaml 文件

---
apiVersion: v1
kind: Service
metadata:
  name: puntdoctor-lb
spec:
   ports:
    - name: https
      port: 443
      targetPort: 443
     - name: http
      port: 80
      targetPort: 80
  selector:
    app: puntdoctor-nginx-deployment
  type: LoadBalancer
  loadBalancerIP: 35.195.214.7
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: puntdoctor-nginx-deployment
spec:
   replicas: 2
  template:
    metadata:
      labels:
        app: puntdoctor-nginx-deployment
    spec:
       containers:
       - name: adcelerate-nginx-proxy
        image: nginx:1.13
         volumeMounts:
        - name: certs
          mountPath: /certs/
        - name: site-config
          mountPath: /etc/site-config/
        - name: default-config
          mountPath: /etc/nginx/
        ports:
        - containerPort: 80
          name: http
        - containerPort: 443
          name: https
      volumes:
      - name: certs
        secret:
          secretName: nginxsecret
      - name: site-config
        configMap:
          name: nginx-config
       - name: default-config
        configMap:
         name: default

希望這有助於有人解決這個問題,感謝其他 2 個答案,他們都給了我寶貴的見解。

從 GKE 版本 1.18.10-gke.600 開始,您可以使用FrontendConfigGoogle 引擎中創建HTTP -> HTTPS redirection Z30136395F01879792198317C18

HTTP 到 HTTPS 重定向是使用 FrontendConfig 自定義資源中的 redirectToHttps 字段配置的。 為整個 Ingress 資源啟用重定向,因此 Ingress 引用的所有服務都將啟用 HTTPS 重定向。

以下 FrontendConfig 清單啟用 HTTP 到 HTTPS 重定向。 將 spec.redirectToHttps.enabled 字段設置為 true 以啟用 HTTPS 重定向。 spec.responseCodeName 字段是可選的。 如果省略,則使用 301 Moved Permanently 重定向。

例如:

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

MOVED_PERMANENTLY_DEFAULT位於可用的RESPONSE_CODE字段值中,以返回301重定向響應代碼(如果未指定responseCodeName ,則為默認值)。

您可以在此處找到更多選項: HTTP 到 HTTPS 重定向

然后您必須將您的 FrontendConfig 鏈接到 Ingress,如下所示:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: your-ingress-name
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: your-frontend-config-name
spec:
  tls:
    ...

暫無
暫無

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

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