Руководство посвящено созданию пользовательских ресурсов на основе уже существующих административных ресурсов, которые были получены от администратора кластера или сети.

Пользовательские ресурсы

Network

Для создания выделенной сети для проекта используются ресурсы Network и NetworkClass, предоставленные администратором:

apiVersion: network.deckhouse.io/v1alpha1
kind: Network
metadata:
  name: my-network
  namespace: my-namespace
spec:
  networkClass: my-network-class # mandatory

После создания ресурса Network вы можете проверить его статус:

d8 k -n my-namespace get network my-network -o yaml
Пример статуса ресурса Network
apiVersion: network.deckhouse.io/v1alpha1
kind: Network
metadata:
...
status:
  bridgeName: d8-br-600
  conditions:
  - lastTransitionTime: "2025-09-29T14:51:26Z"
    message: All node interface attachments are ready
    reason: AllNodeInterfaceAttachmentsAreReady
    status: "True"
    type: AllNodeAttachementsAreReady
  - lastTransitionTime: "2025-09-29T14:51:26Z"
    message: Network is operational
    reason: NetworkReady
    status: "True"
    type: Ready
  nodeAttachementsCount: 1
  observedGeneration: 1
  readyNodeAttachementsCount: 1
  vlanID: 600

Поддерживается статическое определение номера VLAN ID из пула, выданного администратором кластера или сети spec.vlan.id, если значение не указано в спецификации ресурса оно будет назначено динамически.

Подключение дополнительных сетей к подам

Дополнительные сети настраиваются с помощью аннотации пода.

Пример манифеста пода с добавлением двух дополнительных сетей (кластерной my-cluster-network и сети проекта my-network):

В поле ifName (опциональное) задается имя TAP-интерфейса внутри пода. В поле mac (опциональное) задается MAC-адрес, который следует назначить TAP-интерфейсу.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-additional-networks
  namespace: my-namespace
  annotations:
    network.deckhouse.io/networks-spec: |
      [
        {
          "type": "Network",
          "name": "my-network",
          "ifName": "veth_mynet",
          "mac": "aa:bb:cc:dd:ee:ff"
        },
        {
          "type": "ClusterNetwork",
          "name": "my-cluster-network",
          "ifName": "veth_public"
        }
      ]
spec:
  containers:
    - name: app
    # остальные параметры...

IPAM для дополнительных сетей (выдача и назначение IP-адресов)

В модуле sdn реализована возможность использования механизма IPAM для выделения IP-адреса из пулов и их назначения на дополнительные интерфейсы подов.

Особенности использования:

  • IPAM включается на уровне сети (проекта (Network) или кластерной (ClusterNetwork)) через параметр spec.ipam.ipAddressPoolRef.
  • Назначение IP-адреса на интерфейс пода описывается в добавляемой к поду аннотации network.deckhouse.io/networks-spec через поля:
    • ipAddressNames — список объектов IPAddress, которые нужно назначить на данный интерфейс (если не указан — модуль может создать IPAddress автоматически).
    • skipIPAssignment — управление резервированием/отслеживанием IPAddress. Если skipIPAssignment: true, включается резервирование/отслеживание IPAddress, но IP-адрес не назначается на интерфейс внутри пода (вариант для продвинутого использования).
  • Поддерживается только IPv4.

Если в одном поде подключено несколько дополнительных сетей с включенным IPAM, рекомендуется явно задавать ipAddressNames для каждого интерфейса (создавая отдельные IPAddress). Автоматически создаваемый IPAddress привязан к поду и может не подходить для нескольких IPAM-сетей одновременно.

Механизм IPAM поддерживает автоматическую выдачу и ручное назначение статических IP-адресов подам.

Автоматическая выдача IP-адресов

Если для дополнительной сети включен IPAM (см. Руководство администратора), достаточно подключить сеть к поду с помощью аннотации пода. Если в описании интерфейса в аннотации не указан ipAddressNames, модуль автоматически создаст объект IPAddress (тип Auto) и назначит выделенный IP-адрес на интерфейс.

Пример (IP-адрес будет выбран автоматически и назначен на интерфейс net1):

apiVersion: v1
kind: Pod
metadata:
  name: app-with-ipam
  namespace: my-namespace
  annotations:
    network.deckhouse.io/networks-spec: |
      [
        {
          "type": "Network",
          "name": "my-network",
          "ifName": "net1"
        }
      ]
spec:
  containers:
    - name: app
      image: nginx
Ручное (явное) создание IPAddress с типом Auto

Также можно вручную создать объект IPAddress с spec.type: Auto (без указания параметра static.ip). В этом случае контроллер выделит свободный адрес из пула, а вы сможете привязать его к конкретному интерфейсу пода через ipAddressNames.

Пример:

  1. Создайте объект IPAddress:

    apiVersion: network.deckhouse.io/v1alpha1
    kind: IPAddress
    metadata:
      name: app-net1-auto
      namespace: my-namespace
    spec:
      networkRef:
        kind: Network          # или ClusterNetwork
        name: my-network
      type: Auto
    
  2. Назначьте IP-адрес из пула на интерфейс пода:

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-with-manual-auto-ip
      namespace: my-namespace
      annotations:
        network.deckhouse.io/networks-spec: |
          [
            {
              "type": "Network",
              "name": "my-network",
              "ifName": "net1",
              "ipAddressNames": ["app-net1-auto"]
            }
          ]
    spec:
      containers:
        - name: app
          image: nginx
    

Ручное назначение статического IP-адреса на дополнительный интерфейс пода

Чтобы назначить конкретный статический IP-адрес на дополнительный интерфейс пода, выполните следующие шаги:

  1. Создайте IPAddress в неймспейсе пода и укажите, для какой сети он предназначен, и какой IP-адрес требуется:

    apiVersion: network.deckhouse.io/v1alpha1
    kind: IPAddress
    metadata:
      name: app-net1-static
      namespace: my-namespace
    spec:
      networkRef:
        kind: Network
        name: my-network
      type: Static
      static:
        ip: 192.168.10.50
    
  2. Подключите сеть к поду и укажите созданный IPAddress в ipAddressNames:

    apiVersion: v1
    kind: Pod
    metadata:
      name: app-with-static-ip
      namespace: my-namespace
      annotations:
        network.deckhouse.io/networks-spec: |
          [
            {
              "type": "Network",
              "name": "my-network",
              "ifName": "net1",
              "ipAddressNames": ["app-net1-static"]
            }
          ]
    spec:
      containers:
        - name: app
          image: nginx
    

Как проверить, что IP-адрес назначен на интерфейс

Чтобы проверить, что IP-адрес назначен на интерфейс, выполните следующие шаги:

  1. Проверьте выделенный адрес и фазу у IPAddress (фаза должна быть Allocated):

    d8 k -n my-namespace get ipaddress app-net1-static -o yaml
    

    Пример вывода:

    NAME               TYPE   KIND      NAME    ADDRESS        NETWORK           PHASE       AGE
    ipaddress-auto-1   Auto   Network   mynet   192.168.12.1   192.168.12.0/24   Allocated   4d1h
    ipaddress-auto-2   Auto   Network   mynet   192.168.12.2   192.168.12.0/24   Allocated   4d1h
    
  2. Проверьте аннотацию пода network.deckhouse.io/networks-status (включая ipAddressConfigs и маршруты):

    d8 k -n my-namespace get pod app-with-static-ip -o jsonpath='{.metadata.annotations.network\.deckhouse\.io/networks-status}   ' | jq
    

    Пример вывода:

    [
      {
        "type": "Network",
        "name": "mynet",
        "ifName": "aabbcc",
        "mac": "ae:1c:68:7a:00:8f",
        "vlanID": 0,
        "ipAddressConfigs": [
          {
            "name": "ipaddress-auto-1",
            "address": "192.168.12.1",
            "network": "192.168.12.0/24"
          }
        ],
        "conditions": [
          {
            "type": "Configured",
            "status": "True",
            "lastTransitionTime": "2026-02-26T10:06:49Z",
            "reason": "InterfaceConfiguredSuccessfully",
            "message": ""
          },
          {
            "type": "Negotiated",
            "status": "True",
            "lastTransitionTime": "2026-02-26T10:06:49Z",
            "reason": "Up",
            "message": ""
          }
        ]
      }
    ]
    

Подключение физических сетевых интерфейсов к подам (DPDK-приложения)

Для использования физических сетевых интерфейсов (PF/VF) напрямую в поды для DPDK-приложений необходимо:

  1. Убедиться, что ваш namespace был помечен администратором для использования UnderlayNetwork (см. Руководство администратора)
  2. Создать под c аннотацией, запрашивающей устройство из UnderlayNetwork

Создание пода c устройством из UnderlayNetwork

Создайте под, который запрашивает устройство из UnderlayNetwork. В аннотации пода network.deckhouse.io/networks-spec должно быть указано:

  • type: "UnderlayNetwork" — указывает, что это запрос физического устройства;
  • name: "underlay-network-name" — имя ресурса UnderlayNetwork, созданного администратором;
  • bindingMode — режим привязки устройства (VFIO-PCI, DPDK или NetDev).

Пример конфигурации пода для режима DPDK (универсальный режим, который автоматически выбирает подходящий драйвер для вендора сетевого адаптера):

apiVersion: v1
kind: Pod
metadata:
  name: dpdk-app
  namespace: mydpdk
  annotations:
    network.deckhouse.io/networks-spec: |
      [
        {
          "type": "UnderlayNetwork",
          "name": "dpdk-shared-network",
          "bindingMode": "DPDK"
        }
      ]
spec:
  containers:
  - name: dpdk-container
    image: dpdk-app:latest
    securityContext:
      privileged: false
      capabilities:
        add:
        - NET_ADMIN
        - NET_RAW
        - IPC_LOCK
    volumeMounts:
    - mountPath: /hugepages
      name: hugepage
    resources:
      limits:
        hugepages-2Mi: 4Gi
        memory: 4Gi
        cpu: 4
      requests:
        cpu: 4
        memory: 4Gi
    command: ["/bin/sh", "-c", "sleep infinity"]
  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages

Для DPDK-приложений важно:

  • Настроить capabilities (NET_ADMIN, NET_RAW, IPC_LOCK) для запуска в непривилегированном режиме вместо использования privileged: true
  • Подключить volumes с hugepages, так как DPDK требует hugepages для эффективного управления памятью

Для VF устройств в режиме Shared можно дополнительно указать vlanID в аннотации для настройки VLAN-тегирования на VF:

network.deckhouse.io/networks-spec: |
  [
    {
      "type": "UnderlayNetwork",
      "name": "dpdk-shared-network",
      "bindingMode": "VFIO-PCI",
      "vlanID": 100
    }
  ]

После создания пода убедитесь, что устройство было выделено, проверив аннотацию network.deckhouse.io/networks-status:

d8 k -n mydpdk get pod dpdk-app -o jsonpath='{.metadata.annotations.network\.deckhouse\.io/networks-status}' | jq

Вы также можете проверить ResourceClaim, который был автоматически создан:

d8 k -n mydpdk get resourceclaim
Пример статуса пода с выделенным устройством UnderlayNetwork
apiVersion: v1
kind: Pod
metadata:
  name: dpdk-app
  namespace: mydpdk
  annotations:
    network.deckhouse.io/networks-spec: |
      [
        {
          "type": "UnderlayNetwork",
          "name": "dpdk-shared-network",
          "bindingMode": "DPDK"
        }
      ]
    network.deckhouse.io/networks-status: |
      [
        {
          "type": "UnderlayNetwork",
          "name": "dpdk-shared-network",
          "bindingMode": "DPDK",
          "netDevInterfaces": [
            {
              "name": "ens1f0",
              "mac": "00:1b:21:bb:aa:cc"
            }
          ],
          "conditions": [
            {
              "type": "Configured",
              "status": "True",
              "reason": "InterfaceConfiguredSuccessfully",
              "message": "",
              "lastTransitionTime": "2025-01-15T10:35:00Z"
            },
            {
              "type": "Negotiated",
              "status": "True",
              "reason": "Up",
              "message": "",
              "lastTransitionTime": "2025-01-15T10:35:00Z"
            }
          ]
        }
      ]
status:
  phase: Running
  ...