Configura interfaces de red múltiples para pods

En este documento, se describe cómo configurar GKE en Bare Metal para proporcionar varias interfaces de red, varias NIC, para tus Pods. La función de varias NIC para pods puede ayudar a separar el tráfico del plano de control del tráfico del plano de datos, lo que crea aislamiento entre los planos. Las interfaces de red adicionales también habilitan la capacidad de multidifusión para tus pods. Solo se admiten varias NIC para pods en clústeres de usuario, clústeres híbridos y clústeres independientes. No está permitido para los clústeres de tipo de administrador.

El aislamiento del plano de red es importante para los sistemas que usan la virtualización de funciones de red (NFV), como una red definida por software en una red de área extensa (SD-WAN), un agente de seguridad para el acceso a la nube (CASB) y firewalls de última generación (NG-FW). Estos tipos de NFV dependen del acceso a varias interfaces para mantener separados los planos de administración y de datos, mientras se ejecutan como contenedores.

La configuración de interfaces de red múltiples admite la asociación de interfaces de red con grupos de nodos, lo que puede proporcionar beneficios de rendimiento. Los clústeres pueden contener una combinación de tipos de nodos. Cuando agrupas máquinas de alto rendimiento en un grupo de nodos, puedes agregar interfaces adicionales al grupo de nodos para mejorar el flujo de tráfico.

Configura interfaces de red múltiples

En general, hay tres pasos para configurar interfaces de red múltiples para los pods:

  1. Habilita varias NIC para tu clúster con el campo multipleNetworkInterfaces en el recurso personalizado (CR) del clúster.

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

  3. Asigna interfaces de red a los 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 NIC de la manera que mejor se adapte a tus requisitos de herramientas de redes.

Habilitar varias NIC

A fin de habilitar varias NIC para tus pods, agrega el campo multipleNetworkInterfaces a la sección clusterNetwork del recurso personalizado del clúster y configúralo como true.

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

Especifica interfaces de red

Usa los recursos personalizados de NetworkAttachmentDefinition para especificar interfaces de red adicionales. Los recursos personalizados NetworkAttachmentDefinition corresponden a las redes que están disponibles para tus Pods. Puedes especificar los recursos personalizados dentro de la configuración del clúster, como se muestra en el siguiente ejemplo, o puedes crear los recursos personalizados NetworkAttachmentDefinition 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 especificas el recurso personalizado NetworkAttachmentDefinition en el archivo de configuración de tu clúster, GKE en Bare Metal usa este nombre para controlar el recurso personalizado NetworkAttachmentDefinition después de la creación del clúster. GKE en Bare Metal trata este recurso personalizado dentro del espacio de nombres del clúster como la fuente de información y lo concilia con el espacio de nombres default del clúster de destino.

En el siguiente diagrama, se ilustra cómo GKE en Bare Metal concilia los recursos personalizados 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 los recursos personalizados de NetworkAttachmentDefinition de esta manera, durante la creación del clúster. Los clústeres de usuario se benefician más cuando especificas los recursos personalizados durante la creación del clúster, ya que luego puedes controlar los recursos personalizados de NetworkAttachmentDefinition desde el clúster de administrador.

Si decides no especificar los recursos personalizados de NetworkAttachmentDefinition durante la creación del clúster, puedes agregar recursos personalizados de NetworkAttachmentDefinition directamente a un clúster de destino existente. GKE en Bare Metal concilia NetworkAttachmentDefinition recursos personalizados definidos en el espacio de nombres del clúster. La conciliación también ocurre tras la eliminación. Cuando se quita un recurso personalizado NetworkAttachmentDefinition del espacio de nombres de un clúster, GKE en Bare Metal quita el recurso personalizado del clúster de destino.

Asigna interfaces de red a un Pod

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

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

Reemplaza lo siguiente:

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

Usa una lista separada por comas para especificar interfaces de red múltiples.

En el siguiente ejemplo, se asignan dos interfaces de red al pod samplepod. Las interfaces de red se especifican con nombres de dos recursos personalizados de 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:
  ...

Restringe las interfaces de red a un grupo de nodos

Usa la anotación k8s.v1.cni.cncf.io/nodeSelector a fin de especificar el grupo de nodos para el que es válido un recurso personalizado de NetworkAttachmentDefinition. GKE en Bare Metal obliga a los Pods que hacen referencia a este recurso personalizado a implementarse en esos nodos específicos. En el siguiente ejemplo, GKE en Bare Metal fuerza la implementación de todos los Pods asignados a la interfaz de red gke-network-1 en el grupo de nodos multinicNP. GKE en Bare Metal etiqueta un grupo de nodos 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 estás limitado a usar las etiquetas estándar. Puedes crear tus propios grupos personalizados desde los nodos del clúster si aplicas 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

Reemplaza lo siguiente:

  • NODE_NAME: es el nombre del nodo que deseas etiquetar.
  • LABEL_KEY: es la clave que se usará para la etiqueta.
  • LABEL_VALUE: es el nombre de la etiqueta.

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

Medidas de seguridad

Un recurso personalizado de NetworkAttachmentDefinition proporciona acceso completo a una red, por lo que los administradores de clústeres deben tener cuidado cuando proporcionen el acceso de creación, actualización o eliminación a otros usuarios. Si un recurso personalizado determinado de NetworkAttachmentDefinition debe aislarse, se lo puede colocar en un espacio de nombres no predeterminado, en el que solo los Pods de ese espacio de nombres pueden acceder a este. 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 en el 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 complementos de CIN compatibles con la función de varias NIC para GKE en Bare Metal. Usa solo los siguientes complementos cuando especifiques un recurso personalizado de NetworkAttachmentDefinition.

Creación de la interfaz:

  • ipvlan
  • macvlan
  • bridge
  • sriov

Complementos de Meta:

  • portmap
  • sbr
  • tuning

Complementos de IPAM:

  • host-local
  • static
  • whereabouts

Configuración de ruta

Un pod con uno o más recursos personalizados de NetworkAttachmentDefinition asignados tiene varias interfaces de red. De forma predeterminada, la tabla de enrutamiento en esta situación se extiende con las interfaces adicionales disponibles de forma local solo del recurso personalizado de NetworkAttachmentDefinition asignado. La puerta de enlace predeterminada aún está configurada para usar la interfaz principal/predeterminada del pod, eth0.

Puedes modificar este comportamiento mediante los siguientes complementos de CNI:

  • sbr
  • static
  • whereabouts

Por ejemplo, es posible que desees que todo el tráfico pase por la puerta de enlace predeterminada, la interfaz predeterminada. Sin embargo, parte del tráfico específico pasa por una de las interfaces no predeterminadas. Puede ser difícil quitar la ambigüedad del tráfico según la IP de destino (enrutamiento normal), porque el mismo extremo está disponible en ambos tipos de interfaces. En este caso, el enrutamiento basado en la fuente (SBR) puede ayudar.

Complemento SBR

El complemento sbr otorga a la aplicación control sobre las decisiones de enrutamiento. La aplicación controla lo que se usa como la dirección IP de origen de la conexión que establece. Cuando la aplicación elige usar la dirección IP del recurso personalizado de NetworkAttachmentDefinition para su IP de origen, los paquetes llegan a la tabla de enrutamiento adicional sbr configurada. La tabla de enrutamiento sbr establece la interfaz del recurso personalizado de NetworkAttachmentDefinition como la puerta de enlace predeterminada. La IP de la puerta de enlace predeterminada dentro de esa tabla se controla con el campo gateway dentro de los complementos whereabouts o static. Proporciona el complemento sbr como un complemento en cadena. Para obtener más información sobre el complemento sbr, incluida la información de uso, consulta Complemento de enrutamiento basado en la fuente.

En el siguiente ejemplo, se muestra "gateway":"21.0.111.254" configurado en whereabouts y sbr configurado como complemento en cadena 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 static y whereabouts

El complemento whereabouts es, en esencia, una extensión del complemento static, y ambos comparten la configuración de enrutamiento. Para ver un ejemplo de configuración, consulta Complemento static de administración de dirección IP. Puedes definir una puerta de enlace y una ruta para agregar a la tabla de enrutamiento del pod. Sin embargo, no puedes modificar la puerta de enlace predeterminada del pod de esta manera.

En el siguiente ejemplo, se muestra la adición de "routes": [{ "dst": "172.31.0.0/16" }] en el recurso personalizado de 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 comunes compatibles con la función de varias NIC.

Adjunto de red único usado por varios pods

Adjunto de red único usado por varios pods

Varios adjuntos de red usados por un solo pod

Varios adjuntos de red usados por un solo pod

Varios adjuntos de red que apuntan a la misma interfaz usados por un solo pod

Varios adjuntos de red que apuntan a la misma interfaz usados por un solo pod

El mismo adjunto de red usado varias veces por un solo pod

El mismo adjunto de red usado varias veces por un solo pod

Solución de problemas

Si las interfaces de red adicionales están configuradas de forma incorrecta, no se inician los Pods a los que se asignen. En esta sección, se destaca cómo encontrar información para solucionar problemas con la función de varias NIC.

Verifica los eventos del pod

Multus informa fallas a través de los eventos de Pods de Kubernetes. Usa el siguiente comando de kubectl describe para ver los eventos de un Pod determinado:

kubectl describe pod POD_NAME

Verifica los registros

Para cada nodo, puedes encontrar los registros de whereabouts y Multus en las siguientes ubicaciones:

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

Revisa las interfaces del pod

Usa el comando kubectl exec para verificar las interfaces de los pods. Una vez que los recursos personalizados de NetworkAttachmentDefinition se aplican de forma correcta, las interfaces del pod se ven como el siguiente resultado:

$ 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

Obtén el estado del pod

Usa kubectl get para recuperar el estado de la red de un pod determinado:

kubectl get pods POD_NAME -oyaml

A continuación, verás un resultado de muestra del 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