Logging von Netzwerkrichtlinien verwenden


Auf dieser Seite wird erläutert, wie Sie Netzwerkrichtlinien-Logging für Google Kubernetes Engine (GKE) verwenden. Kubernetes-Netzwerkrichtlinien geben den Netzwerktraffic an, den Pods senden und empfangen dürfen. Mit dem Logging von Netzwerkrichtlinien können Sie aufzeichnen, wann eine Verbindung durch eine Netzwerkrichtlinie zugelassen oder abgelehnt wird. Mit dem Logging von Netzwerkrichtlinien können Sie Probleme mit Netzwerkrichtlinien beheben.

Überblick

Mithilfe von Netzwerkrichtlinien-Logging können Sie:

  • Prüfen, ob Ihre Netzwerkrichtlinien wie erwartet funktionieren.
  • Ermitteln, welche Pods in Ihrem Cluster mit dem Internet kommunizieren.
  • Sich damit vertraut machen, welche Namespaces miteinander kommunizieren.
  • Einen Denial-of-Service-Angriff erkennen

Logs von Netzwerkrichtlinien werden in Cloud Logging hochgeladen, um das Speichern, Suchen, die Analyse und Benachrichtigungen zu ermöglichen, wenn Cloud Logging aktiviert ist. Cloud Logging ist in neuen Clustern standardmäßig aktiviert. Weitere Informationen finden Sie unter Logging und Monitoring für GKE konfigurieren.

Voraussetzungen

  • Das Logging von Netzwerkrichtlinien ist nur bei Clustern verfügbar, GKE Dataplane V2 verwenden.
  • Für das Logging von Netzwerkrichtlinien ist die Google Cloud CLI-Version 303.0.0 oder höher erforderlich.
  • Das Logging von Netzwerkrichtlinien wird für Windows Server-Knotenpools nicht unterstützt.

Preise

  • Es fallen für das Logging von Netzwerkrichtlinien keine Gebühren an.
  • Logs können zu Pub/Sub, Cloud Storage oder BigQuery weitergeleitet werden. Für Pub/Sub, Cloud Storage und BigQuery können Gebühren anfallen. Weitere Informationen finden Sie unter Routing und Speicher.

Logging von Netzwerkrichtlinien konfigurieren

Sie konfigurieren die Einstellungen für das Netzwerkrichtlinien-Logging, indem Sie das Objekt NetworkLogging in Ihrem Cluster bearbeiten. GKE erstellt in neuen Dataplane V2-Clustern automatisch ein NetworkLogging-Objekt namens default. Pro Cluster ist nur ein NetworkLogging-Objekt zulässig, das nicht umbenannt werden kann.

Sie können das Logging erlaubter Verbindungen und das Logging abgelehnter Verbindungen separat konfigurieren. Sie können das Logging auch für einige Netzwerkrichtlinien selektiv aktivieren. Das folgende Beispiel zeigt die Spezifikation NetworkLogging mit Einstellungen, mit denen alle zugelassenen und abgelehnten Verbindungen protokolliert werden:

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

Verwenden Sie kubectl, um Ihre Konfiguration zu bearbeiten:

kubectl edit networklogging default

NetworkLogging-Spezifikation

Die Spezifikation des NetworkLogging-Objekts hat das YAML-Format. Dieses Format wird in der folgenden Tabelle beschrieben:

FeldTypBeschreibung
cluster.allowstruct Einstellungen für erlaubte Logging-Verbindungen.
FeldTypBeschreibung
log bool

Wenn true festgelegt ist, werden zulässige Verbindungen im Cluster protokolliert. Andernfalls werden zugelassene Verbindungen nicht protokolliert.

Im Logeintrag werden Netzwerkrichtlinien aufgeführt, die den Pod auswählen und eine mit der Verbindung übereinstimmende Regel haben.

delegate bool

Bei false werden alle zugelassenen Verbindungen protokolliert. Wenn mehrere Netzwerkrichtlinien eine Verbindung zulassen, werden alle übereinstimmenden Richtlinien im Logeintrag aufgeführt.

Bei true werden zulässige Verbindungen nur dann protokolliert, wenn sie von einer Netzwerkrichtlinie mit der Logging-Annotation policy.network.gke.io/enable-logging: "true" zugelassen werden. Wenn mehrere Netzwerkrichtlinien eine Verbindung zulassen, werden alle übereinstimmenden Richtlinien mit der Annotation enable-logging im Logeintrag aufgeführt.

Ein Konfigurationsfehler tritt auf, wenn Sie spec.cluster.allow.delegate auf true und spec.cluster.allow.log auf false setzen.

cluster.deny struct Einstellungen für das Logging abgelehnter Verbindungen
FeldTypBeschreibung
log bool

Wenn true festgelegt ist, werden abgelehnte Verbindungen im Cluster protokolliert. Andernfalls werden abgelehnte Verbindungen nicht protokolliert.

delegate bool

Bei false werden alle abgelehnten Verbindungen protokolliert.

Bei true werden abgelehnte Verbindungen nur dann protokolliert, wenn der Pod, in dem die Verbindung abgelehnt wurde, in einem Namespace mit der Annotation policy.network.gke.io/enable-deny-logging: "true" enthalten ist.

Ein Konfigurationsfehler tritt auf, wenn Sie spec.cluster.deny.delegate auf true und spec.cluster.deny.log auf false setzen.

Auf Logs von Netzwerkrichtlinien zugreifen

Logs von Netzwerkrichtlinien werden automatisch in Cloud Logging hochgeladen. Sie können auf Logs über den Log-Explorer oder mit der Google Cloud CLI zugreifen. Sie können auch Logs an eine Senke weiterleiten.

Cloud Logging

  1. Rufen Sie in der Google Cloud Console den Log-Explorer auf.

    Zum Log-Explorer

  2. Klicken Sie auf Query Builder.

  3. Verwenden Sie die folgende Abfrage, um alle Logs der Netzwerkrichtlinien zu finden:

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

    Ersetzen Sie Folgendes:

    • CLUSTER_LOCATION ist der Compute Engine-Standort des Clusters.
    • CLUSTER_NAME ist der Name Ihres Clusters.
    • PROJECT_NAME ist der Name Ihres Google Cloud-Projekts.

Informationen zur Verwendung des Log-Explorers finden Sie unter Log-Explorer verwenden.

Sie können auch eine Abfrage mit dem Query Builder erstellen. Zum Erstellen einer Abfrage für Netzwerkrichtlinienlogs wählen Sie in der Drop-down-Liste Logname den Eintrag policy-action aus. Wenn keine Logs verfügbar sind, wird policy-action nicht in der Drop-down-Liste angezeigt.

gcloud

Alle Datensätze der Netzwerkrichtlinien suchen:

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"'

Ersetzen Sie Folgendes:

  • PROJECT_NAME ist der Name Ihres Google Cloud-Projekts.
  • CLUSTER_LOCATION ist der Compute Engine-Standort des Clusters.
  • CLUSTER_NAME ist der Name Ihres Clusters.

Sie können weitere Bedingungen hinzufügen, um die Ergebnisse zu filtern. Beispiel:

  • So rufen Sie Logs aus einem bestimmten Zeitraum auf:

    timestamp>="2020-06-22T06:30:51.128Z"
    timestamp<="2020-06-23T06:30:51.128Z"
    
  • So rufen Sie Logs für abgelehnte Verbindungen auf:

    jsonPayload.disposition="deny"
    
  • So rufen Sie Logs für ein Deployment mit dem Namen "redis" auf:

    jsonPayload.dest.pod_name=~"redis"
    jsonPayload.dest.pod_namespace="default"
    
  • So rufen Sie Logs für Cluster-externe Verbindungen auf:

    jsonPayload.dest.instance != ""
    
  • So rufen Sie Logs auf, die mit einer bestimmten Netzwerkrichtlinie übereinstimmen, in diesem Fall "allow-frontend-to-db":

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

Wenn Sie einen Standardcluster verwenden, finden Sie die Logs der Netzwerkrichtlinien, die auf jedem Clusterknoten lokal erstellt werden, auch unter /var/log/network/policy_action.log*. Wenn die aktuelle Logdatei 10 MB erreicht, wird eine neue nummerierte Logdatei erstellt. Es werden bis zu fünf vorherige Logdateien gespeichert.

Format für Logs von Netzwerkrichtlinien

Einträge für Logs von Netzwerkrichtlinien liegen im JSON-Format vor. Dieses Format wird in der folgenden Tabelle beschrieben:

FeldTypBeschreibung
connectionstruct Verbindungsinformationen:
FeldTypBeschreibung
src_ipstringQuell-IP-Adresse der Verbindung.
src_portintQuellport der Verbindung.
dest_ipstringZiel-IP-Adresse der Verbindung.
dest_portintZielport der Verbindung.
protocolstringProtokoll der Verbindung, entweder tcp, udp oder icmp.
directionstringRichtung der Verbindung, entweder ingress oder egress
srcstruct Endpunktinformationen der Quelle:
FeldTypBeschreibung
pod_namestringName des Pods, wenn die Quelle ein Pod ist.
pod_namespace (deprecated)stringNamespace des Pods, wenn die Quelle ein Pod ist. pod_namespace wurde verworfen (verwenden Sie stattdessen namespace).
namespacestringNamespace des Pods, wenn die Quelle ein Pod ist.
workload_namestringName der Arbeitslast, wenn die Zielarbeitslast verfügbar ist.
workload_kindstringArt der Arbeitslast, wenn die Quellarbeitslast verfügbar ist.
instancestringIP-Adresse der Quelle, wenn die Quelle kein Pod ist.
deststruct Endpunktinformationen des Ziels:
FeldTypBeschreibung
pod_namestringName des Pods, wenn das Ziel ein Pod ist
pod_namespace (deprecated)stringNamespace des Pods, wenn das Ziel ein Pod ist pod_namespace wurde verworfen (verwenden Sie stattdessen namespace).
namespacestringNamespace des Pods, wenn das Ziel ein Pod ist
workload_namestringName der Arbeitslast, wenn die Zielarbeitslast verfügbar ist.
workload_kindstringArt der Arbeitslast, wenn die Zielarbeitslast verfügbar ist.
instancestringIP-Adresse der Quelle, wenn das Ziel kein Pod ist.
dispositionstringRichtung der Verbindung, entweder allow oder deny.
policieslist of structs

Übereinstimmende Richtlinien für die erlaubten Verbindungen aus der Sicht des erzwungenen Pods. Bei Ingress-Verbindungen ist der erzwungene Pod der Ziel-Pod. Bei ausgehenden Verbindungen ist der erzwungene Pod der Quell-Pod. Es werden mehrere Richtlinien protokolliert, wenn eine Verbindung mit allen übereinstimmt.

Dieses Feld ist nur in Logs von zulässigen Verbindungen enthalten.

FeldTypBeschreibung
namestringName der passenden Netzwerkrichtlinie.
namespacestringNamespace der passenden Netzwerkrichtlinie.
countintWird für die Logaggregation von abgelehnten Abfragen verwendet. Bei erlaubten Verbindungen ist der Wert immer 1.
node_namestringDer Knoten, auf dem der Pod ausgeführt wird, der diesen Logeintrag generiert hat.
timestampstringZeitpunkt des Verbindungsversuchs

Definition der Verbindung

Bei verbindungsorientierten Protokollen wie TCP wird ein Log für jede zugelassene oder abgelehnte Verbindung erstellt. Bei nicht verbindungsorientierten Protokollen wie UDP und ICMP werden Pakete in zeitfensterbasierten Verbindungen gruppiert.

Richtlinienlogs für abgelehnte Verbindungen

In den Logdatensätzen für abgelehnte Verbindungen ist das Feld policies nicht enthalten, da die Kubernetes Network Policy API keine expliziten Ablehnungsrichtlinien hat. Eine Verbindung wird verweigert, wenn ein Pod von einer oder mehreren Netzwerkrichtlinien abgedeckt wird, aber keine der Richtlinien die Verbindung zulässt. Dies bedeutet, dass für eine blockierte Verbindung keine Richtlinie allein verantwortlich ist.

Logaggregation für abgelehnte Verbindungen

Es ist üblich, dass ein Client versucht, eine zuvor abgelehnte Verbindung noch einmal herzustellen. Damit übermäßiges Logging vermieden wird, werden wiederholte abgelehnte Verbindungen in einem 5-Sekunden-Fenster mit dem Feld count zu einer einzigen Lognachricht zusammengefasst.

Nachfolgende abgelehnte Verbindungen werden mit einer vorherigen Lognachricht aggregiert, wenn src_ip, dest_ip, dest_port, protocol, und direction der Verbindung der ersten abgelehnten Verbindung entsprechen. Der src_port der nachfolgenden Verbindungen muss nicht übereinstimmen, da wiederholte Verbindungen von einem anderen Port stammen können. Der aggregierte Logeintrag enthält den src_prt der ersten abgelehnten Verbindung zu Beginn des Aggregationsfensters.

Beispiel für Logeinträge

Die folgende beispielhafte Netzwerkrichtlinie namens allow-green, die auf test-service angewendet wird, ermöglicht Verbindungen zu test-service von einem Pod mit dem Namen client-green. Daher lehnt diese Richtlinie den gesamten eingehenden Traffic zu test-service ab, auch vom 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

Dieses Diagramm zeigt die Auswirkung der Richtlinie allow-green auf zwei Verbindungen zu test-service. Die Richtlinie allow-green lässt die Verbindung von client-green zu. Da keine Richtlinie die Verbindung von client-red zulässt, wird die Verbindung abgelehnt.

Image

Das Log für die erlaubte Verbindung von client-green sieht so aus:

{
   "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"
}

Das Log für die abgelehnte Verbindung von client-red sieht so aus:

{
   "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"
}

Beachten Sie, dass das Log für die abgelehnte Verbindung nicht das Feld policies enthält. Dies wird im vorherigen Abschnitt Richtlinienlogs für abgelehnte Verbindungen beschrieben.

Das Log für die abgelehnte Verbindung enthält das Feld count für aggregierte abgelehnte Verbindungen.

Probleme mit Logs von Netzwerkrichtlinien beheben

  1. Suchen Sie im Objekt NetworkLogging nach Fehlerereignissen:

    kubectl describe networklogging default
    

    Wenn die Logging-Konfiguration ungültig ist, wird sie nicht wirksam und im Bereich der Ereignisse wird ein Fehler gemeldet:

    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. Zur Begrenzung der für Logging genutzten CPU-Auslastung kann ein Knoten bis zu 500 Verbindungen pro Sekunde protokollieren, bevor er Logs löscht. Die Netzwerkrichtlinien für den Knoten werden weiterhin erzwungen. Sie können sehen, ob Richtlinienlogs verworfen wurden. Prüfen Sie dazu, ob mehr Fehler im Fehlerzähler angezeigt werden.

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

    Ersetzen Sie ANETD_POD_NAME durch den Namen eines anetd-Pods. Prüfen Sie die einzelnen Knoten. anetd ist der Netzwerkcontroller für Dataplane V2.

Logs ohne Namen werden für Pods mit standardmäßigen Ablehnungsrichtlinien angezeigt

Aktivitäts-, Bereitschafts- und Startprüfungen erfordern, dass der Pod die von den Prüfungen hergestellten Ingress-Verbindungen von kubelet akzeptiert. Damit diese Prüfungen ordnungsgemäß funktionieren, lässt GKE unabhängig von den auf den Pod angewendeten Netzwerkrichtlinien automatisch Prüfungs-Traffic an den ausgewählten Pod zu. Dieses Verhalten kann nicht geändert werden.

Logs für Prüfungsverbindungen sehen in etwa so aus:

{
   "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"
}

Das Log hat folgende Merkmale:

  • Der Wert von policies.name ist leer, da keine Netzwerkrichtlinie zugeordnet ist, die die Verbindung zulässt.
  • Der Wert von connection.src_ip entspricht keinem Pod oder Knoten.

Nächste Schritte