Questo documento spiega come configurare i pod in Google Kubernetes Engine (GKE) con più interfacce di rete utilizzando Multus CNI, il plug-in CNI IPVLAN e il plug-in IPAM Whereabouts.
Il plug-in CNI IPVLAN fornisce la connettività di livello 2 per le interfacce Pod aggiuntive e il plug-in IPAM Whereabouts assegna dinamicamente gli indirizzi IP.
Questa configurazione consente configurazioni di rete avanzate, ad esempio la separazione del traffico del piano di controllo e del piano dati 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 di rete per la loro organizzazione. Per scoprire di più sui ruoli comuni e sulle attività di esempio a cui facciamo riferimento nei contenuti, consulta la pagina Ruoli utente e attività comuni di GKE. Google Cloud
Prima di leggere questo documento, assicurati di avere familiarità con 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 chiave. I casi d'uso principali per la configurazione di Multus con IPVLAN in modalità di livello 2 riguardano la segmentazione di rete che richiede l'adiacenza di livello 2:
- Isolamento del traffico:isola diversi tipi di traffico per migliorare la sicurezza e le prestazioni. Ad esempio, puoi separare il traffico di gestione sensibile dal traffico di dati delle applicazioni.
- Separazione del piano di controllo e del piano dati:dedica l'interfaccia di rete principale al traffico del piano di controllo e indirizza il traffico del piano dati a velocità effettiva elevata tramite un'interfaccia IPVLAN secondaria.
- Adiacenza di livello 2:soddisfa i requisiti per le applicazioni che necessitano di connettività diretta di livello 2 tra i pod sulla stessa rete secondaria.
Limitazioni
I pod configurati con 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.
Come funziona Multus con IPVLAN e Whereabouts
Multus è un meta-plug-in CNI che consente ai pod di connettersi 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 di 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 CNI IPVLAN in modalità Layer 2 per ogniNetworkAttachmentDefinitionche specifichi nelle annotazioni di un pod. Questa configurazione fornisce connettività di livello 2 a una rete VPC secondaria. - Gestione indirizzi IP (IPAM): configuri il plug-in IPAM Whereabouts
all'interno di
NetworkAttachmentDefinition. Il plug-in Whereabouts IPAM assegna dinamicamente 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 posiziona 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 nodil che hanno configurato l'interfaccia di rete secondaria necessaria. Questa
procedura di identificazione del nodo garantisce che lo scheduler pianifichi il pod su un
nodo che può connettersi alla rete aggiuntiva e ricevere un indirizzo IP dall'intervallo
specificato.
Le sezioni seguenti ti guidano nella configurazione dei plug-in Multus con IPVLAN e Whereabouts sul tuo cluster GKE.
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
- 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 comando
gcloud components update. 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 che esegue la versione 1.28 o successive con Dataplane V2, IP alias e networking multiplo abilitati. Per scoprire come fare, consulta Configurare il supporto di più reti per i pod. L'attivazione del networking multiplo attiva 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 v4.2.1) per la compatibilità.
Configura VPC
Per configurare Virtual Private Cloud (VPC) da utilizzare con Multus, inclusa la creazione di una subnet per il networking dei nodi e 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 nodo aggiuntiva e un intervallo secondario per le interfacce pod aggiuntive.
Crea 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 tuo cluster GKE. Devi utilizzare la versione 1.28 o successive.
L'abilitazione del networking multiplo ti consente di creare pool di nodi con più interfacce di rete, come richiesto da Multus CNI.
Crea 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 tuo 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 secondari 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 indirizzi IP da SECONDARY_RANGE_NAME.
Per ulteriori informazioni sulla creazione di cluster GKE con funzionalità multi-rete, consulta Configurare il supporto multi-rete per i pod.
Applica 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
Dopodiché, applica il manifest al cluster:
kubectl apply -f multus-manifest.yaml
Crea 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 del tuoNetworkAttachmentDefinition.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 corrisponde all'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 al
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 del 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.
Verifica 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 tuo 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 primario sueth0e10.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.