Questo documento spiega come configurare i pod in Google Kubernetes Engine (GKE) con più interfacce di rete utilizzando Multus CNI, il plug-in IPVLAN CNI e il plug-in Whereabouts IPAM.
Il plug-in IPVLAN CNI fornisce connettività di livello 2 per le interfacce dei pod aggiuntive, mentre il plug-in Whereabouts IPAM assegna dinamicamente gli indirizzi IP.
Questa configurazione consente configurazioni di rete avanzate, come la separazione del traffico del control plane e del data plane per una maggiore segmentazione e isolamento della rete.
Questo documento è destinato agli architetti cloud e agli specialisti di networking che progettano e realizzano l'architettura della rete per la loro organizzazione. Per saperne di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei Google Cloud contenuti, consulta Ruoli e attività comuni degli utenti GKE.
Prima di leggere questo documento, assicurati di conoscere i seguenti concetti:
- Networking di GKE.
- Networking Kubernetes.
- Container Network Interface (CNI).
- IPVLAN.
- Gestione degli indirizzi IP (IPAM).
Vantaggi dell'utilizzo di Multus con IPVLAN
La configurazione dei pod con più interfacce di rete utilizzando questa soluzione offre diversi vantaggi principali. I principali casi d'uso per la configurazione di Multus con IPVLAN in modalità di livello 2 riguardano la segmentazione della rete che richiede l'adiacenza di livello 2:
- Isolamento del traffico: isola diversi tipi di traffico per una maggiore sicurezza e prestazioni. Ad esempio, puoi separare il traffico di gestione sensibile dal traffico di dati delle applicazioni.
- Separazione del control plane e del data plane: dedica l'interfaccia di rete principale al traffico del control plane, mentre indirizza il traffico del data plane a elevata velocità effettiva tramite un'interfaccia IPVLAN secondaria.
- Adiacenza di livello 2: soddisfa i requisiti delle applicazioni che richiedono la connettività diretta di livello 2 tra i pod sulla stessa rete secondaria.
Limitazioni
Multus con IPVLAN e Whereabouts presenta le seguenti limitazioni:
- I pod configurati con le interfacce Multus non possono utilizzare contemporaneamente le funzionalità di networking multiplo integrate di GKE. La configurazione di rete di un pod deve utilizzare Multus o il networking multiplo integrato del cluster.
- Multus con IPVLAN e Whereabouts richiede la risoluzione ARP di livello 2 intra-pod per funzionare correttamente.
- Per impostazione predefinita, le subnet VPC non consentono la risoluzione ARP sulle interfacce secondarie delle VM di Compute Engine. Per consentire questa risoluzione ARP, puoi registrarti all'anteprima privata della funzionalità
resolve-subnet-maskaprendo una richiesta di assistenza.
Come funziona Multus con IPVLAN e Whereabouts
Multus è un meta-plug-in CNI che consente ai pod di collegarsi a più reti. Multus funge da dispatcher, chiamando altri plug-in CNI per configurare le interfacce di rete in base alle risorse NetworkAttachmentDefinition. Definisci ogni rete aggiuntiva utilizzando un NetworkAttachmentDefinition, che specifica quale plug-in CNI (ad esempio IPVLAN) e quale plug-in IPAM (ad esempio Whereabouts) utilizzare per quella rete.
Il seguente diagramma illustra l'architettura Multus con i plug-in IPVLAN e Whereabouts.Il plug-in Whereabouts funziona con Multus e IPVLAN per gestire la gestione degli indirizzi IP (IPAM) per le interfacce di rete aggiuntive dei pod.
Questo diagramma mostra due nodi, ognuno con un pod. Ogni pod ha un'interfaccia principale e un'interfaccia aggiuntiva. Le due interfacce principali si connettono a una scheda di interfaccia di rete condivisa, mentre le due interfacce aggiuntive si connettono a una scheda di interfaccia di rete condivisa diversa.
Quando utilizzi Multus con IPVLAN e Whereabouts su GKE, i pod in genere hanno la seguente configurazione dell'interfaccia:
- Interfaccia principale (
eth0): GKE Dataplane V2 gestisce questa interfaccia, fornendo la connettività predefinita del cluster. - Interfacce aggiuntive (
net1e così via): Multus gestisce queste interfacce. Multus richiama il plug-in IPVLAN CNI in modalità di livello 2 per ogniNetworkAttachmentDefinitionspecificato nelle annotazioni di un pod. Questa configurazione fornisce la connettività di livello 2 a una rete VPC secondaria. - Gestione degli indirizzi IP (IPAM): configura il plug-in Whereabouts IPAM
all'interno di
NetworkAttachmentDefinition. Il plug-in Whereabouts IPAM assegna dinamicamente gli indirizzi IP alle interfacce IPVLAN aggiuntive da un intervallo predefinito.
Pianificazione dei pod con più reti
Quando crei un pod e specifichi un NetworkAttachmentDefinition nelle relative annotazioni, lo scheduler GKE inserisce il pod solo su un nodo in grado di soddisfare i requisiti di rete. Lo scheduler identifica i nodi all'interno di un pool di nodi che hanno l'interfaccia di rete secondaria necessaria configurata. Questo processo di identificazione dei nodi aiuta a garantire che lo scheduler pianifichi il pod su un nodo in grado di connettersi alla rete aggiuntiva e ricevere un indirizzo IP dall'intervallo specificato.
Le sezioni seguenti ti guideranno nella configurazione dei plug-in Multus con IPVLAN e Whereabouts nel cluster GKE.
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 updatecomando. Le versioni precedenti di gcloud CLI potrebbero non supportare l'esecuzione dei comandi in questo documento.
- Installa lo strumento a riga di comando
kubectl. - Configura un cluster GKE con la versione 1.28 o successive con Dataplane V2, IP alias e networking multiplo abilitati. Per scoprire come, consulta Configurare il supporto di più reti per i pod. L'abilitazione del networking multiplo abilita anche le funzionalità Multi-IP-Subnet e Persistent-IP HA Policy, che eliminano la necessità di configurare manualmente la connettività tra i nodi.
- Utilizza una versione di Multus CNI convalidata da GKE (ad esempio la versione 4.2.1) per la compatibilità.
Configurare VPC
Per configurare Virtual Private Cloud (VPC) da utilizzare con Multus, inclusa la creazione di una subnet per il networking dei nodi e di intervalli secondari per il networking dei pod, completa i seguenti passaggi:
Crea un nuovo VPC o utilizzane uno esistente:
gcloud compute networks create VPC_NAME \ --subnet-mode=customSostituisci
VPC_NAMEcon il nome del VPC.Crea una nuova subnet all'interno di questo VPC:
gcloud compute networks subnets create SUBNET_NAME \ --range=PRIMARY_RANGE \ --network=VPC_NAME \ --region=REGION \ --secondary-range=SECONDARY_RANGE_NAME=SECONDARY_RANGE_CIDRSostituisci quanto segue:
SUBNET_NAME: il nome della nuova subnet.PRIMARY_RANGE: l'intervallo CIDR primario per la subnet, ad esempio10.0.1.0/24. Questo comando utilizza questo intervallo per le interfacce dei nodi.VPC_NAME: il nome del VPC.REGION: la regione della subnet, ad esempious-central1.SECONDARY_RANGE_NAME: il nome dell'intervallo di indirizzi IP secondario per i pod nella subnet.SECONDARY_RANGE_CIDR: l'intervallo CIDR secondario per i pod, ad esempio172.16.1.0/24. Le interfacce aggiuntive sui pod utilizzano questo intervallo.
Questo comando crea una subnet con un intervallo CIDR primario per un'interfaccia di nodo aggiuntiva e un intervallo secondario per le interfacce dei pod aggiuntive.
Creare un cluster GKE Standard
Crea un cluster GKE Standard con il networking multiplo abilitato:
gcloud container clusters create CLUSTER_NAME \
--cluster-version=CLUSTER_VERSION \
--enable-dataplane-v2 \
--enable-ip-alias \
--enable-multi-networking
Sostituisci quanto segue:
CLUSTER_NAME: il nome del nuovo cluster.CLUSTER_VERSION: la versione del cluster GKE. Devi utilizzare la versione 1.28 o successive.
L'abilitazione del networking multiplo consente di creare node pool con più interfacce di rete, che Multus CNI richiede.
Creare un pool di nodi GKE Standard
Crea un pool di nodi GKE Standard connesso a reti VPC aggiuntive:
gcloud container node-pools create NODEPOOL_NAME \
--cluster CLUSTER_NAME \
--zone "ZONE" \
--additional-node-network network=VPC_NAME,subnetwork=SUBNET_NAME \
--additional-pod-network subnetwork=SUBNET_NAME,pod-ipv4-range=SECONDARY_RANGE_NAME,max-pods-per-node=8
Sostituisci quanto segue:
NODEPOOL_NAME: il nome del nuovo pool di nodi.CLUSTER_NAME: il nome del cluster.ZONE: la zona del pool di nodi, ad esempious-central1-c.VPC_NAME: il nome del VPC aggiuntivo.SUBNET_NAME: il nome della subnet.SECONDARY_RANGE_NAME: il nome dell'intervallo di indirizzi IP secondario per i pod nella subnet.
Questo comando crea un pool di nodi in cui i nodi hanno un'interfaccia di rete aggiuntiva in SUBNET_NAME, e i pod su questi nodi possono utilizzare gli indirizzi IP di SECONDARY_RANGE_NAME.
Per ulteriori informazioni sulla creazione di cluster GKE con funzionalità di networking multiplo, consulta Configurare il supporto di più reti per i pod.
Applicare il deployment di Multus
Per abilitare più interfacce di rete per i pod, installa il plug-in Multus CNI. Salva il seguente manifest, che include il DaemonSet e la definizione di risorsa personalizzata (CRD) richiesti, come multus-manifest.yaml:
apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: ippools.whereabouts.cni.cncf.io spec: group: whereabouts.cni.cncf.io names: kind: IPPool listKind: IPPoolList plural: ippools singular: ippool scope: Namespaced versions: - name: v1alpha1 schema: openAPIV3Schema: description: IPPool is the Schema for the ippools API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' type: string metadata: type: object spec: description: IPPoolSpec defines the desired state of IPPool properties: allocations: additionalProperties: description: IPAllocation represents metadata about the pod/container owner of a specific IP properties: id: type: string podref: type: string required: - id type: object description: Allocations is the set of allocated IPs for the given range. Its indices are a direct mapping to the IP with the same index/offset for the pools range. type: object range: description: Range is a RFC 4632/4291-style string that represents an IP address and prefix length in CIDR notation type: string required: - allocations - range type: object type: object served: true storage: true status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.4.1 name: overlappingrangeipreservations.whereabouts.cni.cncf.io spec: group: whereabouts.cni.cncf.io names: kind: OverlappingRangeIPReservation listKind: OverlappingRangeIPReservationList plural: overlappingrangeipreservations singular: overlappingrangeipreservation scope: Namespaced versions: - name: v1alpha1 schema: openAPIV3Schema: description: OverlappingRangeIPReservation is the Schema for the OverlappingRangeIPReservations API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object spec: description: OverlappingRangeIPReservationSpec defines the desired state of OverlappingRangeIPReservation properties: containerid: type: string podref: type: string required: - containerid type: object required: - spec type: object served: true storage: true status: acceptedNames: kind: "" plural: "" conditions: [] storedVersions: [] --- kind: ConfigMap apiVersion: v1 metadata: name: multus-cni-config namespace: kube-system labels: app: gke-multinet data: cni-conf.json: | { "name": "multus-cni-network", "type": "multus", "confDir": "/etc/cni/net.d", "namespaceIsolation": true, "logLevel": "verbose", "logFile": "/var/log/multus.log", "kubeconfig": "/var/lib/kubelet/kubeconfig", "clusterNetwork": "gke-pod-network" } --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: network-attachment-definitions.k8s.cni.cncf.io spec: group: k8s.cni.cncf.io scope: Namespaced names: plural: network-attachment-definitions singular: network-attachment-definition kind: NetworkAttachmentDefinition shortNames: - net-attach-def versions: - name: v1 served: true storage: true schema: openAPIV3Schema: description: 'NetworkAttachmentDefinition is a CRD schema specified by the Network Plumbing Working Group to express the intent for attaching pods to one or more logical or physical networks. More information available at: https://github.com/k8snetworkplumbingwg/multi-net-spec' type: object properties: apiVersion: description: 'APIVersion defines the versioned schema of this represen tation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object spec: description: 'NetworkAttachmentDefinition spec defines the desired state of a network attachment' type: object properties: config: description: 'NetworkAttachmentDefinition config is a JSON-formatted CNI configuration' type: string --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: multus-role rules: - apiGroups: ["k8s.cni.cncf.io"] resources: - '*' verbs: - '*' --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: whereabouts rules: - apiGroups: - whereabouts.cni.cncf.io resources: - ippools - overlappingrangeipreservations verbs: - get - list - watch - create - update - patch - delete - apiGroups: - coordination.k8s.io resources: - leases verbs: - create - apiGroups: - coordination.k8s.io resources: - leases resourceNames: - whereabouts verbs: - '*' - apiGroups: [""] resources: - pods verbs: - list - get --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: multus-role-binding subjects: - kind: Group name: system:nodes roleRef: kind: ClusterRole name: multus-role apiGroup: rbac.authorization.k8s.io --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: whereabouts-role-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: whereabouts subjects: - kind: ServiceAccount name: whereabouts-sa namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: whereabouts-sa namespace: kube-system --- apiVersion: apps/v1 kind: DaemonSet metadata: name: gke-multinet namespace: kube-system labels: app: gke-multinet spec: selector: matchLabels: app: gke-multinet template: metadata: labels: app: gke-multinet spec: priorityClassName: system-node-critical hostNetwork: true tolerations: - operator: Exists serviceAccountName: whereabouts-sa containers: - name: whereabouts-gc command: [/ip-control-loop] args: - "--log-level=debug" - "--enable-pod-watch=false" - "--cron-schedule=* * * * *" image: gcr.io/gke-release/whereabouts:v0.7.0-gke.3@sha256:2bb8450a99d86c73b262f5ccd8c433d3e3abf17d36ee5c3bf1056a1fe479e8c2 env: - name: NODENAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName - name: WHEREABOUTS_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" initContainers: - name: install-multus-config image: gcr.io/gke-release/multus-cni:v4.2.1-gke.6@sha256:25b48b8dbbf6c78a10452836f52dee456514783565b70633a168a39e6d322310 args: - "--cni-conf-dir=/host/etc/cni/net.d" - "--multus-conf-file=/tmp/multus-conf/00-multus.conf" - "--multus-log-level=verbose" - "--multus-kubeconfig-file-host=/var/lib/kubelet/kubeconfig" - "--skip-multus-binary-copy=true" - "--skip-config-watch=true" resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: true volumeMounts: - name: cni mountPath: /host/etc/cni/net.d - name: multus-cfg mountPath: /tmp/multus-conf - name: install-whereabouts command: ["/bin/sh"] args: - -c - > SLEEP=false /install-cni.sh image: gcr.io/gke-release/whereabouts:v0.7.0-gke.3@sha256:2bb8450a99d86c73b262f5ccd8c433d3e3abf17d36ee5c3bf1056a1fe479e8c2 env: - name: NODENAME valueFrom: fieldRef: apiVersion: v1 fieldPath: spec.nodeName - name: WHEREABOUTS_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace resources: requests: cpu: "100m" memory: "50Mi" limits: cpu: "100m" memory: "50Mi" securityContext: privileged: true volumeMounts: - name: cni mountPath: /host/etc/cni/net.d - name: cnibin mountPath: /host/opt/cni/bin - name: install-binary image: gcr.io/gke-release/multus-cni:v4.2.1-gke.6@sha256:25b48b8dbbf6c78a10452836f52dee456514783565b70633a168a39e6d322310 command: ["/gkecmd"] args: - "-operation=copy" - "-cni-bin-dir=/host/opt/cni/bin" resources: requests: cpu: "10m" memory: "100Mi" limits: cpu: "10m" memory: "100Mi" securityContext: privileged: true volumeMounts: - name: cnibin mountPath: /host/opt/cni/bin volumes: - hostPath: path: /var/lib/kubelet/kubeconfig type: File name: kubelet-credentials - name: cni hostPath: path: /etc/cni/net.d type: DirectoryOrCreate - name: cnibin hostPath: path: /home/kubernetes/bin type: DirectoryOrCreate - name: multus-cfg configMap: name: multus-cni-config items: - key: cni-conf.json path: 00-multus.conf updateStrategy: rollingUpdate: maxUnavailable: 2 type: RollingUpdate
Quindi, applica il manifest al cluster:
kubectl apply -f multus-manifest.yaml
Creare un manifest NetworkAttachmentDefinition
Per consentire ai pod di connettersi a reti aggiuntive, crea un manifest NetworkAttachmentDefinition. Questo manifest definisce la modalità di connessione dei pod a una rete e specifica l'intervallo di indirizzi IP assegnato da un plug-in IPAM, ad esempio Whereabouts. Questo intervallo deve far parte della subnet che connette le interfacce di rete aggiuntive dei nodi.
Salva questo manifest come
nad.yaml. Questo manifest utilizza i plug-in IPVLAN e Whereabouts.apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: NAD_NAME spec: config: '{ "cniVersion": "0.3.1", "plugins": [ { "type": "ipvlan", "master": "eth1", "mode": "l2", "ipam": { "type": "whereabouts", "range": SECONDARY_RANGE_NAME } } ] }'Il manifest include i seguenti campi:
NAD_NAME: il nome diNetworkAttachmentDefinition.master: il nome dell'interfaccia di rete secondaria del nodo, che funge da interfacciamasterper IPVLAN. Su GKE, le interfacce di rete secondarie in genere iniziano coneth1e vengono denominate in sequenza. Per confermare il nome dell'interfaccia, connettiti a un nodo utilizzando SSH ed esegui il comandoip addr.range: l'intervallo di indirizzi IP per le interfacce dei pod, che è lo stesso dell'intervallo IPv4 secondario creato per i pod (SECONDARY_RANGE_NAME). Ad esempio,172.16.1.0/24.
Applica il manifest al cluster:
kubectl apply -f nad.yaml
Collegare i pod a reti aggiuntive
Per collegare un pod a una rete aggiuntiva, aggiungi l'annotazione k8s.v1.cni.cncf.io/networks al manifest del pod. Per più reti, fornisci un
elenco di nomi NetworkAttachmentDefinition separati da virgole nel seguente formato:
<namespace>/<nad-name>.
L'esempio seguente mostra un manifest del pod che si collega a NetworkAttachmentDefinition denominato NAD_NAME nello spazio dei nomi default:
apiVersion: v1
kind: Pod
metadata:
name: samplepod
annotations:
k8s.v1.cni.cncf.io/networks: default/NAD_NAME
spec:
containers:
- name: sample-container
image: nginx
Sostituisci NAD_NAME con il nome di NetworkAttachmentDefinition che hai creato.
Quando applichi questo manifest, Kubernetes crea il pod con un'interfaccia di rete aggiuntiva (net1) connessa alla rete specificata da NetworkAttachmentDefinition.
Verificare l'indirizzo IP aggiuntivo del pod
Per verificare che il pod riceva un indirizzo IP aggiuntivo dopo averlo collegato a una rete aggiuntiva, esamina le interfacce di rete all'interno del pod:
Per esaminare
samplepode verificare l'indirizzo IP aggiuntivo, utilizza il seguente comando:$kubectl describe pod PODNAMESostituisci
PODNAMEcon il nome del pod, ad esempiosamplepod.Esamina l'output. L'interfaccia
eth0ha l'indirizzo IP principale del pod. Il plug-in Whereabouts assegna l'indirizzo IP aggiuntivo a un'altra interfaccia, ad esempionet1.L'output è simile al seguente:
k8s.v1.cni.cncf.io/network-status: [{ "name": "gke-pod-network", "interface": "eth0", "ips": [ "10.104.3.4" ], "mac": "ea:e2:f6:ce:18:b5", "default": true, "dns": {}, "gateway": [ "\u003cnil\u003e" ] },{ "name": "default/my-nad", "interface": "net1", "ips": [ "10.200.1.1" ], "mac": "42:01:64:c8:c8:07", "dns": {} }] k8s.v1.cni.cncf.io/networks: default/my-nadIn questo esempio,
10.104.5.19è l'indirizzo IP principale sueth0, mentre10.200.1.1è l'indirizzo IP aggiuntivo sunet1.
Passaggi successivi
- Scopri di più su Multus CNI.
- Scopri di più su IPVLAN CNI.
- Scopri di più su Whereabouts IPAM.