Networking a doppio stack IPv4/IPv6

Google Distributed Cloud supporta Doppio stack IPv4/IPv6 networking. Ciò significa che un cluster può accettare il traffico da dispositivi esterni che utilizzano Internet Protocol versione 4 (IPv4) o Internet Protocol versione 6 (IPv6).

Il networking a doppio stack assegna indirizzi IPv4 e IPv6 a pod e nodi. Un servizio Kubernetes può avere un indirizzo IPv4, un indirizzo IPv6 o entrambi.

Tutti i cluster a doppio stack utilizzano modalità flat per IPv6. Per impostazione predefinita, un cluster a doppio stack utilizza la modalità a isola per IPv4, puoi configurarlo in modo che utilizzi la modalità flat per IPv4.

Per creare un cluster a doppio stack, la rete sottostante deve essere abilitata a doppio stack. Se la rete sottostante è una rete IPv4 o IPv6 a stack singolo, non puoi per avviare un cluster a doppio stack.

Prima di iniziare

Se i nodi del tuo cluster eseguono RedHat Enterprise Linux, e hanno SELinux abilitata, quindi su ciascun nodo:

  • In /etc/firewalld/firewalld.conf, imposta IPv6_rpfilter=no.

  • Esegui systemctl restart firewalld.

Panoramica della creazione di un cluster a doppio stack

Puoi abilitare il networking a doppio stack quando crei un nuovo cluster, impossibile abilitare il networking a doppio stack per un cluster esistente.

Segui le istruzioni in una delle documenti relativi alla creazione del cluster.

Nel file di configurazione, includi i manifest per:

  • Una risorsa Spazio dei nomi
  • Una risorsa Cluster
  • Una o più risorse NodePool
  • Una o più risorse ClusterCIDRConfig

Compila il manifest dello spazio dei nomi e si manifesta il pool di nodi come faresti per un in un cluster a stack singolo.

Nel manifest del cluster, in clusterNetwork.services.cidrBlocks, specifica entrambi un intervallo CIDR IPv4 e un intervallo CIDR IPv6. Questo è il criterio di abilitazione in un cluster a doppio stack. Vale a dire, se fornisci intervalli CIDR del servizio sia per IPv4 e IPv6, il cluster avrà una rete a doppio stack.

Nel manifest del cluster, in clusterNetwork.pods.cidrBlocks, specifica un indirizzo IPv4 Intervallo CIDR, ma non specificare un intervallo CIDR IPv6. Intervalli CIDR IPv6 per i pod sono specificate nei manifest ClusterCIDRConfig.

Se utilizzi il bilanciamento del carico in bundle, fornisci indirizzi sia IPv4 che IPv6 nella sezione loadBalancer.addressPools del manifest del cluster.

Le risorse ClusterCIDRConfig consentono di specificare gli intervalli CIDR IPv4 e IPv6 per di pod. Puoi utilizzare una singola risorsa ClusterCIDRConfig per specificare gli intervalli CIDR a livello di cluster. Ciò significa che gli indirizzi dei pod IPv4 per tutti i nodi da un singolo intervallo CIDR e gli indirizzi dei pod IPv6 di tutti i nodi vengono presi da un singolo intervallo CIDR. In alternativa, puoi utilizzare diverse risorse ClusterCIDRConfig per specificare gli intervalli CIDR applicabili a un determinato pool di nodi o a un determinato nodo.

Connettività per gli indirizzi IP dei pod

Un cluster a doppio stack utilizza la modalità flat per il networking IPv6. L'esempio fornito questo documento riguarda un cluster che utilizza il networking flat-mode statico per IPv6. Questo significa che il cluster non è configurato per l'utilizzo del BGP (Border Gateway Protocol).

Per un cluster che utilizza il networking flat-mode statico, devi specificare nodo e Gli indirizzi IP dei pod che fanno tutti parte della stessa subnet. Questa configurazione rende possibile per i client esterni al cluster, ma nello stesso Dominio di livello 2 come nodi del cluster, per inviare pacchetti direttamente agli indirizzi IP dei pod.

Ad esempio, supponiamo che i tuoi nodi del cluster e alcune altre macchine si trovino lo stesso dominio di livello 2. Ecco un modo per specificare gli intervalli di indirizzi:

FinalitàIntervalloNumero di indirizzi
Intero dominio del livello 2fd12::/108220
Podfd12::1:0/112216
Nodifd12::2:0/112216
Altre macchinefd12::3:0/112216
VIPfd12::4:0/112216

Nell'esempio precedente, ecco i punti chiave da comprendere:

  • Tutti gli indirizzi di nodi, pod e macchine sono nell'intervallo più ampio: fd12::/108.

  • Gli indirizzi IP dei pod si trovano in un sottoinsieme dell'intervallo più ampio.

  • Gli indirizzi IP dei nodi si trovano in un sottoinsieme diverso dell'intervallo ampio.

  • Gli indirizzi IP delle altre macchine si trovano in un sottoinsieme diverso del modello intervallo.

  • Tutti gli intervalli di sottoinsiemi sono distinti tra loro.

Nell'esempio precedente, ogni macchina nel dominio di livello 2, incluso il cluster nodi devono avere una regola di forwarding per l'intervallo ampio. Ad esempio:

inet fd12::/108 scope global eth0

Esempio: creare un cluster a doppio stack

Quando crei un cluster a doppio stack, hai a disposizione varie opzioni. Ad esempio, potrebbero avere intervalli CIDR a livello di cluster oppure intervalli CIDR applicabili pool di nodi specifici. Puoi combinare una rete piatta IPv6 con una rete IPv4 in modalità isola. Oppure entrambe le reti IPv4 e IPv6 potrebbero essere piatte. Tu puoi utilizzare il bilanciamento del carico in bundle o manuale.

Questa sezione fornisce un esempio di come creare un cluster a doppio stack. Il cluster in questo esempio ha le seguenti caratteristiche:

  • Una rete IPv4 in modalità isola
  • Una rete IPv6 in modalità flat
  • Un intervallo CIDR IPv4 a livello di cluster per i pod
  • Un intervallo CIDR IPv6 a livello di cluster per i pod
  • Un intervallo CIDR IPv4 a livello di cluster per i servizi
  • Un intervallo CIDR IPv6 a livello di cluster per i servizi
  • Un pool di indirizzi IPv4 da utilizzare per i servizi di tipo LoadBalancer
  • Un pool di indirizzi IPv6 da utilizzare per i servizi di tipo LoadBalancer
  • Bilanciamento del carico in bundle

Per ulteriori esempi di configurazione, consulta Varianti sull'utilizzo di ClusterCIDRConfig.

Compila un file di configurazione

Segui le istruzioni in una delle documenti relativi alla creazione del cluster.

Nel file di configurazione, nel manifest Cluster:

  • Per clusterNetwork.pods.cidrBlocks, fornisci un singolo intervallo CIDR IPv4.

  • Per clusterNetwork.services.cidrBlocks, fornisci due intervalli CIDR: uno per IPv4 e uno per IPv6.

  • Per loadBalancer.addressPools, fornisci due intervalli di indirizzi: uno per IPv4 e una per IPv6. Quando crei un Servizio di tipo LoadBalancer, gli indirizzi IP esterni per il servizio vengono scelti da questi intervalli.

Ecco un esempio che mostra le parti pertinenti del manifest di un cluster:

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"

Nello stesso file di configurazione, includi un manifest per un ClusterCIDRConfig.

  • Imposta ipv4.cidr sullo stesso intervallo CIDR fornito in Cluster del file manifest. Questo è un requisito se IPv4 è in modalità isola.

  • Imposta namespace sullo stesso valore che hai fornito nel file manifest di Cluster.

  • Imposta ipv6.cidr su un intervallo CIDR IPv6 per i pod.

  • Per ogni intervallo CIDR, fornisci un valore per perNodeMaskSize per specificare il numero Gli indirizzi dei pod verranno assegnati a ciascun nodo. Il numero di indirizzi IPv4 assegnato a ciascun nodo deve essere uguale al numero di indirizzi IPv6 assegnati a ciascun nodo. Devi impostare i valori per perNodeMaskSize di conseguenza. Ad esempio, se vuoi 28 indirizzi per nodo, imposta la tua perNodeMaskSize come segue:

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

Ecco un esempio di manifest 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

Nell'esempio precedente:

  • L'intervallo CIDR del pod IPv4 ha 2(32-16) = 216 indirizzi. La dimensione della maschera per nodo è 24, quindi il numero di indirizzi assegnati è 2(32-24) = 28.

  • L'intervallo CIDR del pod IPv6 è 2(128-112) = 216 indirizzi IP esterni. La dimensione della maschera per nodo è 120, quindi il numero di indirizzi assegnato a ciascun nodo è 2(128-120) = 28.

File di configurazione di esempio

Completa la creazione del cluster

Completa la creazione del cluster come descritto documento di creazione del cluster.

Visualizza nodi e pod del cluster

Elenca i nodi del cluster:

kubectl --kubeconfig CLUSTER_KUBECONFIG get nodes --output yaml

Sostituisci CLUSTER_KUBECONFIG con il percorso kubeconfig del cluster .

Nell'output, puoi vedere gli indirizzi IPv4 e IPv6 di ciascun nodo. Puoi vedi anche gli intervalli di indirizzi IPv4 e IPv6 per i pod sul nodo. Ad esempio:

- 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

Elenca i pod presenti nel cluster:

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

Scegli un pod ed elenca i dettagli. Ad esempio:

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

Nell'output puoi vedere gli indirizzi IPv4 e IPv6 del pod. Ad esempio:

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

Varianti sull'utilizzo di ClusterCIDRConfig

L'esempio precedente utilizza un oggetto ClusterCIDRConfig per specificare a livello di cluster Intervalli CIDR dei pod. Vale a dire che viene utilizzato un singolo intervallo CIDR IPv4 per tutti i pod in un cluster Kubernetes. Inoltre, viene utilizzato un singolo intervallo CIDR IPv6 per tutti i pod nel cluster.

In alcune situazioni potresti non voler utilizzare un singolo intervallo CIDR per tutte di pod in un cluster. Ad esempio, potresti voler specificare un intervallo CIDR separato per ogni pool di nodi oppure potresti voler specificare un intervallo CIDR separato nodo. Per ulteriori informazioni su ClusterCIDRConfig ed esempi su vedi Comprendere la risorsa personalizzata ClusterCIDRConfig.

Ad esempio, il seguente ClusterCIDRConfig specifica un intervallo CIDR per un nodo pool denominato "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"

Il seguente ClusterCIDRConfig specifica un intervallo CIDR per un singolo nodo con l'indirizzo 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 servizio a doppio stack di tipo ClusterIP

Ecco un manifest per un 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"

Salva il manifest in un file denominato my-deployment.yaml e crea il deployment:

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

Sostituisci CLUSTER_KUBECONFIG con il percorso kubeconfig del cluster .

Ecco un manifest per un servizio di 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

Nell'ambito di questo esercizio, ecco i punti chiave da comprendere il manifest precedente del servizio:

  • Il campo ipFamilyPolicy è impostato su RequireDualStack. Ciò significa che sia IPv6 e IPv4 ClusterIP sono assegnati al servizio.

  • Il campo ipFamilies specifica prima la famiglia IPv6 e la famiglia IPv4 secondo. Ciò significa che spec.ClusterIP per il servizio sarà un IPv6 indirizzo scelto tra clusterNetwork.services.cidrBlocks nel cluster del file manifest.

Salva il manifest in un file denominato my-cip-service.yaml e crea il servizio:

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

Elenca i dettagli sul Servizio:

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

Nell'output puoi vedere gli indirizzi IP del cluster per il servizio. Per esempio:

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

Su un nodo del cluster, chiama il servizio:

curl IPV4_CLUSTER_IP
curl IPV6_CLUSTER_IP

L'output visualizza "Hello World" messaggio:

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

Crea un servizio a doppio stack di tipo LoadBalancer

Ecco un manifest per un servizio di 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

Salva il manifest in un file denominato my-lb-service.yaml e crea il servizio:

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

Ricorda che nel manifest del tuo cluster hai specificato un intervallo di indirizzi IPv6. e un intervallo di indirizzi IPv4 da utilizzare per i servizi di tipo LoadBalancer:

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

Al servizio verrà assegnato un indirizzo IPv4 esterno scelto dalla piattaforma e un indirizzo IPv6 esterno scelto dall'intervallo IPv6.

Elenca i dettagli del servizio:

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

Nell'output puoi vedere gli indirizzi esterni per il servizio. Ad esempio:

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

Valori possibili per ipFamilyPolicy

Quando crei un servizio a doppio stack, puoi impostare ipFamilyPolicy su uno dei questi valori:

  • SingleStack: il controller alloca un indirizzo IP cluster per il servizio, scelto dal primo intervallo specificato nel manifest del cluster in clusterNetwork.services.cidrBlocks.

  • PreferDualStack: il controller alloca indirizzi IP del cluster IPv4 e IPv6 per il servizio, scelto tra gli intervalli specificati nel manifest del cluster sotto clusterNetwork.services.cidrBlocks. Se il cluster non è a doppio stack cluster, il comportamento è lo stesso di SingleStack.

  • RequireDualStack: il controller alloca l'IP del cluster IPv4 e IPv6 di servizio per il servizio, scelti tra gli intervalli specificati in clusterNetwork.services.cidrBlocks. Imposta il valore di spec.clusterIP in base alla prima famiglia di indirizzi specificata nel Servizio in ipFamilies.

Ulteriori informazioni

Per ulteriori informazioni su come creare servizi dual-stack, vedi Opzioni a doppio stack nei nuovi servizi.