Configurare il reindirizzamento dei servizi

Questa pagina mostra come configurare il reindirizzamento dei servizi per i pod.

Per capire come funziona il reindirizzamento dei servizi, consulta Come funziona il reindirizzamento dei servizi.

Requisiti

  • GKE versione 1.30 o successive.

Limitazioni

  • Una ServiceFunctionChain può avere al massimo una funzione di servizio.
  • Ti consigliamo di utilizzare un massimo di 100 nodi più 10 coppie ServiceFunctionChain e TrafficSelector.
  • Il reindirizzamento dei servizi GKE è disponibile solo con i nodi che eseguono l'immagine del nodo Container-Optimized OS.
  • Il reindirizzamento dei servizi GKE supporta solo gli indirizzi IP di uscita e di destinazione.
  • Il reindirizzamento dei servizi non gestisce i conflitti che si verificano quando più selettori di traffico con lunghezze di prefisso identiche vengono applicati allo stesso soggetto. Per evitare conflitti, progetta in modo proattivo i selettori di traffico con intervalli di indirizzi IP non sovrapposti e criteri di selezione chiaramente definiti.

Implementare il reindirizzamento dei servizi

Il reindirizzamento dei servizi GKE ti consente di personalizzare e controllare il flusso del traffico di rete all'interno di un cluster. Questa sezione mostra come implementare il reindirizzamento dei servizi utilizzando un esempio di gateway web.

Considera un caso d'uso in cui vuoi creare un gateway web che protegga il traffico dai dispositivi client degli utenti finali a internet. Un terminatore VPN attira il traffico nel gateway gestito utilizzando un tunnel sicuro. Il traffico degli utenti finali viene reindirizzato al firewall e poi al proxy. Il proxy esegue la Network Address Translation dell'origine (SNAT) sul traffico, maschera l'indirizzo di origine originale e lo invia a internet.

Per implementare il reindirizzamento dei servizi GKE:

  1. Crea un VPC con MTU di 8896.
  2. Crea un cluster GKE.
  3. Crea i pod e il servizio della funzione di servizio.
  4. Crea ServiceFunctionChain.
  5. Crea la risorsa TrafficSelector che fa riferimento a ServiceFunctionChain.

Prima di iniziare

Prima di iniziare, assicurati di aver eseguito le seguenti attività:

  • Abilita l'API Google Kubernetes Engine.
  • Abilita l'API Google Kubernetes Engine
  • Se vuoi 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 gcloud components update comando. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.

Preparare un VPC

Prepara un VPC. Il reindirizzamento dei servizi utilizza l'incapsulamento per reindirizzare il traffico alle funzioni di servizio appropriate. L'incapsulamento comporta l'aggiunta di intestazioni aggiuntive a ogni pacchetto, il che aumenta le dimensioni del pacchetto. Il reindirizzamento dei servizi non richiede una configurazione speciale nei VPC. Durante la preparazione del VPC, ti consigliamo di tenere conto del sovraccarico di incapsulamento quando decidi le dimensioni MTU. Per ulteriori informazioni, consulta Rete VPC con un MTU specificato.

Il comando seguente imposta le dimensioni MTU nel VPC:

gcloud compute networks create VPC_NETWORK_NAME --mtu=8896

Sostituisci VPC_NETWORK_NAME con il nome della rete VPC che contiene la subnet.

Creare un cluster GKE

Per abilitare le funzionalità avanzate di routing di rete e gestione degli indirizzi IP necessarie per implementare il reindirizzamento dei servizi su GKE, crea un cluster GKE con GKE Dataplane V2 abilitato come segue:

gcloud container clusters create CLUSTER_NAME \
    --network VPC_NAME \
    --release-channel RELEASE_CHANNEL \
    --cluster-version CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias

Sostituisci quanto segue:

  • CLUSTER_NAME: il nome del cluster.
  • VPC_NAME: il nome del VPC a cui vuoi associare il cluster.
  • RELEASE_CHANNEL: il nome del canale di rilascio.
  • VERSION: la versione di GKE, che deve essere 1.30 o successive. Puoi anche utilizzare il flag --release-channel per selezionare un canale di rilascio. Il canale di rilascio deve avere una versione predefinita 1.30 o successive.

Creare pod ServiceFunction

Per stabilire la catena di servizi, esegui il deployment del pod del terminatore VPN e dei pod della funzione di servizio necessari all'interno del cluster. I pod incapsulano le applicazioni containerizzate che eseguono le funzioni di rete.

Il pod del terminatore VPN è spesso la prima funzione di servizio nella catena, che termina il traffico che entra nel cluster tramite la VPN. Quindi indirizza le altre funzioni di servizio, come firewall e bilanciamento del carico, per un'ulteriore elaborazione prima di raggiungere la destinazione finale.

Il seguente file di configurazione di esempio definisce i tre componenti essenziali per la gestione del traffico di rete all'interno di un cluster:

  • Pod VPN: stabilisce un endpoint di rete privata virtuale (VPN) all'interno del cluster, che consente una comunicazione sicura e criptata tra il cluster e le reti esterne.
  • Deployment del firewall: esegue il deployment di più repliche di un pod firewall, che forniscono sicurezza e bilanciamento del carico.
  • DaemonSet proxy: esegue il deployment di un pod proxy su ogni nodo del cluster, il che contribuisce a garantire che il traffico di rete possa essere elaborato localmente prima di essere inoltrato ad altri servizi come il firewall.

Salva il seguente manifest di esempio come service_function.yaml:

apiVersion: v1
kind: Pod
  name: vpn
  namespace: vpn
  labels:
    app: vpn
spec:
  containers:
  -   name: vpn
    image: openvpn
    ports:
    -   containerPort: 51820
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firewall
  namespace: firewall
spec:
  replicas: 3
  selector:
    matchLabels:
      app: firewall
  template:
    metadata:
      labels:
        app: firewall
    spec:
      containers:
      -   name: firewall
        image: firewall
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: proxy
  namespace: proxy
spec:
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
      -   name: proxy
        image: proxy

Applica il manifest:

kubectl apply -f service_function.yaml

Creare ServiceFunctionChains

Per definire una sequenza di funzioni di rete per il traffico, crea una pipeline in cui ogni funzione, come firewall, proxy e bilanciamento del carico, esegue la sua attività specifica prima di passare il traffico alla successiva.

Salva il seguente manifest di esempio come ServiceFunctionChain.yaml:

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  sessionAffinity:
    clientIpNoDestination:
      timeoutSeconds: 3600 # 1hr
  serviceFunctions:
  -   name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewall
---
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: proxy
spec:
  sessionAffinity:
    clientIpNoDestination: {}
  serviceFunctions:
  -   name: proxy
    namespace: proxy
    podSelector:
      matchLabels:
        app: proxy

Applica il manifest:

kubectl apply -f ServiceFunctionChain.yaml

Le funzioni di servizio sono definite in linea all'interno di ServiceFunctionChain utilizzando il campo serviceFunctions. Una funzione di servizio è un selettore di endpoint.

Creare la risorsa TrafficSelector

Per definire dove e quale traffico viene selezionato per il reindirizzamento dei servizi, crea la risorsa TrafficSelector che fa riferimento a ServiceFunctionChains da applicare al traffico scelto.

Salva il seguente manifest di esempio come TrafficSelector.yaml:

apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: vpn-to-firewall
spec:
  serviceFunctionChain: firewall
  subject:
    pods:
      namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: vpn
      podSelector:
        matchLabels:
          app: vpn
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP
---
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: firewall-to-proxy
spec:
  serviceFunctionChain: proxy
  subject:
    pods:
      namespaceSelector:
        kubernetes.io/metadata.name: firewall
      podSelector:
        app: firewall
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP

Applica il manifest:

kubectl apply -f TrafficSelector.yaml

Risolvere i problemi relativi al reindirizzamento dei servizi

Questa sezione mostra come risolvere i problemi relativi al reindirizzamento dei servizi GKE.

Il traffico di rete non scorre

Puoi eseguire le seguenti azioni per eseguire il debug del problema:

Passaggio 1: verifica che servicePathId sia impostato su ServiceFunctionChain

Verifica che servicePathId sia impostato su ServiceFunctionChain. A ogni oggetto ServiceFunctionChain viene assegnato un servicePathId univoco, come mostrato nell'esempio seguente:

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  serviceFunctions:
  - name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewal
status:
  servicePathId: 1

Passaggio 2: verifica che venga creato un servizio Kubernetes per ogni funzione di servizio

Per ogni funzione di servizio viene creato automaticamente un servizio ClusterIP. Puoi visualizzare l'elenco dei servizi utilizzando kubectl:

kubectl get svc -A -l networking.gke.io/managed-by=service-steering-controller.gke.io

Passaggio 3: verifica che per ogni funzione di servizio venga creata una voce della mappa bpf su ogni nodo per archiviare l'indirizzo IP del servizio

Per ogni funzione di servizio, viene creata una voce della mappa bpf su ogni nodo per archiviare l'indirizzo IP del servizio.

Recupera il nome del pod anetd:

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

Registra il nome del pod simile a anetd.

Esegui questo comando:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcpath list

Sostituisci ANETD-POD-NAME con il nome del pod anetd.

L'output è simile al seguente:

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

Passaggio 4: verifica che le voci della mappa bpf vengano create nella mappa sfcselect

Su un nodo, se sono presenti pod selezionati da un TrafficSelector, vengono create voci della mappa bpf nella mappa sfcselect. L'esempio seguente mostra che il traffico TCP/UDP da qualsiasi porta dell'endpoint (pod) 3783 all'indirizzo IP di destinazione 10.0.2.12 viene indirizzato a un ServiceFunctionChain.

Esegui questo comando:

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcselect list

Sostituisci ANETD-POD-NAME con il nome effettivo del pod anetd nel cluster.

L'output è simile al seguente:

SELECTOR                            PATH
3783, egress, 0/TCP, 10.0.2.12/32   /32 (1, 1)
3783, egress, 0/UDP, 10.0.2.12/32   /32 (1, 1)

Passaggio 5: utilizza tcpdump sulla porta 7081 per acquisire e analizzare il traffico di rete

Il reindirizzamento dei servizi esegue l'incapsulamento Geneve sulla porta UDP 7081. Puoi utilizzare tcpdump sui nodi pertinenti per analizzare il flusso di traffico e individuare dove potrebbe verificarsi il problema.

Passaggi successivi