本頁面說明如何保護及最佳化 Google Kubernetes Engine (GKE) Ingress 的流量。您可以在用戶端和負載平衡器之間設定 SSL 憑證,並保護負載平衡器和後端應用程式之間的流量。繼續操作前,請務必熟悉 GKE 如何使用 HTTPS 保護 Ingress。
本頁面適用於網路專家,他們負責為組織設計網路架構,以及安裝、設定和支援網路設備。如要進一步瞭解Cloud de Confiance by S3NS 內容中提及的常見角色和工作範例,請參閱「常見的 GKE 使用者角色和工作」。
保護及最佳化用戶端與負載平衡器之間的流量
如要接受用戶端的 HTTPS 要求,負載平衡器必須具備憑證,向用戶端證明其身分。負載平衡器也必須具備私密金鑰,才能完成 HTTPS 握手。如要進一步瞭解如何為 HTTP(S) 負載平衡器提供 SSL 憑證,請參閱「設定用戶端與負載平衡器之間的 TLS」。
使用 Google 代管憑證
如要設定一或多個 Google 代管的 SSL 憑證,並將其與 Ingress 建立關聯,請按照下列步驟操作:
- 在與 Ingress 相同的命名空間中,建立一或多個 ManagedCertificate 物件。最多可為負載平衡器指定 15 個憑證
- 將
networking.gke.io/managed-certificates註解新增至 Ingress,即可將 ManagedCertificate 物件與 Ingress 建立關聯。這個註解是以半形逗號分隔的 ManagedCertificate 物件清單。
限制
本節說明 Google 代管憑證的限制。如果您需要自行管理的憑證,或已擁有想在 Ingress 設定的 SSL 憑證,請參閱「在用戶端和負載平衡器之間設定 HTTPS (TLS)」。
與您取得且自行管理的憑證相較,Google 代管憑證較不具彈性。Google 代管憑證最多支援 100 個非萬用字元網域。與自行管理的憑證不同,Google 代管憑證不支援萬用字元網域。
Ingress 支援的憑證數量和類型,取決於 Google 代管 SSL 憑證的限制。
不支援更新 Google 代管憑證。詳情請參閱「手動更新 Google 代管的憑證」。
如果直接向憑證授權單位撤銷憑證,Google 不會自動輪替憑證。您必須刪除 ManagedCertificate 並建立新的。
GKE Ingress 不支援由 Certificate Manager 代管的憑證。如要使用由 Certificate Manager 代管的憑證,請使用 Gateway API。
必要條件
您必須擁有網域名稱,網域名稱的長度不得超過 63 個字元。您可以使用任何網域名稱註冊商取得網域名稱。
如果使用 GKE Standard 叢集,則必須啟用
HttpLoadBalancing外掛程式。Ingress 資訊清單必須包含
kubernetes.io/ingress.class: "gce"註解。不支援ingressClassName欄位。您必須在同一個專案和命名空間中套用 Ingress 和 ManagedCertificate 資源。
建立預留 (靜態) 外部 IP 位址。預留靜態 IP 位址可確保即使刪除 Ingress,該位址仍屬於您。如果不預留 IP 位址,該位址可能會變更,屆時您就必須重新設定網域的 DNS 記錄。使用 Google Cloud CLI 或 Cloud de Confiance 控制台建立預留 IP 位址。
gcloud
如要建立預留 IP 位址,請執行下列指令:
gcloud compute addresses create ADDRESS_NAME --global將
ADDRESS_NAME替換為要建立的預留 IP 位址名稱。如要找出您建立的靜態 IP 位址,請執行下列指令:
gcloud compute addresses describe ADDRESS_NAME --global輸出結果會與下列內容相似:
address: 203.0.113.32 ...控制台
如要建立預留 IP 位址,請按照下列步驟操作:
前往 Cloud de Confiance 控制台的「External IP addresses」(外部 IP 位址) 頁面。
指定 IP 位址的名稱 (例如
example-ip-address)。指定要使用 IPv4 還是 IPv6 位址。
在「類型」部分,選取「全域」。
按一下「Reserve」(預留)。 IP 位址會列在「External Address」(外部位址) 欄中。
Config Connector
注意:這個步驟需要 Config Connector。按照安裝操作說明,在叢集上安裝 Config Connector。
如要部署這個資訊清單,請將其下載到您的機器上,並命名為compute-address.yaml,然後執行:kubectl apply -f compute-address.yaml
設定 Google 代管憑證
建立 ManagedCertificate 物件。這項資源會指定 SSL 憑證的網域。不支援萬用字元網域。
下列資訊清單說明 ManagedCertificate 物件。將資訊清單儲存為
managed-cert.yaml。apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: FIRST_CERT_NAME spec: domains: - FIRST_DOMAIN --- apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: SECOND_CERT_NAME spec: domains: - SECOND_DOMAIN更改下列內容:
FIRST_CERT_NAME:第一個 ManagedCertificate 物件的名稱。FIRST_DOMAIN:您擁有的第一個網域。SECOND_CERT_NAME:第二個 ManagedCertificate 物件的名稱。SECOND_DOMAIN:您擁有的第二個網域。
ManagedCertificate 物件的名稱與其建立的實際憑證名稱不同。您只需要知道 ManagedCertificate 物件的名稱,即可在 Ingress 中使用這些物件。
將資訊清單套用至叢集:
kubectl apply -f managed-cert.yaml請按照操作說明建立 Deployment 和 Service,將應用程式公開發布至網際網路。
如要將這個 ManagedCertificate 物件設為
Active,請使用networking.gke.io/managed-certificates註解將其附加至 Ingress,如以下範例所示。ManagedCertificate 不必處於Active狀態,即可附加至 Ingress。如要從自行管理的憑證遷移現有的 Ingress,請改為按照「從自行管理的憑證遷移至 Google 代管憑證」中的步驟操作。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-gmc-ingress annotations: networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002 ``` Replace <code><var>FIRST_DOMAIN</var></code> and <code><var>SECOND_DOMAIN</var></code> with your domain names. This manifest describes an Ingress that lists pre-shared certificate resources in an annotation. Note: It might take several hours for Cloud de Confiance to provision the load balancer and the managed certificates, and for the load balancer to begin using the new certificates. For more information, see [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).等待 Google 代管憑證佈建完成。這項作業最多可能需要 60 分鐘。您可以使用下列指令檢查憑證狀態:
kubectl describe managedcertificate managed-cert輸出結果會與下列內容相似:
Name: managed-cert Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: ManagedCertificate (...) Spec: Domains: FQDN_1 FQDN_2 Status: CertificateStatus: Active (...)Status.CertificateStatus欄位的值表示憑證已佈建。如果Status.CertificateStatus不是Active,表示憑證尚未佈建。使用
https://前置字元造訪網域,確認 SSL 是否正常運作。瀏覽器會指出連線安全,您可以查看憑證詳細資料。
從自行管理憑證遷移至 Google 代管憑證
將 Ingress 從使用自行管理的 SSL 憑證遷移至 Google 代管的 SSL 憑證時,請勿在 Google 代管的 SSL 憑證啟用前,移除自行管理的 SSL 憑證。
如要從自行管理的 SSL 憑證遷移至 Google 代管的 SSL 憑證,且不中斷流量,請按照下列步驟操作:
建立 ManagedCertificate 資源,並套用至叢集,詳情請參閱「設定 Google 代管的憑證」。
更新 Ingress 資訊清單,新增指向新 ManagedCertificate 資源的
networking.gke.io/managed-certificates註解。請在ingress.gcp.kubernetes.io/pre-shared-cert註解中保留現有的自行管理憑證,如以下範例所示:metadata: annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "EXISTING_SELF_MANAGED_CERT_NAME" networking.gke.io/managed-certificates: "NEW_MANAGED_CERT_NAME"更改下列內容:
EXISTING_SELF_MANAGED_CERT_NAME:現有自行管理 SSL 憑證資源的名稱。NEW_MANAGED_CERT_NAME:新 ManagedCertificate 物件的名稱。
套用更新後的 Ingress 資訊清單:
kubectl apply -f INGRESS_MANIFEST.yaml將
INGRESS_MANIFEST替換為 Ingress 資訊清單檔案的名稱。建立 ManagedCertificate 資源後,ManagedCertificate 控制器會建立 Compute Engine SSL 憑證資源 (產生的名稱開頭為
mcrt-)。套用 Ingress 資訊清單會觸發同步處理作業,將產生的mcrt-憑證名稱新增至現有 Ingress 的ingress.gcp.kubernetes.io/pre-shared-cert註解,以便 Ingress 控制器將其附加至負載平衡器的目標 Proxy。 Cloud de Confiance 佈建新憑證時,負載平衡器會繼續使用您在ingress.gcp.kubernetes.io/pre-shared-cert註解中定義的現有有效自行管理憑證,為流量提供服務。等待 ManagedCertificate 資源的狀態變更為
Active,這項作業最多可能需要 60 分鐘。佈建完成後,自行管理的憑證和 Google 代管的憑證都會在負載平衡器上啟用。說明 ManagedCertificate 資源,查看狀態並擷取產生的mcrt-憑證 ID:kubectl describe managedcertificate NEW_MANAGED_CERT_NAME輸出結果會與下列內容相似:
Name: NEW_MANAGED_CERT_NAME Namespace: default (...) Spec: Domains: DOMAIN Status: Certificate Name: MCRT_CERT_ID Certificate Status: Active Domain Status: Domain: DOMAIN Status: Active記下
Status區段中Certificate Name欄位的值 (例如mcrt-a1b2c3d4-e5f6-7890-abcd-ef1234567890)。在 Ingress 資訊清單中,將
ingress.gcp.kubernetes.io/pre-shared-cert註解中的自行管理憑證 ID 替換為 Google 代管憑證的 ID:metadata: annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "MCRT_CERT_ID" networking.gke.io/managed-certificates: "NEW_MANAGED_CERT_NAME"將
MCRT_CERT_ID替換為上一步的Certificate Name值 (開頭為mcrt-)。套用更新後的 Ingress 資訊清單:
kubectl apply -f INGRESS_MANIFEST.yaml套用這項變更後,系統會將舊的自行管理憑證從負載平衡器中卸載,同時保留
ingress.gcp.kubernetes.io/pre-shared-cert註解中附加的有效 Google 代管憑證 (MCRT_CERT_ID)。這項變更會將所有流量切換至 Google 代管的憑證,不會造成服務中斷。將舊的自行管理憑證從負載平衡器卸載後,如果不再需要,可以安全刪除,因為預先共用的 Compute Engine SSL 憑證資源不會由 Ingress 控制器管理或垃圾收集:
gcloud compute ssl-certificates delete EXISTING_SELF_MANAGED_CERT_NAME
為避免註解協調問題,並取得萬用字元憑證的內建支援,請從 Ingress 遷移至 GKE Gateway API,並搭配使用 Certificate Manager。
移除 Google 代管憑證
如要從叢集移除 Google 代管憑證,您必須刪除 ManagedCertificate 物件,並移除參照該物件的 Ingress 註解。
刪除 ManagedCertificate 物件:
kubectl delete -f managed-cert.yaml輸出結果會與下列內容相似:
managedcertificate.networking.gke.io "managed-cert" deleted移除 Ingress 中的註解:
kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-請注意指令結尾的減號
-。釋出為負載平衡器保留的靜態 IP 位址。
您可以使用 Google Cloud CLI、 Cloud de Confiance 控制台或 Config Connector 釋出保留的 IP 位址。
gcloud
使用下列指令釋出保留的 IP 位址:
gcloud compute addresses delete ADDRESS_NAME --global將
ADDRESS_NAME替換為 IP 位址名稱。控制台
如要釋出保留的 IP 位址,請按照下列步驟操作:
前往 Cloud de Confiance 控制台的「External IP addresses」(外部 IP 位址) 頁面。
找出要釋出的 IP 位址,然後勾選旁邊的核取方塊。
按一下 [Release IP address] (釋出 IP 位址)。
Config Connector
注意:這個步驟需要 Config Connector。按照安裝操作說明,在叢集上安裝 Config Connector。
如要部署這個資訊清單,請將其下載到您的機器上,並命名為
compute-address.yaml,然後執行:kubectl delete -f compute-address.yaml
建立憑證和金鑰
如要使用預先共用的憑證或 Kubernetes Secret,您必須先有一或多個憑證,以及對應的私密金鑰。每個憑證都必須有一般名稱 (CN),且與您擁有的網域名稱相同。若您已有具備適當的「共用名稱」值的兩個憑證檔案,可直接前往下一節。
建立第一個金鑰:
openssl genrsa -out test-ingress-1.key 2048建立第一個憑證簽署要求:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=FIRST_DOMAIN"將
FIRST_DOMAIN替換成您擁有的網域名稱,例如example.com。建立第一個憑證:
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt建立第二個金鑰:
openssl genrsa -out test-ingress-2.key 2048建立第二個憑證簽署要求:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=SECOND_DOMAIN"將
SECOND_DOMAIN替換成您擁有的其他網域名稱,例如examplepetstore.com。建立第二個憑證:
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
如要進一步瞭解憑證和金鑰,請參閱「SSL 憑證總覽」。
您現在有兩個憑證檔案和兩個金鑰檔案。
其餘工作會使用下列預留位置,代表您的網域、憑證和金鑰:
FIRST_CERT_FILE:第一個憑證檔案的路徑。FIRST_KEY_FILE:第一個憑證對應的金鑰檔案路徑。FIRST_DOMAIN:您擁有的網域名稱。FIRST_SECRET_NAME:Secret 的名稱,其中包含第一個憑證和金鑰。SECOND_CERT_FILE:第二個憑證檔案的路徑。SECOND_KEY_FILE:第二個憑證的金鑰檔案路徑。SECOND_DOMAIN:您擁有的第二個網域名稱。SECOND_SECRET_NAME:Secret 名稱,內含第二個憑證和金鑰。
使用預先共用的憑證
您可以使用上傳至 Cloud de Confiance 專案的自行管理 SSL 憑證。這類憑證稱為預先共用憑證。您可以為 Ingress 指定一或多個預先共用的憑證。
如要使用多個預先共用憑證,請按照下列步驟操作:
請在 Cloud de Confiance中,為每個憑證和金鑰組建立公開顯示的 SSL 憑證資源。
gcloud compute ssl-certificates create FIRST_CERT_NAME \ --certificate=FIRST_CERT_FILE \ --private-key=FIRST_KEY_FILE ``` ```sh gcloud compute ssl-certificates create SECOND_CERT_NAME \ --certificate=SECOND_CERT_FILE \ --private-key=SECOND_KEY_FILE ``` Replace the following:FIRST_CERT_NAME、SECOND_CERT_NAME:第一個和第二個憑證的名稱。FIRST_CERT_FILE、SECOND_CERT_FILE:您的第一個和第二個憑證檔案。FIRST_KEY_FILE:SECOND_KEY_FILE:第一個和第二個金鑰檔案。
在 Ingress 資訊清單中,新增
ingress.gcp.kubernetes.io/pre-shared-cert註解。註解的值是您的憑證名稱的逗號分隔的清單。此外,請在spec.rules區段中加入host欄位,指定服務的網域。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-psc-ingress annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002 ``` Replace <code><var>FIRST_DOMAIN</var></code> and <code><var>SECOND_DOMAIN</var></code> with your domain names. This manifest describes an Ingress that lists pre-shared certificate resources in an annotation.
使用 Kubernetes Secret
如要為 HTTP(S) 負載平衡器提供您自行建立的憑證和金鑰,請建立一或多個 Kubernetes Secret 物件。每個 Secret 都包含憑證和金鑰。請將 Secret 新增至 Ingress 資訊清單的 tls 欄位。負載平衡器會根據 TLS 握手中的網域名稱,使用伺服器名稱指示 (SNI) 決定要向用戶端提供哪個憑證。
如要使用多個憑證,請按照下列步驟操作:
為每個憑證和金鑰組建立 Secret:
kubectl create secret tls FIRST_SECRET_NAME \ --cert=FIRST_CERT_FILE \ --key=FIRST_KEY_FILE ``` ```sh kubectl create secret tls SECOND_SECRET_NAME \ --cert=SECOND_CERT_FILE \ --key=SECOND_KEY_FILE ```在 Ingress 資訊清單的
spec.tls部分,列出您建立的 Secret。此外,請在spec.rules區段中加入host欄位,指定服務的網域。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-mc-ingress spec: tls: - secretName: FIRST_SECRET_NAME - secretName: SECOND_SECRET_NAME rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002將
FIRST_DOMAIN和SECOND_DOMAIN替換成您擁有的網域名稱,例如example.com和examplepetstore.com。
系統會定期擷取 Secret 的變更,因此如果您修改 Secret 內的資料,最多需要 10 分鐘,這些變更才會套用至負載平衡器。
如要為 GKE 叢集保護 HTTPS 加密 Ingress,請參閱安全 Ingress 範例。
停用 HTTP
如要讓用戶端和負載平衡器之間的所有流量都使用 HTTPS,可以在 Ingress 資訊清單中加入 kubernetes.io/ingress.allow-http 註解,停用 HTTP。將註解的值設為 "false"。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress-2
annotations:
kubernetes.io/ingress.allow-http: "false"
spec:
tls:
- secretName: SECRET_NAME
...
這個資訊清單包含 SECRET_NAME,也就是您建立的 Secret 名稱。
用戶端和負載平衡器之間的 HTTP/2
用戶端可以使用 HTTP/2 向負載平衡器傳送要求,您無需再進行設定。
保護及最佳化負載平衡器與應用程式之間的流量
您可以設定負載平衡器和應用程式 Pod 之間的通訊協定,確保端對端安全防護機制,或最佳化內部流量效能。雖然負載平衡器預設會使用未加密的 HTTP/1.1 進行後端連線,但您可以啟用 HTTPS 或 HTTP/2,以符合應用程式的特定需求。
負載平衡器和應用程式之間的 HTTPS
如果 GKE Pod 中執行的應用程式可以接收 HTTPS 要求,您可以將負載平衡器設為在將要求轉送至應用程式時使用 HTTPS。若須更多訊息,請參閱負載平衡器和應用程式之間的 HTTPS (TLS)。
如要設定負載平衡器和應用程式之間使用的通訊協定,請在 Service 資訊清單中使用 cloud.google.com/app-protocols 註解。除非您使用容器原生負載平衡,否則這個 Service 資訊清單必須包含 type: NodePort。如果您使用容器原生負載平衡,請使用 type: ClusterIP。
以下 Service 資訊清單指定了兩個通訊埠。註解指出,當 HTTP(S) 負載平衡器指定 Service 的通訊埠 80 時,應使用 HTTP。當負載平衡器指定 Service 的通訊埠 443 時,應使用 HTTPS。
Service 資訊清單必須在通訊埠註解中包含 name 值。您只能透過指派的 name 編輯 Service 通訊埠,而不能透過 targetPort 值。
apiVersion: v1
kind: Service
metadata:
name: my-service-3
annotations:
cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
type: NodePort
selector:
app: metrics
department: sales
ports:
- name: my-https-port
port: 443
targetPort: 8443
- name: my-http-port
port: 80
targetPort: 50001
在負載平衡器和應用程式之間使用 HTTP/2
如果 GKE Pod 中執行的應用程式可以接收 HTTP/2 要求,您可以將負載平衡器設為在將要求轉送至應用程式時使用 HTTP/2。
如要啟用 HTTP/2,您必須在 Kubernetes Service 資訊清單中使用 cloud.google.com/app-protocols 註解。這個註解會指定負載平衡器與應用程式通訊時使用的通訊協定。為確保負載平衡器向後端發出正確的 HTTP/2 要求,後端必須設定 SSL。
以下是為 HTTP/2 設定的 Service 資訊清單範例:
apiVersion: v1
kind: Service
metadata:
name: my-http2-service
annotations:
cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
type: NodePort
selector:
app: my-app
ports:
- name: my-port
protocol: TCP
port: 443
targetPort: 8443
注意事項:
cloud.google.com/app-protocols註解設為'{"my-port":"HTTP2"}',指示負載平衡器對傳送至my-port通訊埠的流量使用 HTTP/2。- 通訊埠設為
443,並將流量導向targetPort8443上的 Pod。