使用 FQDN 網路政策控管 Pod 輸出流量


本頁說明如何使用完整網域名稱 (FQDN),控管 Pod 與 Google Kubernetes Engine (GKE) 叢集外部資源之間的輸出通訊。您用來設定 FQDN 的自訂資源是 FQDNNetworkPolicy 資源。

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

需求條件和限制

FQDNNetworkPolicy 資源須符合下列規定和限制:

  • 您必須有執行下列其中一個版本的 GKE 叢集:
    • 1.26.4-gke.500 以上版本
    • 1.27.1-gke.400 以上版本
  • 叢集必須使用 GKE Dataplane V2
    • 您必須在 GKE 叢集中使用其中一個 DNS 供應商,也就是 kube-dns 或 Cloud DNS。不支援自訂 kube-dns 或 Core DNS 部署作業。
  • Google Cloud CLI 462.0.0 以上版本。
  • 不支援 Windows 節點集區。
  • 不支援 Cloud Service Mesh。
  • 如果應用程式中含有硬式編碼的 IP 位址,請使用 Kubernetes 的 IPBlock NetworkPolicy 欄位,而非 FQDNNetworkPolicy
  • 非叢集 DNS 名稱伺服器 (例如 resolv.conf 中的替代名稱伺服器) 傳回的結果,不會視為有效,因此無法在 GKE 資料層的允許清單中進行程式設計。
  • FQDNNetworkPolicy最多可解析為 50 個 IPv4 和 IPv6 IP 位址。
  • 您無法在 FQDNNetworkPolicy 中允許流量前往 ClusterIP 或無 Head 服務,做為輸出目的地,因為 GKE 會先將服務虛擬 IP 位址 (VIP) 轉換為後端 Pod IP 位址,再評估網路政策規則。請改用 Kubernetes 標籤。NetworkPolicy
  • 每個主機名稱的 IP 位址配額上限為 100 個。
  • 節點間透明加密功能不支援 FQDN 網路政策。
  • 使用模式比對的 FQDN 網路政策只會比對與萬用字元同層級的子網域。舉例來說,pattern: *.company.comapi.company.comstore.company.com 相符,但與 eu.api.company.comcompany.com 不相符。

啟用 FQDN 網路政策

您可以在新叢集或現有叢集上啟用 FQDN 網路政策。

在新叢集中啟用 FQDN 網路政策

使用 --enable-fqdn-network-policy 旗標建立叢集:

gcloud container clusters create CLUSTER_NAME  \
    --enable-fqdn-network-policy

CLUSTER_NAME 替換為叢集名稱。

在現有叢集中啟用 FQDN 網路政策

  1. 不論是 Autopilot 還是 Standard 叢集,請使用 --enable-fqdn-network-policy 旗標更新叢集:

    gcloud container clusters update CLUSTER_NAME  \
        --enable-fqdn-network-policy
    

    CLUSTER_NAME 替換為叢集名稱。

  2. 僅限標準叢集,請重新啟動 GKE Dataplane V2 anetd DaemonSet:

    kubectl rollout restart ds -n kube-system anetd
    

建立 FQDNNetworkPolicy

  1. 將下列資訊清單儲存為 fqdn-network-policy.yaml

    apiVersion: networking.gke.io/v1alpha1
    kind: FQDNNetworkPolicy
    metadata:
      name: allow-out-fqdnnp
    spec:
      podSelector:
        matchLabels:
          app: curl-client
      egress:
      - matches:
        - pattern: "*.yourdomain.com"
        - name: "www.google.com"
        ports:
        - protocol: "TCP"
          port: 443
    

    這個資訊清單具有下列屬性:

    • name: www.google.com:完整網域名稱。允許使用與 www.google.com 相關聯的名稱伺服器提供的 IP 位址。您必須指定 name 和/或 pattern
    • pattern: "*.yourdomain.com":允許名稱伺服器提供的 IP 位址符合此模式。您可以使用下列規則運算式做為模式鍵:^([a-zA-Z0-9*]([-a-zA-Z0-9_*]*[a-zA-Z0-9*])*\.?)*$。比對條件是累加的。您可以使用多個 pattern 欄位。您必須指定 name 和/或 pattern
    • protocol: "TCP"port: 443:指定通訊協定和通訊埠。如果 Pod 嘗試使用這個通訊協定和連接埠組合建立與 IP 位址的連線,名稱解析作業會正常運作,但資料層會封鎖輸出連線。這是選填欄位。
  2. 確認網路政策是否選取工作負載:

    kubectl describe fqdnnp
    

    輸出結果會與下列內容相似:

    Name:         allow-out-fqdnnp
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1alpha1
    Kind:         FQDNNetworkPolicy
    Metadata:
    ...
    Spec:
      Egress:
        Matches:
          Pattern:  *.yourdomain.com
          Name:     www.google.com
        Ports:
          Port:      443
          Protocol:  TCP
      Pod Selector:
        Match Labels:
          App: curl-client
    Events:     <none>
    

刪除 FQDNNetworkPolicy

您可以使用 kubectl delete fqdnnp 指令刪除 FQDNNetworkPolicy

kubectl delete fqdnnp FQDN_POLICY_NAME

FQDN_POLICY_NAME 替換成您的 FQDNNetworkPolicy 名稱。

GKE 會從政策強制執行中刪除規則,但現有連線會保持有效,直到連線依據 conntrack 標準通訊協定指南關閉為止。

FQDN 網路政策的運作方式

FQDNNetworkPolicies 是僅限輸出的政策,可控管所選 Pod 可將流量傳送至哪些端點。與 Kubernetes NetworkPolicy 類似,選取工作負載的 FQDNNetworkPolicy 會為未指定為允許輸出目的地的端點建立隱含的拒絕規則。FQDNNetworkPolicies 可與 Kubernetes NetworkPolicies 搭配使用,詳情請參閱 FQDNNetworkPolicy 和 NetworkPolicy

FQDNNetworkPolicies 是在 IP 位址和通訊埠層級強制執行,系統不會使用任何第 7 層通訊協定資訊 (例如 HTTP 要求中的 Request-URI) 強制執行這些限制。系統會使用 GKE 叢集 DNS 供應商提供的 DNS 資訊,將指定的網域名稱轉換為 IP 位址。

DNS 要求

選取工作負載的有效 FQDNNetworkPolicy 不會影響工作負載發出 DNS 要求的能力。nslookupdig 等指令可在任何網域上運作,不受政策影響。不過,如果後續要求傳送至不在允許清單中的網域支援 IP 位址,就會遭到捨棄。

舉例來說,如果 FQDNNetworkPolicy 允許輸出至 www.github.com,則系統會允許所有網域的 DNS 要求,但會捨棄傳送至 twitter.com 後端 IP 位址的流量。

存留時間到期

FQDNNetworkPolicy 會遵守 DNS 記錄提供的 TTL。如果 Pod 在 DNS 記錄的 TTL 經過後,嘗試連線至過期的 IP 位址,系統會拒絕建立新連線。如果連線時間超過 DNS 記錄的 TTL,conntrack 會將連線視為仍處於有效狀態,因此連線不會中斷。

FQDNNetworkPolicy 和 NetworkPolicy

如果同時有 FQDNNetworkPolicyNetworkPolicy 套用至同一個 Pod,也就是 Pod 的標籤符合政策中設定的內容,只要輸出流量符合其中一項政策,系統就會允許輸出流量。指定 IP 位址或標籤選取器的輸出 NetworkPoliciesFQDNNetworkPolicies 之間沒有階層。

共用 IP 位址端點 (負載平衡器、CDN、VPN 閘道等)

許多網域沒有專屬的 IP 位址,而是使用共用 IP 位址。如果應用程式是由負載平衡器或 CDN 提供服務,這種情況就特別常見。舉例來說,Google Cloud API (compute.googleapis.comcontainer.googleapis.com 等) 不會為每個 API 提供專屬 IP 位址。而是透過共用範圍公開所有 API。

設定 FQDNNetworkPolicies 時,請務必考量允許的網域是使用專屬 IP 位址還是共用 IP 位址。由於 FQDNNetworkPolicies 是在 IP 位址和通訊埠層級強制執行,因此無法區分由相同 IP 位址放送的多個網域。允許存取共用 IP 位址支援的網域後,Pod 就能與該 IP 位址服務的所有其他網域通訊。舉例來說,允許流量前往 compute.googleapis.com,也會允許 Pod 與其他 Google Cloud API 通訊。

CNAME 追蹤

如果 FQDNNetworkPolicy 中的 FQDN 物件包含 DNS 記錄中具有 CNAME 的網域,您必須使用 Pod 可直接查詢的所有網域名稱 (包括所有可能的別名) 設定 FQDNNetworkPolicy,確保 FQDNNetworkPolicy 行為可靠。

如果 Pod 查詢 example.com,則您應在規則中寫入 example.com。即使您從上游 DNS 伺服器取得別名鏈結 (例如 example.comexample.cdn.com1.2.3.4),完整網域名稱網路政策仍會允許流量通過。

已知問題

本節列出完整網域名稱 (FQDN) 的所有已知問題。

指定 protocol: ALL 會導致系統忽略政策

GKE 1.27.10-gke.1055000+ 和 1.28.3-gke.1055000+ 版本已修正這項已知問題

如果您建立 FQDNNetworkPolicy,並在 ports 區段中指定 protocol: ALL,GKE 不會強制執行政策。發生這個問題的原因是政策剖析有問題。指定 TCPUDP 不會導致這個問題。

如要解決這個問題,請勿在 ports 項目中指定 protocol,這樣規則預設會比對所有通訊協定。移除 protocol: ALL 可解決剖析問題,GKE 也會強制執行 FQDNNetworkPolicy

在 GKE 1.27.10-gke.1055000+ 和 1.28.3-gke.1055000+ 版本中,系統會正確剖析並強制執行含有 protocol: ALL 的政策。

NetworkPolicy 記錄功能會導致記錄有誤或缺漏

這個已知問題已在 GKE 1.27.10-gke.1055000+ 和 1.28.2-gke.1157000+ 版本中修正

如果叢集使用網路政策記錄和 FQDN 網路政策,可能會發生錯誤,導致記錄項目遺失或不正確。

使用沒有委派的網路政策記錄時,離開工作負載的 DNS 連線政策記錄會錯誤地聲稱流量已遭捨棄。流量本身符合規定 (根據 FQDNNetworkPolicy),但記錄有誤。

使用委派功能時,網路政策記錄會遺失。流量本身不會受到影響。

這個錯誤已在 GKE 1.27.10-gke.105500+ 和 1.28.2-gke.1157000+ 版本中修正。如果流量是由 NetworkPolicyFQDNNetworkPolicy 選取,系統現在會正確將 DNS 連線記錄為 ALLOWED。

後續步驟