本頁說明如何使用 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 節點集區不支援網路政策記錄。
定價
- 網路政策記錄不會產生記錄產生費用。
- 如果您將記錄檔儲存在 Cloud Logging 中,則需支付標準 Cloud Logging 費用。
- 記錄檔可進一步傳送至 Pub/Sub、Cloud Storage 或 BigQuery。您可能需要支付 Pub/Sub、Cloud Storage 或 BigQuery 費用。詳情請參閱「轉送和儲存空間總覽」的說明。
設定網路政策記錄功能
如要設定網路政策記錄設定,請編輯叢集中的 NetworkLogging
物件。GKE 會在新版 Dataplane V2 叢集中,自動建立名為 default
的 NetworkLogging
物件。每個叢集只能有一個 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.allow | struct |
設定是否允許記錄連線。
|
|||||||||
cluster.deny |
struct |
記錄遭拒連線的設定。
|
存取網路政策記錄
網路政策記錄檔會自動上傳至 Cloud Logging。您可以透過記錄檔瀏覽器或 Google Cloud CLI 存取記錄。您也可以將記錄檔路由至接收器。
Cloud Logging
前往 Google Cloud 控制台的「Logs Explorer」頁面。
按一下「查詢產生器」。
使用下列查詢找出所有網路政策記錄:
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 格式。下表說明這個格式:
欄位 | 類型 | 說明 | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
connection | struct |
連線資訊:
|
|||||||||||||||||||||
src | struct |
來源的端點資訊:
|
|||||||||||||||||||||
dest | struct |
目的地端點資訊:
|
|||||||||||||||||||||
disposition | string | 連線的處置方式,可以是 allow 或 deny 。 | |||||||||||||||||||||
policies | list of structs |
從強制執行的 Pod 檢視畫面中,允許連線的相符政策。如果是輸入連線,強制執行的 Pod 就是目的地 Pod。如果是輸出連線,強制執行的 Pod 就是來源 Pod。如果連線符合多項政策,系統就會記錄這些政策。 這個欄位只會納入允許連線的記錄。
|
|||||||||||||||||||||
count | int | 用於遭拒查詢的記錄匯總。如果連線獲准,這個值一律為 1。 | |||||||||||||||||||||
node_name | string | 執行 Pod 的節點,該 Pod 產生了這則記錄訊息。 | |||||||||||||||||||||
timestamp | string | 嘗試連線的時間。 |
連線的定義
如果是 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
欄位,可匯總遭拒連線。
排解網路政策記錄問題
檢查
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
為限制記錄檔使用的 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 或節點。