Add support for multus and sriov CNI, device plugins
This commit adds support for the Multus, SRIOV CNI, and SRIOV device plugins plugins. It is intended that these would be used outside of the stx-openstack application, to pass through devices for a user defined container. The Multus CNI plugin enables attaching multiple network interfaces to pods in Kubernetes The SRIOV CNI plugin allows passing through of an SRIOV VF to a container, with support for IP, vlan, DPDK configuration. The SRIOV device plugin is a kubernetes device plugin for discovering and advertising SRIOV VFs in a Kubernetes host. Sysinv changes have been made to populate the SRIOV device plugin configuration file with appropriate values based on the host's configured PCI-PT and SRIOV interfaces. To enable SRIOV interfaces in a container, the user would create a custom multus NetworkAttachmentDefinition with type 'sriov' and refer to it in the Pod's k8s.vi.cni.cncf.io/networks annotation. A few sample NetworkAttachmentDefinition and pod deployments can be found here: https://github.com/intel/sriov-network-device-plugin Story: 2005208 Task: 29983 Task: 30054 Co-Authored-By: Litao Gao <litao.gao@windriver.com> Co-Authored-By: Jackie Huang <jackie.huang@windriver.com> Change-Id: I01587af6a4dc40fe7542b140e5bbee539d93740f Signed-off-by: Steven Webster <steven.webster@windriver.com>
This commit is contained in:
@@ -1540,6 +1540,7 @@ CONTROL_PLANE_LABEL = 'openstack-control-plane=enabled'
|
||||
COMPUTE_NODE_LABEL = 'openstack-compute-node=enabled'
|
||||
OPENVSWITCH_LABEL = 'openvswitch=enabled'
|
||||
SRIOV_LABEL = 'sriov=enabled'
|
||||
SRIOVDP_LABEL = 'sriovdp=enabled'
|
||||
|
||||
# Default DNS service domain
|
||||
DEFAULT_DNS_SERVICE_DOMAIN = 'cluster.local'
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
from sysinv.common import constants
|
||||
@@ -14,6 +15,7 @@ from sysinv.common import utils
|
||||
from sysinv.openstack.common import log as logging
|
||||
|
||||
from sysinv.puppet import base
|
||||
from sysinv.puppet import interface
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@@ -77,6 +79,9 @@ class KubernetesPuppet(base.BasePuppet):
|
||||
# Update cgroup resource controller parameters for this host
|
||||
config.update(self._get_host_k8s_cgroup_config(host))
|
||||
|
||||
# Update PCI device plugin parameters for this host
|
||||
config.update(self._get_host_pcidp_config(host))
|
||||
|
||||
if host.personality != constants.WORKER:
|
||||
return config
|
||||
|
||||
@@ -202,3 +207,66 @@ class KubernetesPuppet(base.BasePuppet):
|
||||
})
|
||||
|
||||
return config
|
||||
|
||||
def _get_host_pcidp_config(self, host):
|
||||
config = {}
|
||||
if constants.WORKER not in utils.get_personalities(host):
|
||||
return config
|
||||
|
||||
labels = self.dbapi.label_get_by_host(host.uuid)
|
||||
sriovdp_worker = False
|
||||
for l in labels:
|
||||
if (constants.SRIOVDP_LABEL ==
|
||||
str(l.label_key) + '=' + str(l.label_value)):
|
||||
sriovdp_worker = True
|
||||
break
|
||||
|
||||
if (sriovdp_worker is True):
|
||||
config.update({
|
||||
'platform::kubernetes::worker::pci::pcidp_network_resources':
|
||||
self._get_pcidp_network_resources(),
|
||||
})
|
||||
return config
|
||||
|
||||
def _get_network_interfaces_by_class(self, ifclass):
|
||||
# Construct a list of all configured interfaces of a particular class
|
||||
interfaces = []
|
||||
for iface in self.context['interfaces'].values():
|
||||
if iface['ifclass'] == ifclass:
|
||||
interfaces.append(iface)
|
||||
return interfaces
|
||||
|
||||
def _get_pcidp_network_resources_by_ifclass(self, ifclass):
|
||||
resources = {}
|
||||
|
||||
interfaces = self._get_network_interfaces_by_class(ifclass)
|
||||
for iface in interfaces:
|
||||
port = interface.get_interface_port(self.context, iface)
|
||||
datanets = interface.get_interface_datanets(self.context, iface)
|
||||
for datanet in datanets:
|
||||
dn_name = datanet['name'].strip()
|
||||
resource = resources.get(dn_name, None)
|
||||
if resource:
|
||||
# Add to the list of pci addreses for this data network
|
||||
resource['rootDevices'].append(port['pciaddr'])
|
||||
else:
|
||||
# PCI addresses don't exist for this data network yet
|
||||
resource = {dn_name: {
|
||||
"resourceName": "{}_net_{}".format(
|
||||
ifclass, dn_name).replace("-", "_"),
|
||||
"deviceType": "netdevice",
|
||||
"rootDevices": [port['pciaddr']],
|
||||
"sriovMode":
|
||||
ifclass == constants.INTERFACE_CLASS_PCI_SRIOV
|
||||
}}
|
||||
resources.update(resource)
|
||||
return list(resources.values())
|
||||
|
||||
def _get_pcidp_network_resources(self):
|
||||
# Construct a list of all PCI passthrough and SRIOV resources
|
||||
# for use with the SRIOV device plugin
|
||||
sriov_resources = self._get_pcidp_network_resources_by_ifclass(
|
||||
constants.INTERFACE_CLASS_PCI_SRIOV)
|
||||
pcipt_resources = self._get_pcidp_network_resources_by_ifclass(
|
||||
constants.INTERFACE_CLASS_PCI_PASSTHROUGH)
|
||||
return json.dumps({'resourceList': sriov_resources + pcipt_resources})
|
||||
|
||||
Reference in New Issue
Block a user