Herramientas de redes de pila doble IPv4/IPv6

Los clústeres de Anthos en Bare Metal admiten las redes de pila doble IPv6 o IPv6. Esto significa que un clúster puede aceptar tráfico de dispositivos externos que usan la versión 4 del protocolo de Internet (IPv4) o la versión 6 del protocolo de Internet (IPv6).

Las redes de doble pila asignan direcciones IPv4 e IPv6 a los Pods y los nodos. Un servicio de Kubernetes puede tener una dirección IPv4, una dirección IPv6 o ambas.

Todos los clústeres de pila doble usan modo plano para IPv6. De forma predeterminada, un clúster de pila doble usa el modo isleño para IPv4, pero puedes configurarlo a fin de que use el modo plano para IPv4.

Para crear un clúster de pila doble, tu red subyacente debe estar habilitada. Si la red subyacente es una red IPv4 o IPv6 de una sola pila, no puedes iniciar un clúster de pila doble.

Antes de comenzar

Si los nodos de tu clúster ejecutan CentOS o Red Hat Enterprise Linux y tienen SELinux habilitado, entonces, en cada nodo, ejecuta el siguiente comando:

  • En /etc/firewalld/firewalld.conf, configura IPv6_rpfilter=no.

  • Ejecuta systemctl restart firewalld.

Descripción general de la creación de un clúster de pila doble

Puedes habilitar las redes de doble pila cuando creas un clúster nuevo, pero no puedes habilitar la red de pila doble para un clúster existente.

Sigue las instrucciones en uno de los documentos de creación de clústeres.

En tu archivo de configuración, incluye los manifiestos para lo siguiente:

  • Un recurso de espacio de nombres
  • Un recurso de clúster
  • Uno o más recursos de NodePool
  • Uno o más recursos ClusterCIDRConfig

Completa el manifiesto del espacio de nombres y los manifiestos de NodePool como lo harías con un clúster de una sola pila.

En el manifiesto del clúster, en clusterNetwork.services.cidrBlocks, especifica un rango de CIDR de IPv4 y un rango de CIDR de IPv6. Este es el criterio de habilitación de un clúster de pila doble. Es decir, si proporcionas rangos de CIDR de servicio para IPv4 y también IPv6, tu clúster tendrá una red de doble pila.

En el manifiesto del clúster, en clusterNetwork.pods.cidrBlocks, especifica un rango CIDR de IPv4, pero no especifiques un rango de IPv6 de CIDR. Los rangos de CIDR de IPv6 para pods se especifican en los manifiestos de ClusterCIDRConfig.

Si usas el balanceo de cargas en paquetes, proporciona las direcciones IPv4 y las IPv6 en la sección loadBalancer.addressPools del manifiesto del clúster.

Los recursos ClusterCIDRConfig permiten especificar rangos de IPv4 y de IPv6 para pods. Puedes usar un solo recurso ClusterCIDRConfig para especificar los rangos CIDR que se encuentran en todo el clúster. Es decir, las direcciones de pod de IPv4 de todos los nodos se toman de un solo rango CIDR y las direcciones de pod de IPv6 de todos los nodos se toman de un solo rango CIDR. O bien, puedes usar varios recursos ClusterCIDRConfig para especificar los rangos CIDR que se aplican a un grupo de nodos en particular o a un nodo en particular.

Accesibilidad para las direcciones IP del Pod

Un clúster de pila doble usa el modo plano para redes IPv6. El ejemplo que se proporciona en este documento es para un clúster que usa herramientas de redes estáticas de modo plano para IPv6. Es decir, el clúster no está configurado para usar el protocolo de puerta de enlace fronteriza (BGP).

Para un clúster que usa herramientas de redes estáticas de modo plano, debes especificar las direcciones IP de los nodos y los pods que forman parte de la misma subred. Esto permite a los clientes fuera del clúster, pero en el mismo dominio de capa 2 (L2) que los nodos del clúster, enviar paquetes directamente a las direcciones IP del Pod.

Por ejemplo, supongamos que los nodos del clúster y algunas otras máquinas están todos en el mismo dominio L2. A continuación, te mostramos una forma de especificar rangos de direcciones:

ObjetivoRangeCantidad de direcciones
Todo el dominio L2fd12::/1082^20
Podsfd12::1:0/1122^16
Nodosfd12::2:0/1122^16
Otras máquinasfd12::3:0/1122^16
VIPfd12::4:0/1122^16

En el ejemplo anterior, estos son los puntos clave que debes comprender:

  • Todas las direcciones de nodo, pod y máquina están en el gran rango: fd12::/108.

  • Las direcciones IP del Pod están en un subconjunto del rango grande.

  • Las direcciones IP del nodo se encuentran en un subconjunto diferente del gran rango.

  • Las direcciones IP de otras máquinas se encuentran en un subconjunto diferente del rango grande.

  • Todos los rangos de subconjuntos son diferentes entre sí.

En el ejemplo anterior, cada máquina del dominio L2, incluidos los nodos del clúster, debe tener una regla de reenvío para el rango grande. Por ejemplo:

inet fd12::/108 scope global eth0

Ejemplo: Crea un clúster de pila doble

Cuando creas un clúster de pila doble, tienes varias opciones. Por ejemplo, podrías tener rangos de CIDR de todo el clúster o rangos de CIDR que se apliquen a grupos de nodos específicos. Puedes combinar una red plana IPv6 con una red en modo de isla IPv4. O bien, las redes IPv4 e IPv6 podrían ser planas. Puedes usar el balanceo de cargas en paquetes o el balanceo manual.

En esta sección, se proporciona un ejemplo de cómo crear un clúster de pila doble. El clúster de este ejemplo tiene las siguientes características:

  • Una red IPv4 en modo isla
  • Una red IPv6 en modo plano
  • Un rango de CIDR IPv4 para todo el clúster para pods
  • Un rango de CIDR IPv6 en todo el clúster para los pods
  • Un rango de CIDR IPv4 para todo el clúster para servicios
  • Un rango de CIDR IPv6 para todo el clúster
  • Un grupo de direcciones IPv4 que se usará para los servicios de tipo LoadBalancer
  • Un grupo de direcciones IPv6 que se usará para los servicios de tipo LoadBalancer
  • Balanceo de cargas en paquetes

Para ver ejemplos de configuración adicionales, consulta Variaciones sobre el uso de ClusterCIDRConfig.

Completa un archivo de configuración

Sigue las instrucciones en uno de los documentos de creación de clústeres.

En tu archivo de configuración, en el manifiesto Cluster, haz lo siguiente:

  • Para clusterNetwork.pods.cidrBlocks, proporciona un solo rango de IPv4 CIDR.

  • En clusterNetwork.services.cidrBlocks, proporciona dos rangos de CIDR: uno para IPv4 y otro para IPv6.

  • En loadBalancer.addressPools, proporciona dos rangos de direcciones: uno para IPv4 y otro para IPv6. Cuando creas un Service de tipo LoadBalancer, las direcciones IP externas para el Service se eligen entre estos rangos.

A continuación, se muestra un ejemplo en el que se muestran las partes relevantes de un manifiesto de clúster:

apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: "dual-stack"
  namespace: "cluster-dual-stack"

spec:
  clusterNetwork:
    pods:
      cidrBlocks:
      - "192.168.0.0/16"
    services
      cidrBlocks:
       - "172.16.0.0/20"
       - "fd12::5:0/116"
...
  loadBalancer:
    mode: "bundled"
    ...
    addressPools:
    - name: "pool-1"
      addresses:
       - "10.2.0.212-10.2.0.221"
       - "fd12::4:101-fd12::4:110"

En el mismo archivo de configuración, incluye un manifiesto para un ClusterCIDRConfig.

  • Configura ipv4.cidr en el mismo rango de CIDR que proporcionaste en el manifiesto Cluster. Esto es obligatorio si IPv4 está en modo isla.

  • Configura namespace con el mismo valor que proporcionaste en el manifiesto Cluster.

  • Establece ipv6.cidr en un rango de IPv6 de CIDR para los pods.

  • En cada rango CIDR, proporciona un valor para perNodeMaskSize a fin de especificar cuántas direcciones de Pod se asignarán a cada nodo. La cantidad de direcciones IPv4 asignadas a cada nodo debe ser la misma que la cantidad de direcciones IPv6 asignadas a cada nodo. Debes configurar tus valores para perNodeMaskSize según corresponda. Por ejemplo, si quieres 2^8 direcciones por nodo, configura tus valores perNodeMaskSize de la siguiente manera:

    • ipv4.perNodeMaskSize: 24 # (32 - 8 = 24)
    • ipv6.perNodeMaskSize: 120 # (128 - 8 = 120)

Este es un ejemplo de un manifiesto ClusterCIDRConfig:

apiVersion: baremetal.cluster.gke.io/v1alpha1
kind: ClusterCIDRConfig
metadata:
  name: "cluster-wide-ranges"
  namespace: "cluster-dual-stack"  # Must be the same as the Cluster namespace.
spec:
  ipv4:
    cidr: "192.168.0.0/16"  #  For island mode, must be the same as the Cluster CIDR.
    perNodeMaskSize: 24
  ipv6:
    cidr: "fd12::1:0/112"
    perNodeMaskSize: 120

En el ejemplo anterior:

  • El rango de CIDR del Pod de IPv4 tiene 2^(32-16) = 2^16 direcciones. El tamaño de la máscara por nodo es 24, por lo que la cantidad de direcciones asignadas a cada nodo es 2^(32-24) = 2^8.

  • El rango de CIDR del Pod de IPv6 tiene 2^(128-112) = 2^16 direcciones. El tamaño de la máscara por nodo es 120, por lo que la cantidad de direcciones asignadas a cada nodo es 2^(128-120) = 2^8.

Archivo de configuración de ejemplo

Termina de crear el clúster

Termina de crear tu clúster como se describe en tu documento de creación de clústeres.

Visualiza los nodos y pods del clúster

Enumera los nodos del clúster:

kubectl --kubeconfig CLUSTER_KUBECONFIG get nodes --output yaml

Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig del clúster.

En el resultado, puedes ver las direcciones IPv4 y, también, IPv6 de cada nodo. También puedes ver los rangos de direcciones IPv4 y, también, IPv6 para pods en el nodo. Por ejemplo:

- apiVersion: v1
  kind: Node
  ...
  spec:
    podCIDR: 192.168.1.0/24
    podCIDRs:
    - 192.168.1.0/24
    - fd12::1:100/120
    providerID: baremetal://10.2.0.5
  status:
    addresses:
    - address: 10.2.0.5
      type: InternalIP
    - address: fd12::2:5
      type: InternalIP

Enumera los pods en el clúster:

kubectl --kubeconfig CLUSTER_KUBECONFIG get pods --all-namespaces

Elija un Pod y obtenga una lista de detalles. Por ejemplo:

kubectl --kubeconfig CLUSTER_KUBECONFIG get pod gke-metrics-agent-b9qrv \
  --namespace kube-system \
  -- output yaml

En el resultado, puedes ver las direcciones IPv4 y las IPv6 del Pod. Por ejemplo:

apiVersion: v1
kind: Pod
metadata:
  ...
  name: gke-metrics-agent-b9qrv
  namespace: kube-system
...
status:
  ...
  podIPs:
  - ip: 192.168.1.146
  - ip: fd12::1:11a

Variaciones sobre el uso de ClusterCIDRConfig

En el ejemplo anterior, se usó un objeto ClusterCIDRConfig a fin de especificar los rangos de CIDR del Pod en todo el clúster. Es decir, se usa un solo rango CIDR de IPv4 para todos los pods del clúster. Y se usa un solo rango CIDR de IPv6 para todos los pods del clúster.

En ciertas situaciones, es posible que no desees usar un solo rango de CIDR para todos los pods de un clúster. Por ejemplo, es posible que desees especificar un rango de CIDR distinto para cada grupo de nodos o que especifiques un rango de CIDR distinto para cada nodo.

Por ejemplo, el ClusterCIDRConfig siguiente especifica un rango CIDR para un grupo de nodos llamado "workers".

apiVersion: baremetal.cluster.gke.io/v1alpha1
kind: ClusterCIDRConfig
metadata:
  name: "worker-pool-ccc"
  namespace: "cluster-dual-stack"
spec:
  ipv4:
    cidr: "192.168.0.0/16"
    perNodeMaskSize: 24
  ipv6:
    cidr: "fd12::1:0/112"
    perNodeMaskSize: 120
  nodeSelector:
    matchLabels:
      baremetal.cluster.gke.io/node-pool: "workers"

El siguiente ClusterCIDRConfig especifica un rango CIDR para un solo nodo que tiene la dirección IP 10.2.0.5:

apiVersion: baremetal.cluster.gke.io/v1alpha1
kind: ClusterCIDRConfig
metadata:
  name: "range-node1"
  namespace: "cluster-dual-stack"
spec:
  ipv4:
    cidr: "192.168.1.0/24"
    perNodeMaskSize: 24
  ipv6:
    cidr: "fd12::1:0/120"
    perNodeMaskSize: 120
  nodeSelector:
    matchLabels:
      baremetal.cluster.gke.io/k8s-ip: "10.2.0.5"

Crea un Service de pila doble de tipo ClusterIP

A continuación, se muestra un manifiesto de Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: "my-deployment"
spec:
  selector:
    matchLabels:
      app: "try-dual-stack"
  replicas: 3
  template:
    metadata:
      labels:
        app: "try-dual-stack"
    spec:
      containers:
      - name: "hello"
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

Guarda el manifiesto en un archivo llamado my-deployment.yaml y crea el Deployment:

kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-deployment.yaml

Reemplaza CLUSTER_KUBECONFIG por la ruta de acceso del archivo kubeconfig del clúster.

Aquí hay un manifiesto para un servicio de tipo ClusterIP:

apiVersion: v1
kind: Service
metadata:
  name: "my-service"
spec:
  selector:
    app: "try-dual-stack"
  type: "ClusterIP"
  ipFamilyPolicy: "RequireDualStack"
  ipFamilies:
  - "IPv6"
  - "IPv4"
  ports:
  - port: 80
    targetPort: 8080

En el contexto de este ejercicio, estos son los puntos clave que debes comprender sobre el manifiesto del Service anterior:

  • El campo ipFamilyPolicy está configurado en RequireDualStack lo que significa que las direcciones IPv6 e IPv4 ClusterIP están asignadas para el servicio.

  • El campo ipFamilies especifica la familia IPv6 primero y, luego, la familia IPv4. Esto significa que spec.ClusterIP para el servicio será una dirección IPv6 elegida de clusterNetwork.services.cidrBlocks en el manifiesto del clúster.

Guarda el manifiesto en un archivo llamado my-cip-service.yaml y crea el servicio:

kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-cip-service.yaml

Enumerar los detalles del servicio:

kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-service --output yaml

En el resultado, puedes ver las direcciones IP del clúster para el Service. Por ejemplo:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  …
spec:
  clusterIP: fd12::5:9af
  clusterIPs:
  - fd12::5:9af
  - 172.16.12.197

En un nodo del clúster, llama al servicio:

curl IPV4_CLUSTER_IP
curl [IPV6_CLUSTER_IP]

El resultado muestra el mensaje “Hello world”:

Hello, world!
Version: 2.0.0
Hostname: my-deployment-xxx

Crea un Service de pila doble de tipo LoadBalancer

Aquí hay un manifiesto para un servicio de tipo LoadBalancer:

apiVersion: v1
kind: Service
metadata:
  name: "my-lb-service"
spec:
  selector:
    app: "try-dual-stack"
  type: "LoadBalancer"
  ipFamilyPolicy: "RequireDualStack"
  ipFamilies:
  - "IPv6"
  - "IPv4"
  ports:
  - port: 80
    targetPort: 8080

Guarda el manifiesto en un archivo llamado my-lb-service.yaml y crea el servicio:

kubectl --kubeconfig CLUSTER_KUBECONFIG apply -f my-lb-service.yaml

Recuerda que en el manifiesto de tu clúster especificaste un rango de direcciones IPv6 y un rango de direcciones IPv4 que se usarán para los servicios de tipo LoadBalancer:

  loadBalancer:
    mode: "bundled"
    ...
    addressPools:
    - name: "pool-1"
      addresses:
      - "10.2.0.112-10.2.0.221"
      - "fd12::4:101-fd12::4:110"

A tu servicio se le asignará una dirección IPv4 externa elegida del rango IPv4 y una dirección IPv6 externa elegida del rango IPv6.

Enumerar los detalles del servicio:

kubectl --kubeconfig CLUSTER_KUBECONFIG get service my-lb-service --output yaml

En el resultado, puedes ver las direcciones externas del Service. Por ejemplo:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
...
status:
  loadBalancer:
    ingress:
    - ip: 10.2.0.213
    - ip: fd12::4:101

Valores posibles para ipFamilyPolicy

Cuando creas un servicio de pila doble, puedes establecer ipFamilyPolicy en uno de estos valores:

  • SingleStack: El controlador asigna una dirección IP del clúster para el servicio, elegida del primer rango especificado en el manifiesto del clúster en clusterNetwork.services.cidrBlocks.

  • PreferDualStack: El controlador asigna direcciones IP de clúster IPv4 e IPv6 para el servicio, seleccionadas de los rangos especificados en el manifiesto del clúster en clusterNetwork.services.cidrBlocks. Si el clúster no es de doble pila, el comportamiento es el mismo que con SingleStack.

  • RequireDualStack: El controlador asigna direcciones IP de clúster IPv4 e IPv6 para el servicio, seleccionadas de los rangos especificados en el manifiesto del clúster en clusterNetwork.services.cidrBlocks. Establece el valor de spec.clusterIP según la primera familia de direcciones que se especifique en el manifiesto de servicio, en ipFamilies.

Más información

Para obtener más información sobre cómo crear objetos de pila doble, consulta Opciones de pila doble en servicios nuevos.