GKE設定Ingress並設定SSL憑證
注意事項
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憑證
完整設定檔(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
建立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
也可以透過curl來驗證
使用curl -I http://example.com來確認response header是否為redirect 308
再次強調順序性
最後一步的強制轉HTTPS一定要等憑證生效後
再設定ingress annotations重新apply一次
不然最後連HTTP/HTTPS這兩個都會有問題
順序性如下
- 設定好固定IP
- DNS將網域指向該IP
- 建立ingress/frontendConfig憑證(一開始憑證尚未為ACTIVE狀態的時候, ingress就可以使用annotations做attache)
- 確認憑證生效(可透過curl https://example.com)
- ingress annotations設定強制HTTP轉HTTPS
相關參考資料