SR-IOV 네트워킹 설정

이 문서에서는 Anthos clusters on bare metal에 단일 루트 입력/출력 가상화(SR-IOV) 네트워킹을 설정하는 방법을 설명합니다. SR-IOV는 Linux 커널에서 네트워크 기기로 사용할 수 있는 네트워크 인터페이스 카드(NIC)를 만들 수 있도록 I/O 가상화를 제공합니다. 이를 통해 네트워크 연결을 관리하고 포드에 할당할 수 있습니다. 패킷이 NIC 및 포드 간에 직접 이동하므로 성능이 향상됩니다.

포드 워크로드에 빠른 네트워킹이 필요한 경우 이 기능을 사용하세요. Anthos clusters on bare metal용 SR-IOV를 사용하면 클러스터 노드의 지원되는 기기에서 가상 기능(VF)을 구성할 수 있습니다. 특정 커널 모듈을 지정하여 VF에 바인딩하는 것도 가능합니다.

이 기능은 워크로드가 실행되는 클러스터(예:하이브리드 ,독립형 ,사용자 클러스터)에서 사용할 수 있습니다.

설정 프로세스는 다음과 같은 주요 단계로 구성됩니다.

  1. SR-IOV 네트워킹을 사용 설정하도록 클러스터를 구성합니다.
  2. SriovOperatorConfig 커스텀 리소스인 SR-IOV 연산자를 구성합니다.
  3. SR-IOV 정책을 설정하고 VF를 구성합니다.
  4. VF를 참조하는 NetworkAttachmentDefinition 커스텀 리소스를 만듭니다.

요구사항

SR-IOV 네트워킹 기능을 사용하려면 네트워크 어댑터의 공식 드라이버가 클러스터 노드에 있어야 합니다. SR-IOV 연산자를 사용하기 전에 드라이버를 설치합니다. 또한 VF에 vfio-pci 모듈을 사용하려면 이 모듈을 사용할 노드에서 사용할 수 있는지 확인합니다.

클러스터의 SR-IOV 네트워킹 사용 설정

SR-IOV 네트워킹을 사용 설정하려면 baremetal.cluster.gke.io/enable-sriov-networking 주석을 클러스터 커스텀 리소스에 추가합니다. 또한 클러스터 커스텀 리소스의 clusterNetwork 섹션에 있는 multipleNetworkInterfaces 필드를 true로 설정합니다.

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 연산자 구성

SriovOperatorConfig 커스텀 리소스는 SR-IOV 네트워킹 기능에 대한 전역 구성을 제공합니다. 이 번들 커스텀 리소스 이름은 default이며 gke-operators 네임스페이스에 있습니다. SriovOperatorConfig 커스텀 리소스는 이 이름과 네임스페이스에만 적용됩니다.

다음 명령어를 사용하여 이 객체를 수정할 수 있습니다.

kubectl -n gke-operators edit sriovoperatorconfigs.sriovnetwork.k8s.cni.cncf.io default

다음은 SriovOperatorConfig 커스텀 리소스 구성의 예시입니다.

apiVersion: sriovnetwork.k8s.cni.cncf.io/v1
kind: SriovOperatorConfig
metadata:
  name: default
  namespace: gke-operators
spec:
  configDaemonNodeSelector:
    nodePool: "withSriov"
  disableDrain: false
  logLevel: 2

configDaemonNodeSelector 섹션을 통해 SR-IOV 연산자가 처리할 수 있는 노드를 제한할 수 있습니다. 앞의 예시에서 연산자는 nodePool: withSriov 라벨이 있는 노드로 제한됩니다. configDaemonNodeSelector 필드를 지정하지 않으면 다음 기본 라벨이 적용됩니다.

beta.kubernetes.io/os: linux
node-role.kubernetes.io/worker: ""

disableDrain 필드는 노드를 재부팅하기 전이나 특정 VF 구성을 변경하기 전에 Kubernetes 노드 드레이닝 작업을 수행할지 여부를 지정합니다.

SR-IOV 정책 만들기

클러스터에서 특정 VF를 구성하려면 gke-operators 네임스페이스에 SriovNetworkNodePolicy 커스텀 리소스를 만들어야 합니다.

다음은 SriovNetworkNodePolicy 커스텀 리소스의 매니페스트 예시입니다.

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"

nodeSelector 섹션에서는 VF가 생성되어야 하는 노드를 추가로 제한할 수 있습니다. 이 제한은 이전 섹션에서 설명한 SriovOperatorConfig의 선택기와는 구분됩니다.

deviceType 필드는 VF에 사용할 커널 모듈을 지정합니다. deviceType에 사용할 수 있는 옵션은 다음과 같습니다.

  • netdevice: VF 관련 표준 커널 모듈용
  • vfio-pci: VFIO-PCI 드라이버용

resourceName은 VF가 Kubernetes 노드에서 나타내는 이름을 정의합니다.

구성 프로세스가 완료되면 선택한 클러스터 노드에 다음 예시와 같이 정의된 리소스가 포함됩니다(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"

연산자는 항상 SriovNetworkNodePolicy로 정의하는 모든 리소스에 gke.io/ 프리픽스를 추가합니다.

NIC 선택기 지정

SriovNetworkNodePolicy가 올바르게 작동할 수 있도록 nicSelector 섹션에 선택기를 최소 하나 이상 지정합니다. 이 필드에는 클러스터 노드에서 특정 물리적 함수(PF)를 식별하는 방법에 대한 옵션 여러 개가 포함됩니다. 이 필드에 필요한 대부분의 정보는 자동으로 검색되어 SriovNetworkNodeState 커스텀 리소스에 저장됩니다. 이 연산자가 처리할 수 있는 노드마다 객체 하나가 있습니다.

사용 가능한 모든 노드를 보려면 다음 명령어를 사용하세요.

kubectl -n gke-operators get sriovnetworknodestates.sriovnetwork.k8s.cni.cncf.io -o yaml

노드 예시는 다음과 같습니다.

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

물리적 함수 파티션 나누기 설정

nicSelector 섹션의 pfNames 필드에 특히 주의하세요. 사용할 PF를 정확하게 명시하는 것 외에도 지정된 PF 및 정책에 정의된 리소스에 사용할 VF를 정확하게 지정할 수 있습니다.

예를 들면 다음과 같습니다.

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"

앞의 예시에서 gke.io/mlnx 리소스는 3~6번의 VF만 사용하고 사용 가능한 VF 4개만 표시합니다. VF는 항상 0번 색인부터 생성되므로 요청 VF 수 numVfs는 최소한 범위의 최종 값(0부터 계수)보다 커야 합니다. 이 번호 지정 로직으로 인해 앞의 예시에서 numVfs7로 설정됩니다. 3~4(enp65s0f0#3-4) 범위의 경우 numVfs5 이상이어야 합니다.

파티션 나누기가 지정되지 않은 경우 numVfs는 사용 중인 VF 범위를 정의하고 이 범위는 항상 0부터 시작합니다. 예를 들어 파티션 나누기를 지정하지 않고 numVfs=3을 설정하면 VF 0-2가 사용됩니다.

정책 우선순위 이해하기

SriovNetworkNodePolicy 객체를 여러 개 지정하여 다양한 공급업체나 다양한 VF 구성을 처리할 수 있습니다. 여러 정책에서 같은 PF를 참조하면 객체와 공급업체 여러 개를 관리하는 것이 어려워질 수 있습니다. 이러한 상황이 해결되도록 priority 필드는 노드별로 충돌을 해결합니다.

다음은 PF 정책 중복에 대한 우선순위 지정 로직입니다.

  1. 우선순위가 높은 정책은 항상 우선순위가 낮은 정책을 덮어씁니다.

  2. 동일한 우선순위 정책은 병합됩니다.

    1. 정책은 이름을 기준으로 정렬되며 이 순서대로 처리됩니다.
    2. VF 범위가 겹치는 정책을 덮어씁니다.
    3. PF 파티션 나누기가 겹치지 않는 정책은 병합되고 모두 존재합니다.

우선순위가 높은 정책은 priority 필드의 숫자 값이 낮은 정책입니다. 예를 들어 priority: 20이 있는 정책보다 priority: 10이 있는 정책의 우선순위가 더 높습니다.

다음 섹션에서는 다양한 파티션 나누기 구성에 대한 정책 예시를 제공합니다.

파티션을 나눈 PF

다음 두 SriovNetworkNodePolicy 매니페스트를 배포하면 사용 가능한 리소스로 gke.io/dev-kernelgke.io/dev-vfio 두 개가 생성됩니다. 각 리소스에는 겹치지 않는 VF 두 개가 있습니다.

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"

VF 범위 겹침

다음 두 SriovNetworkNodePolicy 매니페스트를 배포하면 gke.io/dev-vfio 리소스만 사용할 수 있게 됩니다. policy-1 VF 범위는 policy-2와 겹치는 0-2입니다. 이름 지정으로 인해 policy-2가 마지막으로 처리됩니다. 따라서 policy-2, gke.io/dev-vfio에 지정된 리소스만 사용할 수 있습니다.

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"

SR-IOV 정책 설정 상태 확인

SR-IOV 정책을 적용할 때 특정 노드의 SriovNetworkNodeState 커스텀 리소스에서 노드의 최종 구성을 추적하고 볼 수 있습니다. status 섹션에서 syncStatus 필드는 구성 데몬의 현재 단계를 나타냅니다. Succeeded 상태는 구성이 완료되었음을 나타냅니다. SriovNetworkNodeState 커스텀 리소스의 spec 섹션은 정책 수와 정책 우선순위에 따라 노드의 VF 구성 최종 상태를 정의합니다. 생성된 모든 VF가 지정된 PF의 status 섹션에 나열됩니다.

다음은 SriovNetworkNodeState 커스텀 리소스의 예시입니다.

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

NetworkAttachmentDefinition 커스텀 리소스 만들기

클러스터에서 VF를 성공적으로 구성하고 VF가 Kubernetes 노드에 리소스로 표시되면 리소스를 참조하는 NetworkAttachmentDefinition을 만들어야 합니다. k8s.v1.cni.cncf.io/resourceName 주석으로 참조를 만듭니다.

다음은 gke.io/mlnx 리소스를 참조하는 NetworkAttachmentDefinition 매니페스트의 예시입니다.

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"
      }
    }'

NetworkAttachmentDefinition에는 CNI 유형으로 sriov가 있어야 합니다. k8s.v1.cni.cncf.io/networks 주석을 사용하여 포드에 배포된 NetworkAttachmentDefinition 커스텀 리소스를 참조합니다.

다음은 포드에서 이전 NetworkAttachmentDefinition 커스텀 리소스를 참조하는 방법의 예시입니다.

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

워크로드에서 NetworkAttachmentDefinition 커스텀 리소스를 참조할 때는 자동으로 수행되는 포드의 리소스 정의나 특정 노드의 배치에 대해 걱정할 필요가 없습니다.

다음 예시에서는 VLAN 구성이 있는 NetworkAttachmentDefinition 커스텀 리소스를 보여줍니다. 이 샘플에서 모든 VF는 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"
      }
    }'

추가 정보

다음 섹션에는 SR-IOV 네트워킹을 구성하는 데 도움이 되는 정보가 포함되어 있습니다.

노드 재부팅

SR-IOV 연산자에서 노드를 구성할 때 노드를 재부팅해야 할 수도 있습니다. VF 또는 커널 구성 중에 노드를 재부팅해야 할 수 있습니다. 커널 구성은 운영체제에서 SR-IOV 기능 지원을 사용 설정합니다.

지원되는 네트워크 어댑터

다음 표에는 버전 1.10.x 클러스터에 지원되는 네트워크 어댑터가 나와 있습니다.

이름 공급업체 ID 기기 ID VF 기기 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 1592 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