このページでは、Google Kubernetes Engine(GKE)でネットワーク ポリシー ロギングを使用する方法について説明します。Kubernetes ネットワーク ポリシーでは、Pod で送受信できるネットワーク トラフィックを指定します。ネットワーク ポリシー ロギングを使用すると、ネットワーク ポリシーによって接続が許可または拒否された時間を記録できます。ネットワーク ポリシー ロギングは、ネットワーク ポリシーに関する問題のトラブルシューティングに役立つ場合があります。
概要
ネットワーク ポリシー ロギングを使用すると、次のことができます。
- ネットワーク ポリシーが予期したとおり機能していることを確認する。
- クラスタ内のどの Pod がインターネットと通信しているかを把握する。
- 互いに通信している Namespace を把握する。
- サービス拒否攻撃を認識する。
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 オブジェクトは 1 つのクラスタに 1 つだけ存在し、その名前は変更できません。
許可された接続と拒否された接続のロギングを別々に構成できます。一部のネットワーク ポリシーでは、ロギングを選択的に有効にすることもできます。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 コンソールの [ログ エクスプローラ] ページに移動します。
[クエリビルダー] をクリックします。
次のクエリを使用して、すべてのネットワーク ポリシーのログレコードを検索します。
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] を選択します。使用可能なログがない場合、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"
Standard クラスタを使用する場合、各クラスタノードで生成されたネットワーク ポリシー ログは、/var/log/network/policy_action.log*
でローカルで確認することもできます。現行のログファイルが 10 MB になると、新しい番号の付いたログファイルが作成されます。ログファイルは最大 5 世代まで保存されます。
ネットワーク ポリシー ログの形式
ネットワーク ポリシー ログは 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 が実行されているノード。 | |||||||||||||||||||||
timestamp | string | 接続の試行日時。 |
接続の定義
TCP などのコネクション型のプロトコルでは、許可された接続または拒否された接続ごとにログが作成されます。UDP や ICMP などのコネクション型以外のプロトコルの場合、パケットは時間枠に基づく接続に分類されます。
拒否された接続のポリシーログ
Kubernetes ネットワーク ポリシー API には明示的な拒否ポリシーがないため、拒否された接続のログレコードに policies
フィールドは含まれません。Pod が 1 つ以上のネットワーク ポリシーで処理され、その接続を許可するポリシーがない場合、接続は拒否されます。これは、接続がブロックされた根拠となるポリシーが存在しないことを意味します。
拒否された接続のログ集計
一般に、クライアントは拒否された接続を再試行します。過剰なロギングを防ぐため、5 秒以内に連続して拒否された接続は、count
フィールドを使用して 1 つのログメッセージに集約されます。
接続の src_ip, dest_ip, dest_port, protocol,
と direction
が最初に拒否された接続と一致すると、後続の接続は前のログメッセージに集計されます。接続の再試行が別のポートから行われることもあるため、後続の接続の src_port
を照合する必要はありません。集計されたログメッセージには、集計期間中に最初に拒否された接続の src_prt
が含まれます。
ログレコードの例
次のネットワーク ポリシーの例では、ポリシー名が allow-green
で、client-green
という Pod から test-service
への接続を test-service
で許可しています。このポリシーでは、Pod client-red
から test-service
への上り(内向き)トラフィックをすべて暗黙的に拒否されます。
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
との 2 つの接続に与える影響を示しています。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 使用率を制限するため、ログの削除を開始するまでに 1 ノードで 1 秒あたり最大 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 に名前のないログが存在する
liveness、readiness、startup プローブを使用するには、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 やノードにも一致しません。
次のステップ
- Cloud Logging でログを表示して分析する方法を確認する。
- ネットワーク ポリシーでトラフィックを制限する一般的な方法を実装する。