使用網路政策記錄功能


本頁說明如何使用 Google Kubernetes Engine (GKE) 的網路政策記錄功能。Kubernetes 網路政策可指定 Pod 允許傳送及接收的網路流量。網路政策記錄功能可讓您記錄網路政策允許或拒絕連線的時間。網路政策記錄有助於排解網路政策問題。

總覽

使用網路政策記錄功能,您可以:

  • 確認網路政策運作正常。
  • 瞭解叢集中哪些 Pod 會與網際網路通訊。
  • 瞭解哪些命名空間正在相互通訊。
  • 辨識阻斷服務攻擊。

如果啟用 Cloud Logging,系統會將網路政策記錄上傳至 Cloud Logging,以供儲存、搜尋、分析及發出快訊。新叢集預設會啟用 Cloud Logging。詳情請參閱「設定 GKE 的記錄和監控功能」。

需求條件

  • 網路政策記錄僅適用於使用 GKE Dataplane V2 的叢集。
  • 網路政策記錄功能需要 Google Cloud CLI 303.0.0 以上版本。
  • Windows Server 節點集區不支援網路政策記錄。

定價

  • 網路政策記錄不會產生記錄產生費用。
  • 記錄檔可進一步傳送至 Pub/Sub、Cloud Storage 或 BigQuery。您可能需要支付 Pub/Sub、Cloud Storage 或 BigQuery 費用。詳情請參閱「轉送和儲存空間總覽」的說明。

設定網路政策記錄功能

如要設定網路政策記錄設定,請編輯叢集中的 NetworkLogging 物件。GKE 會在新版 Dataplane V2 叢集中,自動建立名為 defaultNetworkLogging 物件。每個叢集只能有一個 NetworkLogging 物件,且無法重新命名。

您可以分別設定允許連線的記錄檔和拒絕連線的記錄檔。您也可以選擇性地為部分網路政策啟用記錄功能。以下是 NetworkLogging 規格範例,其中指定了記錄所有允許和拒絕連線的設定:

kind: NetworkLogging
apiVersion: networking.gke.io/v1alpha1
metadata:
  name: default
spec:
  cluster:
    allow:
      log: true
      delegate: false
    deny:
      log: true
      delegate: false

使用 kubectl 編輯設定:

kubectl edit networklogging default

NetworkLogging 規格

NetworkLogging 物件規格採用 YAML 格式。下表說明這個格式:

欄位類型說明
cluster.allowstruct 設定是否允許記錄連線。
欄位類型說明
log bool

如果設為 true,系統會記錄叢集中允許的連線;否則不會記錄允許的連線。

記錄訊息中會列出選取 Pod 且有規則與連線相符的網路政策。

delegate bool

如果設為 false,系統會記錄所有允許的連線。如果多項網路政策允許連線,記錄訊息中會列出所有相符的政策。

如果設為 true,只有在網路政策允許連線,且政策含有記錄註解 policy.network.gke.io/enable-logging: "true" 時,系統才會記錄連線。如果多項網路政策允許連線,系統會在記錄訊息中列出所有符合條件的政策,並加上 enable-logging 註解。

如果將 spec.cluster.allow.delegate 設為 true,並將 spec.cluster.allow.log 設為 false,就會發生設定錯誤。

cluster.deny struct 記錄遭拒連線的設定。
欄位類型說明
log bool

如果設為 true,系統會記錄叢集中遭拒的連線;否則不會記錄。

delegate bool

如果設為 false,系統會記錄所有遭拒的連線。

如果 true,只有在連線遭拒的 Pod 位於具有註解 policy.network.gke.io/enable-deny-logging: "true" 的命名空間中時,系統才會記錄遭拒的連線。

如果將 spec.cluster.deny.delegate 設為 true,並將 spec.cluster.deny.log 設為 false,就會發生設定錯誤。

存取網路政策記錄

網路政策記錄檔會自動上傳至 Cloud Logging。您可以透過記錄檔瀏覽器或 Google Cloud CLI 存取記錄。您也可以將記錄檔路由至接收器。

Cloud Logging

  1. 前往 Google Cloud 控制台的「Logs Explorer」頁面。

    前往記錄檔探索工具

  2. 按一下「查詢產生器」

  3. 使用下列查詢找出所有網路政策記錄:

    resource.type="k8s_node"
    resource.labels.location="CLUSTER_LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    logName="projects/PROJECT_NAME/logs/policy-action"
    

    更改下列內容:

    • CLUSTER_LOCATION:叢集的 Compute Engine 位置
    • CLUSTER_NAME:叢集名稱。
    • PROJECT_NAME:您的 Google Cloud 專案名稱。

如要瞭解如何使用記錄檔探索工具,請參閱「使用記錄檔探索工具」。

您也可以使用查詢建構工具建構查詢。如要建立網路政策記錄的查詢,請在「記錄名稱」下拉式清單中選取「policy-action」。如果沒有可用的記錄,下拉式選單就不會顯示「政策動作」

gcloud

找出所有網路政策記錄:

gcloud logging read --project "PROJECT_NAME" 'resource.type="k8s_node"
    resource.labels.location="CLUSTER_LOCATION"
    resource.labels.cluster_name="CLUSTER_NAME"
    logName="projects/PROJECT_NAME/logs/policy-action"'

更改下列內容:

  • PROJECT_NAME:您的 Google Cloud 專案名稱。
  • CLUSTER_LOCATION:叢集的 Compute Engine 位置
  • CLUSTER_NAME:叢集名稱。

您可以新增其他條件來篩選結果。例如:

  • 顯示特定時間範圍內的記錄:

    timestamp>="2020-06-22T06:30:51.128Z"
    timestamp<="2020-06-23T06:30:51.128Z"
    
  • 顯示遭拒連線的記錄:

    jsonPayload.disposition="deny"
    
  • 顯示名為「redis」的部署作業記錄:

    jsonPayload.dest.pod_name=~"redis"
    jsonPayload.dest.pod_namespace="default"
    
  • 顯示叢集外部連線的記錄:

    jsonPayload.dest.instance != ""
    
  • 顯示符合特定網路政策的記錄,在本例中為「allow-frontend-to-db」:

    jsonPayload.policies.name="allow-frontend-to-db"
    jsonPayload.policies.namespace="default"
    

如果您使用標準叢集,也可以在每個叢集節點的 /var/log/network/policy_action.log* 中,找到本機產生的網路政策記錄。當目前的記錄檔達到 10 MB 時,系統會建立新的編號記錄檔。系統最多會儲存五個先前的記錄檔。

網路政策記錄格式

網路政策記錄檔採用 JSON 格式。下表說明這個格式:

欄位類型說明
connectionstruct 連線資訊:
欄位類型說明
src_ipstring連線的來源 IP 位址。
src_portint連線的來源通訊埠。
dest_ipstring連線的目的地 IP 位址。
dest_portint連線的目的地通訊埠。
protocolstring連線通訊協定,可以是 tcpudpicmp
directionstring連線方向,可以是 ingressegress
srcstruct 來源的端點資訊:
欄位類型說明
pod_namestringPod 的名稱 (如果來源是 Pod)。
pod_namespace (deprecated)stringPod 的命名空間 (如果來源是 Pod)。pod_namespace 已淘汰,請改用 namespace
namespacestringPod 的命名空間 (如果來源是 Pod)。
workload_namestring工作負載名稱 (如有來源工作負載)。
workload_kindstring工作負載類型 (如有來源工作負載)。
instancestring來源的 IP 位址 (如果來源不是 Pod)。
deststruct 目的地端點資訊:
欄位類型說明
pod_namestringPod 的名稱 (如果目的地是 Pod)。
pod_namespace (deprecated)string如果目的地是 Pod,則為 Pod 的命名空間。pod_namespace 已淘汰,請改用 namespace
namespacestringPod 的命名空間 (如果目的地是 Pod)。
workload_namestring目的地工作負載的名稱 (如有)。
workload_kindstring目的地工作負載的類型 (如有)。
instancestring來源的 IP 位址 (如果目的地不是 Pod)。
dispositionstring連線的處置方式,可以是 allowdeny
policieslist of structs

從強制執行的 Pod 檢視畫面中,允許連線的相符政策。如果是輸入連線,強制執行的 Pod 就是目的地 Pod。如果是輸出連線,強制執行的 Pod 就是來源 Pod。如果連線符合多項政策,系統就會記錄這些政策。

這個欄位只會納入允許連線的記錄

欄位類型說明
namestring相符的網路政策名稱。
namespacestring相符網路政策的命名空間。
countint用於遭拒查詢的記錄匯總。如果連線獲准,這個值一律為 1。
node_namestring執行 Pod 的節點,該 Pod 產生了這則記錄訊息。
timestampstring嘗試連線的時間。

連線的定義

如果是 TCP 等連線導向通訊協定,系統會為每個允許或拒絕的連線建立記錄。對於 UDP 和 ICMP 等非連線導向的通訊協定,封包會依時間範圍分組。

遭拒連線的政策記錄

遭拒連線的記錄檔不包含 policies 欄位,因為 Kubernetes 網路政策 API 沒有明確的拒絕政策。如果 Pod 受到一或多項網路政策的規範,但沒有任何政策允許連線,系統就會拒絕連線。這表示沒有任何政策單獨導致連線遭到封鎖。

記錄檔匯總 (連線遭拒)

用戶端通常會重試遭拒的連線。為避免記錄過多資訊,系統會使用 count 欄位,將五秒內重複遭到拒絕的連線彙整為單一記錄訊息。

如果後續遭拒連線的 src_ip, dest_ip, dest_port, protocol,direction 與第一個遭拒連線相符,系統就會將這些連線與先前的記錄訊息彙整在一起。請注意,後續連線的 src_port 不一定要相符,因為重試連線可能來自不同通訊埠。匯總記錄訊息會在匯總視窗開頭,包含第一個遭拒連線的 src_prt

記錄範例

以下範例網路政策名為 allow-green,套用至 test-service 後,允許名為 client-green 的 Pod 連線至 test-service。這項政策會隱含拒絕所有其他輸入流量進入 test-service,包括來自 Pod client-red 的流量。

  apiVersion: networking.k8s.io/v1
  kind: NetworkPolicy
  metadata:
    name: allow-green
    namespace: default
    annotations:
      policy.network.gke.io/enable-logging: "true"
  spec:
    podSelector:
      matchLabels:
        app: test-service
    ingress:
    - from:
      - podSelector:
          matchLabels:
            app: client-green
    policyTypes:
    - Ingress

這張圖表顯示 allow-green 政策對兩個連線至 test-service 的影響。allow-green 政策允許從 client-green 建立連線。由於沒有任何政策允許從 client-red 建立連線,因此連線遭到拒絕。

圖片

允許 client-green 建立連線的記錄如下所示:

{
   "connection":{
      "src_ip":"10.84.0.252",
      "dest_ip":"10.84.0.165",
      "src_port":52648,
      "dest_port":8080,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"allow",
   "policies":[
      {
         "name":"allow-green",
         "namespace":"default"
      }
   ],
   "src":{
      "pod_name":"client-green-7b78d7c957-68mv4",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"client-green-7b78d7c957",
      "workload_kind":"ReplicaSet"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"test-service-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":1,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-16T03:10:37.993712906Z"
}

遭拒連線的 client-red 記錄如下所示:

{
   "connection":{
      "src_ip":"10.84.0.180",
      "dest_ip":"10.84.0.165",
      "src_port":39610,
      "dest_port":8080,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"deny",
   "src":{
      "pod_name":"client-red-5689846f5b-b5ccx",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"client-red-5689846f5b",
      "workload_kind":"ReplicaSet"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"test-service-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":3,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-15T22:38:32.189649531Z"
}

請注意,遭拒連線記錄不包含 policies 欄位。如前一節「連線遭拒的政策記錄檔」所述。

遭拒連線記錄包含 count 欄位,可匯總遭拒連線

排解網路政策記錄問題

  1. 檢查 NetworkLogging 物件中的錯誤事件:

    kubectl describe networklogging default
    

    如果記錄設定無效,設定不會生效,且事件部分會回報錯誤:

    Name:         default
    Namespace:
    Labels:       addonmanager.kubernetes.io/mode=EnsureExists
    Annotations:  API Version:  networking.gke.io/v1alpha1
    Kind:         NetworkLogging
    Metadata:
      Creation Timestamp:  2020-06-20T05:54:08Z
      Generation:          8
      Resource Version:    187864
      Self Link:           /apis/networking.gke.io/v1alpha1/networkloggings/default
      UID:                 0f1ddd6e-4193-4295-9172-baa6a52aa6e6
    Spec:
      Cluster:
        Allow:
          Delegate:  true
          Log:       false
        Deny:
          Delegate:  false
          Log:       false
    Events:
      Type     Reason                 Age                From                                                               Message
      ----     ------                 ----               ----                                                               -------
      Warning  InvalidNetworkLogging  16s (x3 over 11h)  network-logging-controller, gke-anthos-default-pool-cee49209-0t09  cluster allow log action is invalid: delegate cannot be true when log is false
      Warning  InvalidNetworkLogging  16s (x3 over 11h)  network-logging-controller, gke-anthos-default-pool-cee49209-80fx  cluster allow log action is invalid: delegate cannot be true when log is false
    
  2. 為限制記錄檔使用的 CPU 資源,節點每秒最多可記錄 500 個連線,超過這個數量就會開始捨棄記錄檔。節點上的網路政策仍會強制執行。如要查看是否有遭捨棄的政策記錄,請檢查是否有任何錯誤計數器遞增:

    kubectl exec ANETD_POD_NAME -n kube-system -- curl -s http://localhost:9990/metrics |grep policy_logging
    

    ANETD_POD_NAME 替換為 anetd Pod 的名稱。檢查每個節點。anetd 是 Dataplane V2 的網路控制器。

如果 Pod 採用預設拒絕政策,記錄檔會顯示沒有名稱

有效性、完備性和啟動探測需要 Pod 接受探測從 kubelet 建立的 Ingress 連線。為確保這些探針正常運作,無論套用至 Pod 的網路政策為何,GKE 都會自動允許探針流量流向為 Pod 設定的所選 Pod。你無法變更這項行為。

探測連線的記錄類似於下列內容:

{
   "connection":{
      "src_ip":"10.88.1.1",
      "dest_ip":"10.88.1.4",
      "src_port":35848,
      "dest_port":15021,
      "protocol":"tcp",
      "direction":"ingress"
   },
   "disposition":"allow",
   "src":{
      "instance":"10.88.1.1"
   },
   "dest":{
      "pod_name":"testpod-745c798fc9-sfd9h",
      "pod_namespace":"default",
      "namespace":"default",
      "workload_name":"testpod-745c798fc9",
      "workload_kind":"ReplicaSet"
   },
   "count":1,
   "policies": [
     {
       "name":""
     }
    ],
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2021-04-01T12:42:32.1898720941Z"
}

記錄具有下列特性:

  • 由於沒有相關聯的網路政策允許連線,因此 policies.name 的值為空白。
  • connection.src_ip 的值不對應任何 Pod 或節點。

後續步驟