Usa el registro de políticas de red


En esta página, se explica cómo usar el registro de políticas de red para Google Kubernetes Engine (GKE).

Descripción general

Las políticas de red especifican el tráfico de red que los Pods pueden enviar y recibir. El registro de políticas de red te permite registrar cuando una política de red permite o rechaza una conexión. Mediante el registro de políticas de red, puedes hacer lo siguiente:

  • Verificar que las políticas de red funcionen según lo previsto
  • Conocer qué Pods de tu clúster se comunican con Internet
  • Comprender qué espacios de nombres se comunican entre sí
  • Reconocer un ataque de denegación del servicio

Los registros de políticas de red se suben a Cloud Logging para el almacenamiento, la búsqueda, el análisis y las alertas si Cloud Logging está habilitado. En los clústeres nuevos, Cloud Logging está habilitado de forma predeterminada. Consulta Instala operaciones de Cloud para la asistencia de GKE a fin de obtener más información.

Requisitos

  • El registro de políticas de red solo está disponible para clústeres que usan Dataplane V2.
  • El registro de políticas de red requiere el SDK de Cloud 303.0.0 o superior.
  • El registro de políticas de red no es compatible con los grupos de nodos de Windows Server.

Precios

  • La generación de registros no genera cargos para el registro de políticas de red.
  • Si almacenas tus registros en Cloud Logging, se aplican los cargos estándar de Cloud Logging.
  • Los registros se pueden exportar luego a Pub/Sub, Cloud Storage o BigQuery. Es posible que se apliquen cargos de Pub/Sub, Cloud Storage o BigQuery. Para obtener más información sobre la exportación de registros, consulta Descripción general de la exportación de registros.

Configura el registro de políticas de red

Para establecer la configuración del registro de las políticas de red, edita el objeto NetworkLogging en el clúster. De forma automática, GKE crea un objeto NetworkLogging llamado default en los clústeres nuevos de Dataplane V2. Solo puede haber un objeto NetworkLogging por clúster y no se puede cambiar de nombre.

Puedes configurar el registro de las conexiones permitidas y de las conexiones rechazadas por separado. También puedes habilitar el registro de forma selectiva para algunas políticas de red. A continuación, se muestra un ejemplo de la especificación de NetworkLogging, con la configuración especificada para registrar todas las conexiones permitidas y rechazadas:

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

Usa kubectl para editar la configuración:

kubectl edit networklogging default

Especificación de NetworkLogging

La especificación del objeto NetworkLogging está en formato YAML. Este formato se describe en la siguiente tabla:

CampoTipoDescripción
cluster.allowstruct Opciones de configuración para registrar conexiones permitidas.
CampoTipoDescripción
log bool

Si se configura como true, se registran las conexiones permitidas en el clúster. De lo contrario, las conexiones permitidas no se registran.

Las políticas de red que seleccionan el Pod y tienen una regla que coincide con la conexión se enumeran en el mensaje de registro.

delegate bool

Si es false, se registran todas las conexiones permitidas. Si varias políticas de red permiten una conexión, se enumeran todas las políticas coincidentes en el mensaje de registro.

Si es true, las conexiones permitidas solo se registran si una política de red con la anotación de registro policy.network.gke.io/enable-logging: "true" lo permite. Si varias políticas de red permiten una conexión, se enumeran todas las políticas coincidentes con la anotación enable-logging en el mensaje de registro.

Se produce un error de configuración si estableces spec.cluster.allow.delegate en true y spec.cluster.allow.log en false.

cluster.deny struct Opciones de configuración para registrar conexiones rechazadas.
CampoTipoDescripción
log bool

Si se configura como true, se registran las conexiones rechazadas en el clúster. De lo contrario, las conexiones rechazadas no se registran.

delegate bool

Si es false, se registran todas las conexiones rechazadas.

Si es true, las conexiones rechazadas solo se registran si el Pod en el que se rechazó la conexión está en un espacio de nombres con la anotación policy.network.gke.io/enable-deny-logging: "true".

Se produce un error de configuración si estableces spec.cluster.deny.delegate en true y spec.cluster.deny.log en false.

Accede a los registros

Los registros de las políticas de red generados en cada nodo del clúster están disponibles de forma local en /var/log/network/policy_action.log*. Se crea un archivo de registro numerado nuevo cuando el archivo de registro actual alcanza los 10 MB. Se almacenan hasta cinco archivos de registro anteriores.

Los registros de las políticas de red se suben de forma automática a Cloud Logging. Puedes acceder a los registros mediante el Explorador de registros o la herramienta de línea de comandos de gcloud. También puedes exportar registros de Cloud Logging al receptor que elijas.

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

Reemplaza los siguientes elementos:

  • PROJECT_NAME: Es el nombre de tu proyecto de Google Cloud.
  • CLUSTER_LOCATION: Es la zona en la que se encuentra el clúster.
  • CLUSTER_NAME: Es el nombre del clúster.

Cloud Logging

  1. Ve a la página Explorador de registros en Cloud Console.

    Ir al Explorador de registros

  2. Haz clic en Compilador de consultas.

  3. Usa la siguiente consulta para encontrar todos los registros de las políticas de red:

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

    Reemplaza lo siguiente:

    • CLUSTER_LOCATION: Es la zona en la que se encuentra el clúster.
    • CLUSTER_NAME: Es el nombre del clúster.
    • PROJECT_NAME: Es el nombre de tu proyecto de Google Cloud.

Consulta Usa el Explorador de registros para obtener información sobre cómo usar el Explorador de registros.

También puedes compilar una consulta con el Compilador de consultas. A fin de crear una consulta para los registros de políticas de red, selecciona policy-action en la lista desplegable Nombre del registro. Si no hay registros disponibles, policy-action no aparece en la lista desplegable.

Puedes agregar más condiciones para filtrar los resultados. Por ejemplo:

  • Mostrar registros en un período determinado:

    timestamp>="2020-06-22T06:30:51.128Z"
    timestamp<="2020-06-23T06:30:51.128Z"
    
  • Mostrar los registros de las conexiones rechazadas:

    jsonPayload.disposition="deny"
    
  • Mostrar los registros de una implementación llamada “redis”:

    jsonPayload.dest.pod_name=~"redis"
    jsonPayload.dest.pod_namespace="default"
    
  • Mostrar los registros de las conexiones externas del clúster:

    jsonPayload.dest.instance != ""
    
  • Mostrar los registros que coinciden con una política de red determinada, en este caso “allow-frontend-to-db”:

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

Formato de registro

Los registros de las políticas de red están en formato JSON. Este formato se describe en la siguiente tabla:

CampoTipoDescripción
connectionstruct Información de la conexión:
CampoTipoDescripción
src_ipstringDirección IP de origen de la conexión.
src_portintPuerto de origen de la conexión.
dest_ipstringDirección IP de destino de la conexión.
dest_portintPuerto de destino de la conexión.
protocolstringProtocolo de la conexión, que puede ser tcp, udp o icmp,
directionstringDirección de la conexión, que puede ser ingress o egress.
srcstruct Información del extremo del origen:
CampoTipoDescripción
pod_namestringNombre del Pod, si el origen es un Pod.
pod_namespacestringEspacio de nombres del Pod, si el origen es un Pod.
instancestringDirección IP del origen, si el origen no es un Pod.
deststruct Información del extremo del destino:
CampoTipoDescripción
pod_namestringNombre del Pod, si el destino es un Pod.
pod_namespacestringEspacio de nombres del Pod, si el destino es un Pod.
instancestringDirección IP del origen, si el destino no es un Pod.
dispositionstringDisposición de la conexión, que puede ser allow o deny.
policieslist of structs

Políticas coincidentes para las conexiones permitidas desde la vista del Pod aplicado. En la conexión de entrada, el Pod aplicado es el Pod de destino. En la conexión de salida, el Pod aplicado es el Pod de origen. Se registran varias políticas si una conexión coincide con todas ellas.

Este campo solo se incluye en los registros de las conexiones permitidas.

CampoTipoDescripción
namestringNombre de la política de red coincidente.
namespacestringEspacio de nombres de la política de red coincidente.
countintSe usa para la agregación de registros de las consultas rechazadas. El valor es siempre 1 para la conexión permitida.
node_namestringEl nodo que ejecuta el Pod que generó este mensaje de registro.
timestampstringCuándo ocurrió el intento de conexión.

Definición de conexión

En el caso de los protocolos orientados a la conexión, como TCP, se crea un registro por cada conexión permitida o rechazada. Para los protocolos como UDP y ICMP que no están orientados a la conexión, los paquetes se agrupan en conexiones basadas en ventanas de tiempo.

Registros de políticas para conexiones rechazadas

Los registros de conexión de las conexiones rechazadas no incluyen el campo policies, ya que la API de políticas de red de Kubernetes no tiene políticas de rechazo explícitas. Se rechaza una conexión si un Pod está cubierto por una o más políticas de red, pero ninguna de las políticas permite la conexión. Esto significa que ninguna política es responsable de manera individual de una conexión bloqueada.

Agregación de registros para las conexiones rechazadas

Es común que un cliente vuelva a intentar una conexión que se rechazó. Para evitar el registro excesivo, las conexiones rechazadas repetidas en una ventana de cinco segundos se agregan en un solo mensaje de registro mediante el campo count.

Las conexiones rechazadas posteriores se agregan con un mensaje de registro anterior si los src_ip, dest_ip, dest_port, protocol, y la direction de la conexión coinciden con la primera conexión rechazada. Ten en cuenta que el src_port de las conexiones posteriores no tiene que coincidir, ya que las conexiones que se reintentaron pueden provenir de un puerto diferente. El mensaje de registro agregado incluye el src_prt de la primera conexión rechazada al comienzo de la ventana de agregación.

Registros de ejemplo

La siguiente política de red de ejemplo llamada allow-green aplicada a test-service permite conexiones a test-service desde un Pod llamado client-green. De manera implícita, esta política rechaza todo el tráfico de entrada a test-service, incluido desde el client-red del Pod.

  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

En este diagrama, se muestra el efecto de la política allow-green en dos conexiones a test-service. La política allow-green permite la conexión desde client-green. Debido a que ninguna política permite la conexión desde client-red, se rechaza la conexión.

El registro para la conexión permitida desde client-green se ve de la siguiente manera:

{
   "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"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default"
   },
   "count":1,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-16T03:10:37.993712906Z"
}

El registro para la conexión rechazada desde client-red se ve de la siguiente manera:

{
   "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"
   },
   "dest":{
      "pod_name":"test-service-745c798fc9-sfd9h",
      "pod_namespace":"default"
   },
   "count":3,
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2020-06-15T22:38:32.189649531Z"
}

Ten en cuenta que no se incluye el campo policies en el registro de la conexión rechazada. Esto se describe en la sección anterior, Registros de políticas para conexiones rechazadas.

El registro de la conexión rechazada incluye un campo count para agregar conexiones rechazadas.

Soluciona problemas

  1. Verifica los eventos de errores en el objeto NetworkLogging:

    kubectl describe networklogging default
    

    Si la configuración de registros no es válida, no se aplicará y se informará un error en la sección de eventos:

    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. Para limitar el uso de CPU empleado a la hora de registrar el nodo, un nodo puede registrar hasta 500 conexiones por segundo antes de comenzar a descartar registros. Las políticas de red en el nodo se siguen aplicando. Para ver si hay registros de políticas descartados, verifica si los contadores de errores aumentan:

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

    Reemplaza ANETD_XYZ por el nombre de un Pod anetd. Verifica cada nodo. El anetd es el controlador de herramientas de redes para Dataplane V2.

Registros sin nombre aparecen para los pods con políticas de denegación predeterminadas

Los sondeos de capacidad de funcionamiento, preparación e inicio requieren que el Pod acepte las conexiones de Ingress realizadas por los sondeos de kubelet. Para garantizar que estos sondeos funcionen de forma correcta, GKE permite el tráfico del sondeo al Pod seleccionado de forma automática como está configurado para el Pod, sin importar las políticas de red aplicadas al Pod. No puedes cambiar este comportamiento.

Los registros de las conexiones de sondeo son similares a los siguientes:

{
   "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"
   },
   "count":1,
   "policies": [
     {
       "name":""
     }
    ],
   "node_name":"gke-demo-default-pool-5dad52ed-k0h1",
   "timestamp":"2021-04-01T12:42:32.1898720941Z"
}

El registro tiene las siguientes características:

  • El valor de policies.name está vacío porque no hay ninguna política de red asociada para permitir la conexión.
  • El valor de connection.src_ip no corresponde a ningún Pod ni nodo.

¿Qué sigue?