Utilizzo di GKE Dataplane V2

Questa pagina spiega come attivare e risolvere i problemi relativi a GKE Dataplane V2 per i cluster Google Kubernetes Engine (GKE).

GKE Dataplane V2 è sempre abilitato nei nuovi cluster Autopilot. Se riscontri problemi con l'utilizzo di GKE Dataplane V2, vai alla sezione Risoluzione dei problemi.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti operazioni:

  • Attiva l'API Google Kubernetes Engine.
  • Attiva l'API Google Kubernetes Engine
  • Per utilizzare Google Cloud CLI per questa attività, installala e poi inizializza gcloud CLI. Se hai già installato gcloud CLI, scarica l'ultima versione eseguendo il comando gcloud components update. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per creare un cluster GKE, chiedi all'amministratore di concederti il ruolo IAM Amministratore di cluster Kubernetes Engine (container.clusterAdmin) nel progetto. Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.

Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.

Creazione di un cluster GKE con GKE Dataplane V2

Puoi abilitare GKE Dataplane V2 solo quando crei un nuovo cluster GKE. Non puoi modificare questa impostazione per un cluster esistente.

Per creare un cluster Standard che utilizza GKE Dataplane V2, seleziona una delle seguenti opzioni:

Console

  1. Nella console Google Cloud , vai alla pagina Crea un cluster Kubernetes.

    Vai a Crea un cluster Kubernetes

  2. Nel menu di navigazione, fai clic su Networking.

  3. Espandi la sezione Container Network Interface (CNI).

  4. Seleziona la casella di controllo Dataplane V2.

  5. Fai clic su Crea.

gcloud

Esegui questo comando:

gcloud container clusters create CLUSTER_NAME \
    --location=CONTROL_PLANE_LOCATION \
    --enable-dataplane-v2

Sostituisci quanto segue:

  • CLUSTER_NAME: un nome per il nuovo cluster.
  • CONTROL_PLANE_LOCATION: una posizione per il control plane del cluster.

API

Per creare un nuovo cluster con GKE Dataplane V2, specifica il campo datapathProvider nell' oggetto networkConfig nella richiesta create del cluster.

Il seguente snippet JSON mostra la configurazione necessaria per attivare GKE Dataplane V2:

"cluster":{
    "networkConfig":{
      "datapathProvider":"ADVANCED_DATAPATH"
    }
}

Risoluzione dei problemi relativi a GKE Dataplane V2

Questa sezione mostra come esaminare e risolvere i problemi relativi a GKE Dataplane V2.

  1. Verifica che GKE Dataplane V2 sia abilitato:

    kubectl -n kube-system get pods -l k8s-app=cilium -o wide
    

    Se GKE Dataplane V2 è in esecuzione, l'output include i pod con il prefisso anetd-. anetd è il controller di rete per GKE Dataplane V2.

  2. Se il problema riguarda i servizi o l'applicazione dei criteri di rete, controlla i log del pod anetd. Utilizza i seguenti selettori di log in Cloud Logging:

    resource.type="k8s_container"
    labels."k8s-pod/k8s-app"="cilium"
    resource.labels.cluster_name="CLUSTER_NAME"
    
  3. Se la creazione del pod non riesce, controlla i log kubelet per trovare indizi. Utilizza i seguenti selettori di log in Cloud Logging:

    resource.type="k8s_node"
    log_name=~".*/logs/kubelet"
    resource.labels.cluster_name="CLUSTER_NAME"
    

    Sostituisci CLUSTER_NAME con il nome del cluster o rimuovilo completamente per visualizzare i log di tutti i cluster.

  4. Se i pod anetd non sono in esecuzione, esamina ConfigMap cilium-config per eventuali modifiche. Evita di modificare i campi esistenti all'interno di questo ConfigMap, perché tali modifiche possono destabilizzare il cluster e interrompere anetd. Il ConfigMap viene patchato allo stato predefinito solo se vengono aggiunti nuovi campi. Le modifiche ai campi esistenti non vengono applicate e ti consigliamo di non modificare o personalizzare ConfigMap.

Problemi noti

Quando utilizzi GKE Dataplane V2, potresti riscontrare i seguenti problemi noti.

Timeout di connessione per i pod non pronti

Quando un pod non è pronto, le connessioni al servizio associato possono scadere. Questo è il comportamento previsto per GKE Dataplane V2 ed è diverso da kube-proxy, che può restituire un errore connection refused più rapido.

Il filtro delle etichette pertinenti all'identità per l'identità Cilium non ha effetto e i pod sono bloccati nello stato ContainerCreating

Versioni interessate: 1.34, 1.35

Nei cluster GKE Dataplane V2, l'utilizzo di emergenza del filtro delle etichette pertinenti all'identità tramite kube-system/cilium-config-emergency-override ConfigMap non viene applicato correttamente nelle versioni interessate.

Questo approccio limita le etichette dei pod utilizzate per la generazione dell'identità Cilium.

Quando altri meccanismi di prevenzione/rimozione di coppie chiave/valore di etichette con cardinalità elevata dai pod non sono disponibili (ad esempio quando le etichette vengono applicate da uno strumento o framework), il filtro delle etichette pertinenti all'identità può essere utilizzato per escludere le chiavi delle etichette dal calcolo dell'identità di Cilium. Per ulteriori informazioni sulla configurazione di queste regole, consulta Etichette pertinenti all'identità nella documentazione di Cilium.

Per le versioni GKE interessate, le identità Cilium create dall'operatore continuano a includere le etichette escluse.

Sintomi

  • I pod con etichette che devono essere filtrate per la generazione dell'identità Cilium potrebbero non avviarsi e rimanere bloccati nello stato ContainerCreating. Gli eventi del pod potrebbero mostrare errori di timeout:

      {"level":"warning", "msg":"Error changing endpoint identity", "error":"unable to resolve identity: timed out waiting for cilium-operator to allocate CiliumIdentity for key ...;, error: exponential backoff cancelled via context: context canceled", "k8sPodName":"...", "subsys":"endpoint"}
    
  • Anziché condividere le identità in base alle etichette filtrate, i pod con valori di etichetta univoci continuano a generare identità Cilium univoche. Ciò può portare a un forte aumento delle identità, potenzialmente esaurendo le identità Cilium disponibili (fino a un limite di 65.536) e causando problemi di scalabilità.

Versioni corrette

Per risolvere il problema, esegui l'upgrade del cluster a una delle seguenti versioni di GKE:

  • 1.34.6-gke.1307000 o versioni successive
  • 1.35.2-gke.1962000 o versioni successive

Soluzione temporanea

Come soluzione alternativa, applica le regole di filtro delle etichette al campo data.labels nel ConfigMap cilium-config principale e rimuovile da cilium-config-emergency-override. Questa situazione persiste durante le operazioni del control plane, come gli upgrade, perché GKE conserva le modifiche apportate dall'utente ai campi che non gestisce all'interno di ConfigMap cilium-config.

  1. Rimuovi la chiave labels dalla sezione data del ConfigMap cilium-config-emergency-override, se esiste.
  2. Modifica il ConfigMap cilium-config aggiungendo o modificando la chiave labels nella sezione data. Ad esempio, per impedire l'utilizzo delle etichette denominate uuid per la generazione di identità:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: cilium-config
      namespace: kube-system
    data:
      # ... other existing keys
      labels: "!uuid"
      # ... other existing keys
    
  3. Riavvia anet-operator sul control plane eseguendo l'upgrade del control plane alla stessa versione in esecuzione. In questo modo, l'operatore viene forzato a riavviare e ricaricare la configurazione:

    gcloud container clusters upgrade CLUSTER_NAME \
        --location CLUSTER_LOCATION \
        --project PROJECT_ID \
        --cluster-version $(gcloud container clusters describe CLUSTER_NAME --location CLUSTER_LOCATION --project PROJECT_ID --format="value(currentMasterVersion)") \
        --master
    
  4. Dopo il riavvio del control plane, riavvia il DaemonSet anetd per assicurarti che anche gli agenti dei nodi rilevino le modifiche richieste:

    kubectl rollout restart daemonset anetd -n kube-system
    

Problemi di connettività intermittente relativi a conflitti di intervallo NodePort nei cluster GKE Dataplane V2

Nei cluster GKE Dataplane V2, possono verificarsi problemi di connettività intermittenti per il traffico mascherato o con l'utilizzo di porte effimere. Questi problemi sono dovuti a potenziali conflitti di porta con l'intervallo NodePort riservato e si verificano in genere nei seguenti scenari:

  • ip-masq-agent personalizzato:se utilizzi un ip-masq-agent personalizzato (versione 2.10 o successive), in cui il cluster dispone di servizi NodePort o Load Balancer, potresti riscontrare problemi di connettività intermittenti a causa del conflitto con l'intervallo NodePort. A partire dalla versione 2.10, ip-masq-agent ha l'argomento --random-fully implementato internamente per impostazione predefinita. Per risolvere il problema, imposta in modo esplicito --random-fully=false (applicabile dalla versione 2.11) negli argomenti della configurazione di ip-masq-agent. Per i dettagli di configurazione, vedi Configurazione di un agente di mascheramento IP nei cluster Standard.

  • Sovrapposizione dell'intervallo di porte effimere:se l'intervallo di porte effimere definito da net.ipv4.ip_local_port_range sui nodi GKE si sovrappone all'intervallo NodePort (30000-32767), possono verificarsi anche problemi di connettività. Per evitare questo problema, assicurati che i due intervalli non si sovrappongano.

Rivedi la configurazione di ip-masq-agent e le impostazioni dell'intervallo di porte effimere per assicurarti che non siano in conflitto con l'intervallo di NodePort. Se riscontri problemi di connettività intermittenti, valuta queste potenziali cause e modifica la configurazione di conseguenza.

Problemi di connettività con hostPort nei cluster GKE Dataplane V2

Versioni GKE interessate: tutte le versioni disponibili

Nei cluster che utilizzano GKE Dataplane V2, potresti riscontrare errori di connettività quando il traffico ha come target l'IP:Porta di un nodo, dove porta è hostPort definito nel pod. Questi problemi si verificano in due scenari principali:

  • Nodi con hostPort dietro un bilanciatore del carico di rete passthrough:

    hostPort collega un pod alla porta di un nodo specifico e un bilanciatore del carico di rete passthrough distribuisce il traffico su tutti i nodi. Quando esponi i pod a internet utilizzando hostPort e un bilanciatore del carico di rete passthrough, il bilanciatore del carico potrebbe inviare traffico a un nodo in cui il pod non è in esecuzione, causando errori di connessione. Ciò è dovuto a una limitazione nota in GKE Dataplane V2, in cui il traffico del bilanciatore del carico di rete passthrough non viene inoltrato in modo coerente ai pod hostPort.

    Soluzione alternativa:quando esponi hostPort di un pod sul nodo con un bilanciatore del carico di rete passthrough, specifica l'indirizzo IP interno o esterno del bilanciatore del carico di rete nel campo hostIP del pod.

    ports:
    - containerPort: 62000
      hostPort: 62000
      protocol: TCP
      hostIP: 35.232.62.64
    - containerPort: 60000
      hostPort: 60000
      protocol: TCP
      hostIP: 35.232.62.64
      # Assuming 35.232.62.64 is the external IP address of a passthrough Network Load Balancer.
    
  • hostPort conflitto con l'intervallo NodePort riservato:

    Se hostPort di un pod è in conflitto con l'intervallo NodePort riservato (30000-32767), Cilium potrebbe non riuscire a inoltrare il traffico al pod. Questo comportamento si verifica perché Cilium gestisce le funzionalità hostPort, sostituendo il metodo Portmap precedente. Si tratta di un comportamento previsto per Cilium e menzionato nella documentazione pubblica.

Non prevediamo di risolvere queste limitazioni nelle versioni successive. La causa principale di questi problemi è correlata al comportamento di Cilium ed esula dal controllo diretto di GKE.

Consiglio:ti consigliamo di eseguire la migrazione ai servizi NodePort anziché a hostPort per una maggiore affidabilità. NodePort I servizi forniscono funzionalità simili.

Gli intervalli di porte per i criteri di rete non vengono applicati

Versioni di GKE interessate: precedenti alla 1.32

Se specifichi il campo endPort in un oggetto NetworkPolicy su un cluster in cui è abilitato GKE Dataplane V2 e viene eseguita una versione di GKE precedente alla 1.32, Kubernetes ignora il campo.

L'API NetworkPolicy Kubernetes ti consente di specificare un intervallo di porte in cui Kubernetes applica il criterio di rete. Questa API è supportata nei cluster con criteri di rete Calico e nei cluster con GKE Dataplane V2 che eseguono GKE versione 1.32 o successive. L'API non è supportata nei cluster GKE Dataplane V2 che eseguono versioni precedenti alla 1.32.

Per verificare il comportamento degli oggetti NetworkPolicy, rileggili dopo averli scritti sul server API. Se l'oggetto contiene ancora il campo endPort, Kubernetes applica la funzionalità. Se il campo endPort non è presente, Kubernetes non applica la funzionalità. L'oggetto archiviato nel server API è la fonte di riferimento per la policy di rete.

Per saperne di più, consulta KEP-2079: Network Policy to support Port Ranges.

Versioni corrette

Per risolvere il problema, esegui l'upgrade del cluster alla versione 1.32 o successive di GKE.

Nodi nello stato NodeNotReady a causa dell'errore containerID mancante

Quando i cluster vengono aggiornati alla versione GKE 1.35.1-gke.1616000 e successive, i nodi potrebbero entrare immediatamente in uno stato NodeNotReady se sono abilitati sia GKE Dataplane V2 che Cloud Service Mesh.

Causa

A partire dalla versione 1.35.1-gke.1616000 di GKE, i cluster GKE Dataplane V2 utilizzano la versione 1.1.0 di CNI nei file di configurazione CNI. Questa modifica richiede che anche i plug-in CNI downstream, come Google Managed Istio, supportino la versione 1.1.0 di CNI. A causa di un ritardo nell'implementazione di Managed Istio, alcuni cluster non hanno ancora ricevuto la versione compatibile (1.23), il che ha comportato l'errore di inizializzazione.

Sintomi

I nodi interessati vengono immediatamente visualizzati come NodeNotReady. Nel log di containerd viene visualizzato il seguente messaggio di errore:

NetworkPluginNotReady message:Network plugin returns error: missing containerID

Soluzione alternativa

Per risolvere il problema, esegui il downgrade del cluster interessato a una versione di GKE precedente alla 1.35.1-gke.1616000.

Interferenza dei programmi eBPF personalizzati

GKE utilizza i programmi eBPF per gestire il networking per GKE Dataplane V2. Se esegui il deployment di programmi eBPF personalizzati sulle interfacce di rete dei nodi gestiti da GKE, questi programmi possono interferire con i programmi eBPF gestiti da GKE e causare problemi di networking.

GKE non supporta i programmi eBPF personalizzati collegati alle seguenti interfacce di rete:

  • eth*
  • ens4
  • lo
  • cilium*
  • gke*
  • veth*

La presenza di programmi eBPF personalizzati su queste interfacce può interferire con i programmi installati dall'agente GKE Dataplane V2 anetd, il che può interrompere il networking del cluster. Ti consigliamo di rimuovere dal cluster eventuali programmi o carichi di lavoro eBPF personalizzati che inseriscono questi programmi.

Scopri i programmi eBPF personalizzati

Per rilevare i programmi eBPF personalizzati in esecuzione sui nodi del cluster, puoi creare un DaemonSet configurato con l'impostazione hostNetwork: true, che utilizza bpftool per eseguire query su questi programmi eBPF:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: bpftool-logger
  labels:
    app: bpftool-logger
spec:
  selector:
    matchLabels:
      app: bpftool-logger
  template:
    metadata:
      labels:
        app: bpftool-logger
    spec:
      hostPID: true
      hostNetwork: true
      containers:
      - name: bpftool
        image: ubuntu:22.04
        securityContext:
          privileged: true
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        command:
        - /bin/bash
        - -c
        - |
          echo "Installing dependencies..."
          apt-get update -y > /dev/null 2>&1
          apt-get install -y curl tar > /dev/null 2>&1

          echo "Downloading and setting up bpftool..."
          curl -sL https://github.com/libbpf/bpftool/releases/download/v7.7.0/bpftool-v7.7.0-amd64.tar.gz | tar xz
          chmod +x bpftool
          mv bpftool /usr/local/bin/

          echo "========== $(date) | Node: ${NODE_NAME} =========="
          bpftool net | grep -E '^(eth|ens4|lo|cilium|gke|veth)' | grep -v ' cil_'
          sleep infinity
  1. Salva il manifest come ebpf-discovery.yaml e applica il DaemonSet:

    kubectl apply -f ebpf-discovery.yaml
    
  2. Attendi che i pod siano in esecuzione:

    kubectl rollout status ds/bpftool-logger
    
  3. Controlla i log dei pod per scoprire i programmi eBPF:

    kubectl logs -l app=bpftool-logger
    
  4. Al termine, elimina il DaemonSet:

    kubectl delete -f ebpf-discovery.yaml
    

Passaggi successivi