In diesem Dokument wird beschrieben, wie Sie SR-IOV-Netzwerke (Single-Root Input/Output Virtualization) für Anthos-Cluster auf Bare-Metal einrichten. SR-IOV bietet E/A-Virtualisierung, um eine Netzwerkkarte (NIC) zu erstellen, verfügbar als Netzwerkgeräte im Linux-Kernel. So können Sie Netzwerkverbindungen verwalten und Pods zuweisen. Die Leistung wird verbessert, da Pakete direkt zwischen der NIC und dem Pod verschoben werden.
Nutzen Sie dieses Feature, wenn Sie ein schnelles Netzwerk für Ihre Pod-Arbeitslasten benötigen. Mit SR-IOV für Anthos-Cluster auf Bare-Metal können Sie die virtuellen Funktionen (VFs) auf den unterstützten Geräten Ihrer Clusterknoten konfigurieren. Sie können auch das spezifische Kernel-Modul angeben, das an die VFs gebunden werden soll.
Dieses Feature ist für Cluster verfügbar, auf denen Arbeitslasten ausgeführt werden, wie z. B. Hybrid-Cluster, eigenständige Cluster und Nutzercluster.
Der Einrichtungsprozess umfasst die folgenden allgemeinen Schritte:
- Konfigurieren Sie einen Cluster für SR-IOV-Netzwerke.
- Konfigurieren Sie den SR-IOV-Operator, eine benutzerdefinierte
SriovOperatorConfig
-Ressource. - Richten Sie SR-IOV-Richtlinien ein und konfigurieren Sie VFs.
- Erstellen Sie eine benutzerdefinierte
NetworkAttachmentDefinition
-Ressource, die auf die VFs verweist.
Voraussetzungen
Für das SR-IOV-Netzwerkfeature müssen die offiziellen Treiber für die Netzwerkadapter auf den Clusterknoten vorhanden sein. Installieren Sie die Treiber, bevor Sie den SR-IOV-Operator verwenden. Wenn Sie das Modul vfio-pci
für Ihre VFs verwenden möchten, muss das Modul auch auf den Knoten verfügbar sein, auf denen es verwendet werden soll.
SR-IOV-Netzwerk für einen Cluster aktivieren
Fügen Sie der benutzerdefinierten Clusterressource die Annotation baremetal.cluster.gke.io/enable-sriov-networking
hinzu, um das SR-IOV-Netzwerk zu aktivieren. Legen Sie außerdem das Feld multipleNetworkInterfaces
im Abschnitt clusterNetwork
der benutzerdefinierten Clusterressource auf true
fest.
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: cluster1
annotations:
baremetal.cluster.gke.io/enable-sriov-networking: "true"
spec:
clusterNetwork:
multipleNetworkInterfaces: true
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/12
SR-IOV-Operator konfigurieren
Die benutzerdefinierte Ressource SriovOperatorConfig
bietet eine globale Konfiguration für das SR-IOV-Netzwerkfeature. Diese gebündelte benutzerdefinierte Ressource hat den Namen default
und befindet sich im Namespace gke-operators
. Die benutzerdefinierte Ressource SriovOperatorConfig
wird nur für diesen Namen und diesen Namespace berücksichtigt.
Sie können dieses Objekt mit dem folgenden Befehl bearbeiten:
kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default
Hier sehen Sie ein Beispiel für die Konfiguration einer benutzerdefinierten SriovOperatorConfig
-Ressource:
apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovOperatorConfig
metadata:
name: default
namespace: gke-operators
spec:
configDaemonNodeSelector:
nodePool: "withSriov"
disableDrain: false
logLevel: 2
Im Abschnitt configDaemonNodeSelector
können Sie einschränken, welche Knoten der SR-IOV-Operator verarbeiten kann. Im vorherigen Beispiel ist der Operator auf Knoten mit dem Label nodePool: withSriov
beschränkt. Wenn das Feld configDaemonNodeSelector
nicht angegeben ist, werden die folgenden Standardlabels angewendet:
beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""
Das Feld disableDrain
gibt an, ob ein Kubernetes-Knoten geleert werden soll, bevor der Knoten neu gestartet werden muss oder bevor eine bestimmte VF-Konfiguration geändert wird.
SR-IOV-Richtlinien erstellen
Damit Sie bestimmte VFs in Ihrem Cluster konfigurieren können, müssen Sie im Namespace gke-operators
die benutzerdefinierte SriovNetworkNodePolicy
-Ressource erstellen.
Hier ist ein Beispielmanifest für eine benutzerdefinierte SriovNetworkNodePolicy
-Ressource:
apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
name: policy-1
namespace: gke-operators
spec:
deviceType: "netdevice"
mtu: 1600
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0
deviceID: "1015"
rootDevices:
- 0000:01:00.0
vendor: "15b3"
numVfs: 4
priority: 80
resourceName: "mlnx"
Im Abschnitt nodeSelector
können Sie die Knoten weiter einschränken, auf denen die VFs erstellt werden müssen. Diese Einschränkung basiert auf den Selektoren aus SriovOperatorConfig
, die im vorherigen Abschnitt beschrieben wurden.
Das Feld deviceType
gibt das Kernelmodul an, das für die VFs verwendet werden soll. Für deviceType
sind folgende Optionen verfügbar:
netdevice
für ein VF-spezifisches Standard-Kernel-Modulvfio-pci
für den VFIO-PCI-Treiber
Der resourceName
definiert, mit welchem Namen die VFs auf dem Kubernetes-Knoten dargestellt werden.
Nach Abschluss der Konfiguration enthalten die ausgewählten Clusterknoten die definierte Ressource, wie im folgenden Beispiel gezeigt. Beachten Sie die gke.io/mlnx
:
apiVersion: v1
kind: Node
metadata:
name: worker-01
spec:
…
status:
allocatable:
cpu: 47410m
ephemeral-storage: "210725550141"
gke.io/mlnx: "4"
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 59884492Ki
pods: "250"
capacity:
cpu: "48"
ephemeral-storage: 228651856Ki
gke.io/mlnx: "4"
hugepages-1Gi: "0"
hugepages-2Mi: "0"
memory: 65516492Ki
pods: "250"
Der Operator fügt jeder Ressource, die Sie mit SriovNetworkNodePolicy
definieren, immer das Präfix gke.io/
hinzu.
NIC-Selektor angeben
Damit SriovNetworkNodePolicy
ordnungsgemäß funktioniert, geben Sie mindestens einen Selektor im Abschnitt nicSelector
an. Dieses Feld enthält mehrere Optionen zum Identifizieren bestimmter physischer Funktionen (PFs) in Ihren Clusterknoten. Die meisten Informationen, die für dieses Feld erforderlich sind, werden für Sie ermittelt und in der benutzerdefinierten Ressource SriovNetworkNodeState
gespeichert. Für jeden Knoten, den dieser Operator verarbeiten kann, gibt es ein Objekt.
Mit dem folgenden Befehl rufen Sie alle verfügbaren Knoten auf:
kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml
Hier ein Beispiel für einen Knoten:
apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
name: worker-01
namespace: gke-operators
spec:
dpConfigVersion: "6368949"
status:
interfaces:
- deviceID: "1015"
driver: mlx5_core
eSwitchMode: legacy
linkSpeed: 10000 Mb/s
linkType: ETH
mac: 1c:34:da:5c:2b:9c
mtu: 1500
name: enp1s0f0
pciAddress: "0000:01:00.0"
totalvfs: 4
vendor: 15b3
- deviceID: "1015"
driver: mlx5_core
linkSpeed: 10000 Mb/s
linkType: ETH
mac: 1c:34:da:5c:2b:9d
mtu: 1500
name: enp1s0f1
pciAddress: "0000:01:00.1"
totalvfs: 2
vendor: 15b3
syncStatus: Succeeded
Partitionierung physischer Funktionen festlegen
Achten Sie dabei besonders auf das Feld pfNames
im Abschnitt nicSelector
. Sie können nicht nur die genaue zu verwendende PF angeben, sondern auch die genauen VFs, die für die angegebene PF und die in der Richtlinie definierten Ressource verwendet werden sollen.
Beispiel:
apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodePolicy
metadata:
name: policy-1
namespace: gke-operators
spec:
deviceType: "netdevice"
mtu: 1600
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0#3-6
deviceID: "1015"
rootDevices:
- 0000:01:00.0
vendor: "15b3"
numVfs: 7
priority: 80
resourceName: "mlnx"
Im vorherigen Beispiel verwendet die Ressource gke.io/mlnx
nur die VFs mit den Nummern 3 bis 6 und zeigt nur vier verfügbare VFs an. Da die VFs immer aus dem Index mit null erstellt werden, muss die angeforderte Anzahl von VFs (numVfs
) mindestens so hoch sein wie der Wert beim Schließen des Bereichs (gerechnet ab null). Diese Nummerierungslogik ist der Grund, warum numVfs
im vorherigen Beispiel auf 7
gesetzt wurde. Wenn Sie einen Bereich von 3 bis 4 festlegen (enp65s0f0#3-4
), muss numVfs
mindestens 5
sein.
Wenn die Partitionierung nicht angegeben ist, definiert numVfs
den verwendeten VF-Bereich, der immer bei null beginnt. Wenn Sie beispielsweise numVfs=3
festlegen, ohne die Partitionierung anzugeben, wird der VF-Bereich 0-2
verwendet.
Informationen zur Richtlinienpriorität
Sie können mehrere SriovNetworkNodePolicy
-Objekte angeben, um verschiedene Anbieter oder unterschiedliche VF-Konfigurationen zu verarbeiten. Die Verwaltung mehrerer Objekte und Anbieter kann zu Problemen führen, wenn mehrere Richtlinien auf dieselbe PF verweisen. Um solche Situationen zu vermeiden, löst das Feld priority
die Konflikte auf Knotenbasis.
Die Priorisierungslogik für überlappende PF-Richtlinien lautet folgendermaßen:
Eine Richtlinie mit höherer Priorität überschreibt immer eine Richtlinie mit niedrigerer Priorität.
Richtlinien mit derselben Priorität werden zusammengeführt:
- Richtlinien werden nach Name sortiert und in dieser Reihenfolge verarbeitet
- Richtlinien mit sich überschneidenden VF-Bereichen werden überschrieben.
- Richtlinien mit nicht überlappender PF-Partitionierung werden zusammengeführt und sind alle vorhanden.
Eine Richtlinie mit hoher Priorität ist eine Priorität mit einem niedrigeren numerischen Wert im Feld priority
. Beispielsweise ist die Priorität für eine Richtlinie mit priority: 10
höher als für eine Richtlinie mit priority: 20
.
In den folgenden Abschnitten finden Sie Richtlinienbeispiele für verschiedene Partitionierungskonfigurationen.
Partitionierte PF
Das Bereitstellen der folgenden zwei SriovNetworkNodePolicy
-Manifeste führt zu zwei verfügbaren Ressourcen: gke.io/dev-kernel
und gke.io/dev-vfio
. Jede Ressource hat zwei VFs, die sich nicht überschneiden.
kind: SriovNetworkNodePolicy
metadata:
name: policy-1
spec:
deviceType: "netdevice"
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0#0-1
numVfs: 2
priority: 70
resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
name: policy-2
spec:
deviceType: "vfio-pci"
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0#2-3
numVfs: 4
priority: 70
resourceName: "dev-vfio"
Sich überschneidende VF-Bereiche
Durch die Bereitstellung der folgenden zwei SriovNetworkNodePolicy
-Manifeste ist nur die Ressource gke.io/dev-vfio
verfügbar. Der VF-Bereich policy-1
ist 0-2
, was sich mit policy-2
überschneidet. Aufgrund der Benennung wird policy-2
zuletzt verarbeitet.
Daher ist nur die in policy-2
angegebene Ressource gke.io/dev-vfio
verfügbar.
kind: SriovNetworkNodePolicy
metadata:
name: policy-1
spec:
deviceType: "netdevice"
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0
numVfs: 3
priority: 70
resourceName: "dev-kernel"
kind: SriovNetworkNodePolicy
metadata:
name: policy-2
spec:
deviceType: "vfio-pci"
nodeSelector:
baremetal.cluster.gke.io/node-pool: node-pool-1
nicSelector:
pfNames:
- enp65s0f0#2-3
numVfs: 4
priority: 70
resourceName: "dev-vfio"
Einrichtungsstatus der SR-IOV-Richtlinie prüfen
Wenn Sie die SR-IOV-Richtlinien anwenden, können Sie die endgültige Konfiguration der Knoten in der benutzerdefinierten Ressource SriovNetworkNodeState
für den jeweiligen Knoten verfolgen und ansehen. Im Abschnitt status
stellt das Feld syncStatus
die aktuelle Phase für den Konfigurations-Daemon dar. Der Status Succeeded
zeigt an, dass die Konfiguration abgeschlossen ist. Der Abschnitt spec
der benutzerdefinierten Ressource SriovNetworkNodeState
definiert den endgültigen Zustand der VFs-Konfiguration für diesen Knoten anhand der Anzahl der Richtlinien und ihrer Prioritäten. Alle erstellten VFs werden im Abschnitt status
für die angegebenen PFs aufgeführt.
Hier ein Beispiel für eine benutzerdefinierte SriovNetworkNodeState
-Ressource:
apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovNetworkNodeState
metadata:
name: worker-02
namespace: gke-operators
spec:
dpConfigVersion: "9022068"
interfaces:
- linkType: eth
name: enp1s0f0
numVfs: 2
pciAddress: "0000:01:00.0"
vfGroups:
- deviceType: netdevice
policyName: policy-1
resourceName: mlnx
vfRange: 0-1
status:
interfaces:
- Vfs:
- deviceID: "1016"
driver: mlx5_core
mac: 96:8b:39:d8:89:d2
mtu: 1500
name: enp1s0f0np0v0
pciAddress: "0000:01:00.2"
vendor: 15b3
vfID: 0
- deviceID: "1016"
driver: mlx5_core
mac: 82:8e:65:fe:9b:cb
mtu: 1500
name: enp1s0f0np0v1
pciAddress: "0000:01:00.3"
vendor: 15b3
vfID: 1
deviceID: "1015"
driver: mlx5_core
eSwitchMode: legacy
linkSpeed: 10000 Mb/s
linkType: ETH
mac: 1c:34:da:5c:2b:9c
mtu: 1500
name: enp1s0f0
numVfs: 2
pciAddress: "0000:01:00.0"
totalvfs: 2
vendor: 15b3
- deviceID: "1015"
driver: mlx5_core
linkSpeed: 10000 Mb/s
linkType: ETH
mac: 1c:34:da:5c:2b:9d
mtu: 1500
name: enp1s0f1
pciAddress: "0000:01:00.1"
totalvfs: 2
vendor: 15b3
syncStatus: Succeeded
Benutzerdefinierte NetworkAttachmentDefinition
-Ressource erstellen
Nachdem Sie die VFs erfolgreich im Cluster konfiguriert haben und diese im Kubernetes-Knoten als Ressource angezeigt werden, müssen Sie ein NetworkAttachmentDefinition
erstellen, das auf die Ressource verweist. Erstellen Sie den Verweis mit der Annotation k8s.v1.cni.cncf.io/resourceName
.
Das folgende Beispiel zeigt ein NetworkAttachmentDefinition
-Manifest, das auf die Ressource gke.io/mlnx
verweist:
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: gke-sriov-1
annotations:
k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
config: '{
"cniVersion": "0.3.0",
"name": "mynetwork",
"type": "sriov",
"ipam": {
"type": "whereabouts",
"range": "21.0.108.0/21",
"range_start": "21.0.111.16",
"range_end": "21.0.111.18"
}
}'
Die NetworkAttachmentDefinition
muss sriov
als CNI-Typ haben.
Verweisen Sie mit der Annotation k8s.v1.cni.cncf.io/networks
auf alle bereitgestellten benutzerdefinierten NetworkAttachmentDefinition
-Ressourcen in Ihren Pods.
Hier ist ein Beispiel dafür, wie Sie auf die vorherige benutzerdefinierte NetworkAttachmentDefinition
-Ressource in einem Pod verweisen:
apiVersion: v1
kind: Pod
metadata:
name: samplepod
annotations:
k8s.v1.cni.cncf.io/networks: gke-sriov-1
spec:
containers:
...
Wenn Sie in Arbeitslasten auf eine benutzerdefinierte NetworkAttachmentDefinition
-Ressource verweisen, müssen Sie sich keine Gedanken über die Ressourcendefinitionen der Pods oder die Platzierung in bestimmten Knoten machen, da dies automatisch für Sie erledigt wird.
Das folgende Beispiel zeigt eine benutzerdefinierte NetworkAttachmentDefinition
-Ressource mit einer VLAN-Konfiguration. In diesem Beispiel gehört jede VF zum 100
-VLAN:
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
name: gke-sriov-vlan-100
annotations:
k8s.v1.cni.cncf.io/resourceName: gke.io/mlnx
spec:
config: '{
"cniVersion": "0.3.0",
"name": "mynetwork",
"type": "sriov",
"vlan": 100,
"ipam": {
"type": "whereabouts",
"range": "21.0.100.0/21"
}
}'
Weitere Informationen
Die folgenden Abschnitte enthalten Informationen zum Konfigurieren eines SR-IOV-Netzwerks.
Neustart von Knoten
Wenn der SR-IOV-Operator die Knoten konfiguriert, müssen die Knoten möglicherweise neu gestartet werden. Während der VF- oder Kernel-Konfiguration ist möglicherweise ein Neustart der Knoten erforderlich. Die Kernel-Konfiguration umfasst die Unterstützung der SR-IOV-Funktionalität im Betriebssystem.
Unterstützte Netzwerkadapter
In der folgenden Tabelle sind die unterstützten Netzwerkadapter für Cluster der Version 1.10.x aufgeführt:
Name | Anbieter-ID | Geräte-ID | VF-Geräte-ID |
---|---|---|---|
Intel i40e XXV710 | 8086 | 158a | 154c |
Intel i40e 25G SFP28 | 8086 | 158b | 154c |
Intel i40e 10G X710 SFP | 8086 | 1572 | 154c |
Intel i40e XXV710 N3000 | 8086 | 0d58 | 154c |
Intel i40e 40G XL710 QSFP | 8086 | 1583 | 154c |
Intel ice Columbiaville E810-CQDA2 2CQDA2 | 8086 | 1.592 | 1889 |
Intel ice Columbiaville E810-XXVDA4 | 8086 | 1593 | 1889 |
Intel ice Columbiaville E810-XXVDA2 | 8086 | 159b | 1889 |
Nvidia mlx5 ConnectX-4 | 15b3 | 1013 | 1014 |
Nvidia mlx5 ConnectX-4LX | 15b3 | 1015 | 1016 |
Nvidia mlx5 ConnectX-5 | 15b3 | 1017 | 1018 |
Nvidia mlx5 ConnectX-5 Ex | 15b3 | 1019 | 101a |
Nvidia mlx5 ConnectX-6 | 15b3 | 101b | 101c |
Nvidia mlx5 ConnectX-6_Dx | 15b3 | 101d | 101e |
Nvidia mlx5 MT42822 BlueField-2 integrated ConnectX-6 Dx | 15b3 | a2d6 | 101e |