GKE設定Ingress並設定SSL憑證

2022/10/25

注意事項

Cluster addon必須啟用HttpLoadBalancing

新建立cluster的情況可參考gcloud container clusters create command的addon選項

對於已存在的cluster更新

可參考gcloud container clusters update command的update-addons選項

 

設定Ingress

 

完整範例(ingress.yml)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodejs-web-ingress
spec:
  defaultBackend:
    service:
      name: nodejs-web-service
      port:
        number: 80
  rules:
  # 設定網域
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nodejs-web-service
            port:
              number: 80

 

apply

apply之後要稍微等一下ingress ip才會建立並且正確指向service(我自己觀察每次都大約要五、六分鐘)

kubectl apply -f ingress.yml

 

先調整/etc/hosts測試

上述的example.com可改為自己的網域

除了可以直接設定DNS之外

一開始也可以先在/etc/hosts中設定IP讓本機可將網域指向該ingress ip

範例如下

34.160.90.99    example.com

 

這樣設定好之後

瀏覽器開啟example.com就會自動指向ingress ip

 

設定固定IP、DNS

 

設定固定IP

gcloud compute addresses create [static-ip-name] --global

 

DNS

使用A紀錄將網域指向固定IP

設定好之後記得移除先前/etc/hosts中的網址對應IP設定

 

設定Google-managed憑證

ref

 

完整設定檔(cert.yml)

apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: [cert-name]
spec:
  domains:
    - example.com
    - foobar.com

 

注意事項

要注意的是

根據Load Balancing的官方文件Renew a Google-managed SSL certificate段落說明

Google雖然會自動在憑證到期之前更新

但必須確保憑證內設定的domain或subdomain必須正確指向該Load balancer IP

只要一個domain沒正確指向

將會造成這個憑證更新失敗

 

apply

kubectl apply -f cert.yml

 

apply之後可透過以下指令查看狀態

kubectl get managedCertificate

# 查看細節
kubectl describe managedcertificate [cert-name]

 

憑證狀態一開始為PROVISIONING

文件上寫要花大約一小時才會轉為ACTIVE狀態(生效)

不過我自己測試大約在憑證建立20分鐘左右就會生效

 

調整ingress憑證相關設定

這步驟不需要等上面的憑證狀態生效(ACTIVE)

 

調整annotations

annotations:
  # GCP固定IP名稱
  kubernetes.io/ingress.global-static-ip-name: [static-ip-name]
  # 前面建立的Google-managed憑證名稱
  networking.gke.io/managed-certificates: [cert-name]
  kubernetes.io/ingress.class: gce

 

重新apply ingress

kubectl apply -f ingress.yml

 

測試(需等憑證狀態為ACTIVE)

在apply之後

使用curl指令存取https網域測試

curl https://example.com

 

將HTTP強制轉為HTTPS

ref

 

建立FrontendConfig(frontendConfig.yml)

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

 

apply FrontendConfig

kubectl apply -f frontendConfig.yml

 

調整ingress.annotations

新增networking.gke.io/v1beta1.FrontendConfig屬性

值要同前面FrontendConfig資源的名稱

annotations:
  networking.gke.io/v1beta1.FrontendConfig: ingress-frontend-config

 

重新apply ingress

kubectl apply -f ingress.yml

 

測試

ingress需要等一段時間生效

待調整生效之後

開啟瀏覽器的dev tools network

並前往http網域後

就會發現被強制導向https(並且是透過308 redirect)

 

完整範例

 

合併ingress/frontendConfig/憑證設定

合併為單一檔案後一次apply

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nodejs-web-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: [static-ip-name]
    networking.gke.io/managed-certificates: [cert-name]
    kubernetes.io/ingress.class: gce

    # 一開始先不要強制設定HTTPS
    # networking.gke.io/v1beta1.FrontendConfig: ingress-frontend-config
spec:
  defaultBackend:
    service:
      name: nodejs-web-service
      port:
        number: 80
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nodejs-web-service
            port:
              number: 80
---
apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: ingress-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: PERMANENT_REDIRECT
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: [cert-name]
spec:
  domains:
    - example.com

 

設定強制轉HTTPS

在這步執行前

一定要確認憑證生效(可透過curl https://example.com)才行

不然後續會有問題

 

將上方ingress.annotations內的強制轉HTTPS設定註解拿掉

重新apply ingress

接著需要等數分鐘生效

 

驗證是否有強制轉為HTTPS

可透過瀏覽器dev tools的network

發現前往HTTP網址被執行redirect 308

308-redirect.png

 

也可以透過curl來驗證

使用curl -I http://example.com來確認response header是否為redirect 308

308-redirect2.png

 

再次強調順序性

最後一步的強制轉HTTPS一定要等憑證生效後

再設定ingress annotations重新apply一次

不然最後連HTTP/HTTPS這兩個都會有問題

 

順序性如下

  • 設定好固定IP
  • DNS將網域指向該IP
  • 建立ingress/frontendConfig憑證(一開始憑證尚未為ACTIVE狀態的時候, ingress就可以使用annotations做attache)
  • 確認憑證生效(可透過curl https://example.com)
  • ingress annotations設定強制HTTP轉HTTPS

 

相關參考資料