Mehrere Netzwerkschnittstellen für Pods konfigurieren

In diesem Dokument wird beschrieben, wie Sie Google Distributed Cloud so konfigurieren, dass mehrere Netzwerkschnittstellen (NICs) für Ihre Pods bereitgestellt werden. Das Feature mit mehreren NICs für Pods kann dabei helfen, den Traffic auf Steuerungsebene vom Traffic auf Datenebene zu trennen, wodurch eine Isolation zwischen den Ebenen entsteht. Zusätzliche Netzwerkschnittstellen ermöglichen auch Multicast-Funktionen für Ihre Pods. Multi-NIC für Pods wird für Nutzercluster unterstützt, nicht jedoch für Administratorcluster.

Die Isolierung der Netzwerkebene ist für Systeme wichtig, die Virtual Functions für Netzwerkfunktionen (NFVs) verwenden, z. B. softwarebasierte Netzwerke in einem Wide Area Network (SD-WAN), einen Cloud Access Security Broker (CASB) und Generierungsfirewalls (NG-FWs). Diese Arten von NFVs sind auf den Zugriff auf mehrere Schnittstellen angewiesen, um die Steuerungs- und Datenebenen zu trennen.

Die Konfiguration der mehreren Netzwerkschnittstellen unterstützt die Verknüpfung von Netzwerkschnittstellen mit Knotenpools, was zu Leistungsvorteilen führen kann. Ein Cluster kann beispielsweise eine Mischung aus Knotentypen enthalten. Wenn Sie leistungsstarke Maschinen in einem Knotenpool gruppieren, können Sie für den Knotenpool zusätzliche Schnittstellen erstellen, um den Trafficfluss zu verbessern.

Mehrere Netzwerkschnittstellen einrichten

Im Allgemeinen gibt es drei Schritte, um mehrere Netzwerkschnittstellen für Ihre Pods einzurichten:

  1. Aktivieren Sie Multi-NIC für Ihren Nutzercluster. Verwenden Sie dazu die Felder multipleNetworkInterfaces und enableDataplaneV2 in der Cluster-Konfigurationsdatei.

  2. Geben Sie Netzwerkschnittstellen unter additionalNodeInterfaces in der Clusterkonfigurationsdatei an und erstellen Sie eine oder mehrere benutzerdefinierte NetworkAttachmentDefinition-Ressourcen.

  3. Weisen Sie Pods Netzwerkschnittstellen mit der Annotation k8s.v1.cni.cncf.io/networks zu.

Mehrere NICs aktivieren

Aktivieren Sie Multi-NIC für Ihre Pods, indem Sie die Felder multipleNetworkInterfaces und enableDataplaneV2 in der Konfigurationsdatei des Nutzerclusters auf true setzen.

apiVersion: v1
multipleNetworkInterfaces: true
enableDataplaneV2: true
  ...

Netzwerkschnittstellen angeben

Geben Sie in der Clusterkonfigurationsdatei im Abschnitt additionalNodeInterfaces zusätzliche Knotennetzwerkschnittstellen an.

Das folgende Beispiel zeigt einen Teil einer Nutzercluster-Konfigurationsdatei mit einer zusätzlichen Knotennetzwerkschnittstelle:

apiVersion: v1
multipleNetworkInterfaces: true
enableDataplaneV2: true
network:
  serviceCIDR: "10.96.0.0/20"
  podCIDR: "192.168.0.0/16"
  vCenter:
    networkName: network-private310
  ...
  # New multiple network configs
  additionalNodeInterfaces:
  - networkName: "gke-network-1"
    ipBlockFilePath: "my-block-yaml"
    type: static

Nach dem Erstellen eines Clusters mit der vorherigen Konfiguration müssen Sie in Ihrem Nutzercluster eine oder mehrere benutzerdefinierte NetworkAttachmentDefinition-Ressourcen (NAD) erstellen, in denen Sie zusätzliche Netzwerkschnittstellen angeben. Die NetworkAttachmentDefinitions entsprechen den Netzwerken, die für Ihre Pods verfügbar sind. Das folgende Beispiel zeigt ein Manifest für eine NetworkAttachmentDefinition:

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: default
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "ens224", # defines the node interface that this Pod interface would map to
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.16.0.0/24"
   }
}'

Speichern Sie das Manifest als YAML-Datei, z. B. mit my-nad.yaml, und erstellen Sie die NetworkAttachmentDefinition:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] apply -f my-nad.yaml

Einem Pod Netzwerkschnittstellen zuweisen

Verwenden Sie die Annotation k8s.v1.cni.cncf.io/networks, um einem Pod eine oder mehrere Netzwerkschnittstellen zuzuweisen. Jede Netzwerkschnittstelle wird mit einem Namespace und dem Namen eines NetworkAttachmentDefinition angegeben, der durch einen Schrägstrich (/) getrennt ist. Verwenden Sie eine durch Kommas getrennte Liste, um mehrere Netzwerkschnittstellen anzugeben.

Im folgenden Beispiel werden dem Pod samplepod zwei Netzwerkschnittstellen zugewiesen. Die Netzwerkschnittstellen werden durch die Namen von zwei NetworkAttachmentDefinitions, gke-network-1 und gke-network-2, angegeben, die im Namespace default erstellt wurden.

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
  containers:
  ...

Netzwerkschnittstellen auf eine Gruppe von Knoten beschränken

Wenn eine NetworkAttachmentDefinition nicht auf einen gesamten Cluster angewendet werden soll, können Sie ihre Funktionalität auf eine Reihe von Knoten beschränken.

Sie können Clusterknoten entweder mit dem dem Knoten zugewiesenen Standardlabel oder Ihrem eigenen benutzerdefinierten Label gruppieren. Sie können dann das Knotenlabel im Manifest NetworkAttachmentDefinition mithilfe der Annotation k8s.v1.cni.cncf.io/nodeSelector angeben. GKE on VMware erzwingt, dass alle Pods, die auf diese benutzerdefinierte Ressource verweisen, auf den Knoten mit diesem Label bereitgestellt werden.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: LABEL_KEY=LABEL_VALUE
  name: gke-network-1
spec:
...

Das folgende Beispiel zeigt das Label my-label=multinicNP, das auf dem NetworkAttachmentDefinition angegeben ist, und erzwingt die Bereitstellung aller Pods, denen das Netzwerk gke-network-1 zugewiesen ist, auf den Knoten, die dieses Label haben.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: my-label=multinicNP
  name: gke-network-1
spec:
...

Mit dem Befehl kubectl label nodes können Sie ein benutzerdefiniertes Label auf einen Knoten anwenden:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] label nodes NODE_NAME LABEL_KEY=LABEL_VALUE 

Ersetzen Sie Folgendes:

  • NODE_NAME: der Name des Knotens, den Sie mit einem Label versehen.
  • LABEL_KEY ist der für Ihr Label zu verwendende Schlüssel.
  • LABEL_VALUE: der Labelwert.

In diesem Beispiel erhält der Knoten my-node das Label environment=production:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] label nodes my-node environment=production

Sicherheitsbedenken

Eine NetworkAttachmentDefinition bietet uneingeschränkten Zugriff auf ein Netzwerk. Daher müssen Clusteradministratoren darauf achten, wie sie anderen Nutzern Zugriffsrechte für das Erstellen, Aktualisieren oder Löschen gewähren. Wenn eine bestimmte NetworkAttachmentDefinition isoliert werden muss, können Sie beim Erstellen einen nicht standardmäßigen Namespace angeben, auf den nur die Pods aus diesem Namespace zugreifen können.

Im folgenden Diagramm können Pods aus dem Namespace default nicht auf die Netzwerkschnittstelle im Namespace privileged zugreifen.

Verwendung von Namespaces zum Isolieren des Netzwerktraffics.

Unterstützte CNI-Plug-ins

In diesem Abschnitt werden die CNI-Plug-ins aufgeführt, die von der Multi-NIC-Funktion für Google Distributed Cloud unterstützt werden. Verwenden Sie nur die folgenden Plug-ins, wenn Sie eine NetworkAttachmentDefinition angeben.

Schnittstellenerstellung:

  • ipvlan
  • macvlan
  • bridge

Meta-Plug-ins:

  • portmap
  • sbr
  • tuning

IPAM-Plug-ins:

  • host-local
  • static
  • whereabouts

Routenkonfiguration

Ein Pod mit einer oder mehreren zugewiesenen NetworkAttachmentDefinitions hat mehrere Netzwerkschnittstellen. Standardmäßig wird die Routingtabelle des Pods in diesem Fall um die lokal verfügbaren zusätzlichen Schnittstellen nur aus dem zugewiesenen NetworkAttachmentDefinitions erweitert. Pakete, die für das Standardgateway gebunden sind, werden weiterhin so konfiguriert, dass sie die Standardschnittstelle des Pods eth0 verwenden. Sie können dieses Verhalten mithilfe der folgenden CNI-Plug-ins ändern:

  • sbr
  • static
  • whereabouts

Wenn der Traffic z. B. über das Standardgateway geleitet werden soll, wird der Traffic über die Standardnetzwerkschnittstelle geleitet. Sie möchten jedoch, dass bestimmter Traffic über eine der nicht standardmäßigen Schnittstellen geleitet wird. Es kann schwierig sein, den Traffic basierend auf der Ziel-IP zu unterscheiden (normales Routing), da derselbe Endpunkt über beide Schnittstellentypen verfügbar ist. In diesem Fall kann das quellenbasierte Routing (SBR) helfen.

SBR-Plug-in

Das Plug-in sbr gibt der Anwendung die Kontrolle über Routingentscheidungen. Die Anwendung steuert, was als Quell-IP-Adresse der hergestellten Verbindung verwendet wird. Wenn die Anwendung die IP-Adresse der NetworkAttachmentDefinition für die Quell-IP-Adresse verwendet, landen Pakete in der zusätzlichen Routingtabelle, die von sbr eingerichtet wurde. Die Routingtabelle sbr sendet Traffic über ihr eigenes Standardgateway, das die Schnittstelle NetworkAttachmentDefinition nutzt. Die Standard-Gateway-IP in dieser Tabelle wird mit dem Feld gateway in den Plug-ins whereabouts oder static gesteuert. Das Plug-in sbr wird als verkettetes Plug-in ausgeführt. Weitere Informationen zum sbr-Plug-in, einschließlich der Nutzungsinformationen, finden Sie unter Quellbasiertes Routing-Plug-in.

Das folgende Beispiel zeigt "gateway":"21.0.111.254", das in whereabouts festgelegt ist, und sbr als verkettetes Plug-in nach ipvlan:

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1

Statische und Standort-Plug-ins

Das Plug-in whereabouts ist im Grunde eine Erweiterung des Plug-ins static. Beide nutzen die Routingkonfiguration gemeinsam. Ein Konfigurationsbeispiel finden Sie unter Plug-in für die statische IP-Adressverwaltung. Sie können ein Gateway und eine Route definieren, die zur Routingtabelle des Pods hinzugefügt werden soll. Sie können das Standardgateway des Pods jedoch nicht so ändern.

Im folgenden Beispiel wird das Hinzufügen von "routes": [{ "dst": "172.31.0.0/16" }] in NetworkAttachmentDefinition gezeigt:

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link

Konfigurationsbeispiele

In diesem Abschnitt werden einige der allgemeinen Netzwerkkonfigurationen erläutert, die von der Multi-NIC-Funktion unterstützt werden.

Von mehreren Pods verwendeter einzelner Netzwerkanhang:

Einzelner Netzwerkanhang, der von mehreren Pods verwendet wird.

Mehrere Netzwerkanhänge, die von einem einzelnen Pod verwendet werden:

Mehrere Netzwerkanhänge werden von einem einzelnen Pod verwendet.

Mehrere Netzwerkanhänge, die auf dieselbe Schnittstelle verweisen, die von einem einzelnen Pod verwendet wird:

Mehrere Netzwerkanhänge, die auf dieselbe Schnittstelle verweisen, werden von einem einzelnen Pod verwendet.

Derselbe Netzwerkanhang, der von einem einzelnen Pod mehrmals verwendet wird:

Derselbe Netzwerkanhang wird von einem einzelnen Pod mehrmals verwendet.

Fehlerbehebung

Wenn weitere Netzwerkschnittstellen falsch konfiguriert sind, werden die Pods, denen sie zugewiesen sind, nicht gestartet. In diesem Abschnitt wird beschrieben, wie Sie Informationen zur Fehlerbehebung bei Multi-NIC-Features finden.

Pod-Ereignisse prüfen

Multus meldet Fehler über Kubernetes-Pod-Ereignisse. Verwenden Sie den folgenden kubectl describe-Befehl, um Ereignisse für einen bestimmten Pod aufzurufen:

kubectl describe pod POD_NAME

Logs prüfen

Für jeden Knoten finden Sie die Logs von Whereabouts und Multus an den folgenden Stellen:

  • /var/log/whereabouts.log
  • /var/log/multus.log

Pod-Schnittstellen prüfen

Prüfen Sie Ihre Pod-Schnittstellen mit dem Befehl kubectl exec. Sobald die NetworkAttachmentDefinitions erfolgreich angewendet wurden, sehen die Pod-Schnittstellen so aus:

user@node1:~$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 21.0.103.112/21 scope global net1
       valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.191/32 scope global eth0
       valid_lft forever preferred_lft forever

Pod-Status abrufen

Verwenden Sie kubectl get, um den Netzwerkstatus für einen bestimmten Pod abzurufen:

kubectl get pods POD_NAME -oyaml

Die folgende Beispielausgabe zeigt den Status eines Pods mit mehreren Netzwerken:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "",
          "interface": "eth0",
          "ips": [
              "192.168.1.88"
          ],
          "mac": "36:0e:29:e7:42:ad",
          "default": true,
          "dns": {}
      },{
          "name": "default/gke-network-1",
          "interface": "net1",
          "ips": [
              "21.0.111.1"
          ],
          "mac": "00:50:56:82:a7:ab",
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: gke-network-1