Configurar varias interfaces de red para pods

En este documento se describe cómo configurar Google Distributed Cloud para proporcionar varias interfaces de red (multi-NIC) a tus pods. La función de varias NICs para pods puede ayudar a separar el tráfico del plano de control del tráfico del plano de datos, lo que crea un aislamiento entre los planos. Las interfaces de red adicionales también habilitan la función de multidifusión para tus pods. Se admite el uso de varias NICs en pods en clústeres de usuarios, clústeres híbridos y clústeres independientes. La función de varias NICs para pods está disponible en los clústeres de administrador con la versión 1.34 y posteriores.

Esta página está dirigida a especialistas en redes que instalan, configuran y ofrecen asistencia para equipos de redes. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido de Google Cloud , consulta Roles y tareas de usuario habituales de GKE.

El aislamiento del plano de red es importante para los sistemas que usan virtualizaciones de funciones de red (NFVs), como las redes definidas por software en una red de área amplia (SD-WAN), un agente de seguridad de acceso a la nube (CASB) y cortafuegos de nueva generación (NG-FWs). Estos tipos de NFVs dependen del acceso a varias interfaces para mantener separados los planos de gestión y de datos, mientras se ejecutan como contenedores.

La configuración de varias interfaces de red permite asociar interfaces de red con grupos de nodos, lo que puede mejorar el rendimiento. Los clústeres pueden contener una combinación de tipos de nodos. Si agrupas máquinas de alto rendimiento en un grupo de nodos, puedes añadir interfaces adicionales al grupo de nodos para mejorar el flujo de tráfico.

Configurar varias interfaces de red

Por lo general, hay tres pasos para configurar varias interfaces de red para tus pods:

  1. Habilita la opción de varias NICs en tu clúster con el campo multipleNetworkInterfaces del recurso personalizado del clúster.

  2. Especifica interfaces de red con recursos personalizados de NetworkAttachmentDefinition.

  3. Asigna interfaces de red a pods con la anotación k8s.v1.cni.cncf.io/networks.

Se proporciona información adicional para ayudarte a configurar y usar la función de varias NICs de la forma que mejor se adapte a tus requisitos de red.

Habilitar varias NICs

Habilita la opción de varias NICs en tus pods añadiendo el campo multipleNetworkInterfaces a la sección clusterNetwork del recurso personalizado del clúster y asignándole el valor true.

  ...
  clusterNetwork:
    multipleNetworkInterfaces: true
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...

Especificar interfaces de red

Use recursos personalizados NetworkAttachmentDefinition para especificar interfaces de red adicionales. Los recursos personalizados de NetworkAttachmentDefinition se corresponden con las redes disponibles para tus pods. Puedes especificar los recursos personalizados en la configuración del clúster, como se muestra en el siguiente ejemplo, o crear los NetworkAttachmentDefinition recursos personalizados directamente.

---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: my-cluster
  namespace: cluster-my-cluster
spec:
    type: user
    clusterNetwork:
      multipleNetworkInterfaces: true
...
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "enp2342",  # defines the node interface that this pod interface would
                         map to.
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.120.0.0/24"
  }
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-2
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "macvlan",
  "mode": "bridge",
  "master": "vlan102",
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "10.10.0.1/24",
        "gateway": "10.10.0.254"
      }
    ],
    "routes": [
      { "dst": "192.168.0.0/16", "gw": "10.10.5.1" }
    ]
  }
}'

Cuando especifiques el recurso personalizado NetworkAttachmentDefinition en el archivo de configuración del clúster, Google Distributed Cloud usará este nombre para controlar el recurso personalizado NetworkAttachmentDefinition después de crear el clúster. Google Distributed Cloud trata este recurso personalizado en el espacio de nombres del clúster como la fuente de información veraz y lo reconcilia con el espacio de nombres default del clúster de destino.

En el siguiente diagrama se muestra cómo reconcilia Google Distributed Cloud los recursos personalizados de NetworkAttachmentDefinition del espacio de nombres específico del clúster con el espacio de nombres default.

Conciliación de NetworkAttachmentDefinition

Aunque es opcional, te recomendamos que especifiques NetworkAttachmentDefinition recursos personalizados de esta forma durante la creación del clúster. Los clústeres de usuarios se benefician más cuando se especifican los recursos personalizados durante la creación del clúster, ya que entonces se pueden controlar los recursos personalizados NetworkAttachmentDefinition desde el clúster de administrador.

Si decides no especificar NetworkAttachmentDefinition recursos personalizados durante la creación del clúster, puedes añadir NetworkAttachmentDefinition recursos personalizados directamente a un clúster de destino. Google Distributed Cloud reconcilia los NetworkAttachmentDefinition recursos personalizados definidos en el espacio de nombres del clúster. La conciliación también se produce al eliminar. Cuando se elimina un recurso personalizado NetworkAttachmentDefinition de un espacio de nombres de un clúster, Google Distributed Cloud elimina el recurso personalizado del clúster de destino.

Asignar interfaces de red a un pod

Usa la anotación k8s.v1.cni.cncf.io/networks para asignar una o varias interfaces de red a un pod. Cada interfaz de red se especifica con un espacio de nombres y el nombre de un recurso personalizado NetworkAttachmentDefinition, separados por una barra diagonal (/).

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: NAMESPACE/NAD_NAME
spec:
  containers:
  ...

Haz los cambios siguientes:

  • NAMESPACE: el espacio de nombres. Usa default para el espacio de nombres predeterminado, que es el estándar. Consulta la sección Problemas de seguridad para ver una excepción.
  • NAD_NAME: el nombre del recurso personalizado NetworkAttachmentDefinition.

Usa una lista separada por comas para especificar varias interfaces de red.

En el siguiente ejemplo, se asignan dos interfaces de red al pod samplepod. Las interfaces de red se especifican mediante los nombres de dos recursos personalizados NetworkAttachmentDefinition, gke-network-1 y gke-network-2, en el espacio de nombres predeterminado del clúster de destino.

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
  containers:
  ...

Restringir interfaces de red a un NodePool

Usa la anotación k8s.v1.cni.cncf.io/nodeSelector para especificar el grupo de nodos para los que es válido un recurso personalizado NetworkAttachmentDefinition. Google Distributed Cloud obliga a que los pods que hagan referencia a este recurso personalizado se implementen en esos nodos específicos. En el siguiente ejemplo, Google Distributed Cloud fuerza la implementación de todos los pods a los que se les ha asignado la interfaz de red gke-network-1 al NodePool multinicNP. Google Distributed Cloud etiqueta un NodePool con la etiqueta baremetal.cluster.gke.io/node-pool según corresponda.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: baremetal.cluster.gke.io/node-pool=multinicNP
  name: gke-network-1
spec:
...

No tienes por qué usar solo las etiquetas estándar. Puede crear sus propios pools personalizados a partir de los nodos del clúster aplicando una etiqueta personalizada a esos nodos. Usa el comando kubectl label nodes para aplicar una etiqueta personalizada:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

Haz los cambios siguientes:

  • NODE_NAME: el nombre del nodo que estás etiquetando.
  • LABEL_KEY: la clave que se va a usar en la etiqueta.
  • LABEL_VALUE: nombre de la etiqueta.

Una vez que se haya etiquetado el nodo, aplica la anotación baremetal.cluster.gke.io/label-taint-no-sync en ese nodo para evitar que Google Distributed Cloud concilie las etiquetas. Usa el comando kubectl get nodes --show-labels para verificar si un nodo está etiquetado.

Problemas de seguridad

Un recurso personalizado NetworkAttachmentDefinition proporciona acceso completo a una red, por lo que los administradores de clústeres deben tener cuidado al proporcionar acceso de creación, actualización o eliminación a otros usuarios. Si un recurso personalizado NetworkAttachmentDefinition determinado tiene que aislarse, se puede colocar en un espacio de nombres no predeterminado, donde solo los pods de ese espacio de nombres pueden acceder a él. Para conciliar los recursos personalizados de NetworkAttachmentDefinition especificados en el archivo de configuración del clúster, siempre se colocan en el espacio de nombres predeterminado.

En el siguiente diagrama, los pods del espacio de nombres default no pueden acceder a la interfaz de red del espacio de nombres privileged.

Uso de espacios de nombres para aislar el tráfico de red

Complementos de CNI admitidos

En esta sección se enumeran los plugins CNI compatibles con la función de varias NICs de Google Distributed Cloud. Usa solo los siguientes complementos cuando especifiques un recurso personalizado NetworkAttachmentDefinition.

Creación de interfaces:

  • ipvlan
  • macvlan
  • bridge
  • sriov

Complementos de Meta:

  • portmap
  • sbr
  • tuning

Complementos de IPAM:

  • host-local
  • static
  • whereabouts

Configuración de rutas

Un pod con uno o varios recursos personalizados NetworkAttachmentDefinition asignados tiene varias interfaces de red. De forma predeterminada, la tabla de enrutamiento en esta situación se amplía con las interfaces adicionales disponibles localmente de los recursos personalizados NetworkAttachmentDefinition asignados. La pasarela predeterminada sigue configurada para usar la interfaz principal o predeterminada del pod, eth0.

Puedes modificar este comportamiento con los siguientes complementos de CNI:

  • sbr
  • static
  • whereabouts

Por ejemplo, puede que quieras que todo el tráfico pase por la interfaz predeterminada, es decir, la puerta de enlace predeterminada. Sin embargo, parte del tráfico específico se envía a través de una de las interfaces no predeterminadas. Puede ser difícil desambiguar el tráfico en función de la IP de destino (enrutamiento normal), ya que el mismo endpoint está disponible en ambos tipos de interfaz. En este caso, el enrutamiento basado en la fuente (SBR) puede ser útil.

Complemento SBR

El complemento sbr permite que la aplicación controle las decisiones de enrutamiento. La aplicación controla lo que se usa como dirección IP de origen de la conexión que establece. Cuando la aplicación decide usar la dirección IP del recurso personalizado NetworkAttachmentDefinition como IP de origen, los paquetes llegan a la tabla de enrutamiento adicional que ha configurado sbr. La tabla de sbrenrutamientoNetworkAttachmentDefinition establece la interfaz del recurso personalizado NetworkAttachmentDefinitioncomo pasarela predeterminada. La IP de la pasarela predeterminada de esa tabla se controla con el campo gateway de los complementos whereabouts o static. Proporciona el complemento sbr como complemento encadenado. Para obtener más información sobre el complemento sbr, incluida información sobre su uso, consulta el artículo Complemento de enrutamiento basado en la fuente.

En el siguiente ejemplo se muestra "gateway":"21.0.111.254" definido en whereabouts y sbr definido como complemento encadenado después de ipvlan:

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1

Complementos de ubicación y de estado

El complemento whereabouts es básicamente una extensión del complemento static y ambos comparten la configuración de enrutamiento. Para ver un ejemplo de configuración, consulta el complemento de gestión de direcciones IP estáticas. Puedes definir una pasarela y una ruta para añadirlas a la tabla de enrutamiento del pod. Sin embargo, no puedes modificar la pasarela predeterminada del pod de esta forma.

En el siguiente ejemplo se muestra la adición de "routes": [{ "dst": "172.31.0.0/16" }] en el recurso personalizado NetworkAttachmentDefinition:

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link

Ejemplos de configuración

En esta sección se ilustran algunas de las configuraciones de red habituales que admite la función de varias NICs.

Una sola conexión de red usada por varios pods

Una sola conexión de red usada por varios pods

Varias conexiones de red usadas por un solo pod

Varias conexiones de red usadas por un solo pod

Varias conexiones de red que apuntan a la misma interfaz usada por un solo pod

Varias conexiones de red que apuntan a la misma interfaz usada por un solo pod

Se ha usado la misma conexión de red varias veces en un solo pod

Se ha usado la misma conexión de red varias veces en un solo pod

Solucionar problemas

Si se configuran incorrectamente interfaces de red adicionales, los pods a los que se les asignan no se inician. En esta sección se explica cómo encontrar información para solucionar problemas con la función de varias NICs.

Consultar eventos de pods

Multus informa de los errores a través de los eventos de pods de Kubernetes. Usa el siguiente comando kubectl describe para ver los eventos de un pod concreto:

kubectl describe pod POD_NAME

Consultar registros

En cada nodo, puedes encontrar los registros de ubicación y de Multus en las siguientes ubicaciones:

  • /var/log/whereabouts.log
  • /var/log/multus.log

Revisar las interfaces de los pods

Usa el comando kubectl exec para comprobar las interfaces de tu pod. Una vez que los recursos personalizados de NetworkAttachmentDefinition se hayan aplicado correctamente, las interfaces del pod tendrán un aspecto similar al siguiente:

$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 21.0.103.112/21 scope global net1
       valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.191/32 scope global eth0
       valid_lft forever preferred_lft forever

Obtener el estado de un pod

Usa kubectl get para obtener el estado de la red de un pod concreto:

kubectl get pods POD_NAME -oyaml

A continuación se muestra un ejemplo de salida que muestra el estado de un pod con varias redes:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "",
          "interface": "eth0",
          "ips": [
              "192.168.1.88"
          ],
          "mac": "36:0e:29:e7:42:ad",
          "default": true,
          "dns": {}
      },{
          "name": "default/gke-network-1",
          "interface": "net1",
          "ips": [
              "21.0.111.1"
          ],
          "mac": "00:50:56:82:a7:ab",
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: gke-network-1