为 VM 部署 Kubevirt DPDK 数据平面支持
总结 云原生 Contrail® 网络™ 支持在 Kubernetes 中部署 vRouter DPDK 数据平面 (Kubevirt),以实现高性能虚拟机和容器网络。
库贝维尔特概述
Kubevirt 是一个开源的 Kubernetes 项目,支持在 Kubernetes 集群中管理(调度)虚拟机工作负载 (VM) 以及容器工作负载。Kubevirt 提供了一个统一的开发平台,开发人员可以在其中构建、修改和部署驻留在公共共享环境中的应用程序容器和虚拟机中的应用程序。Kubevirt 为您的 Kubernetes 集群提供了以下附加功能:
- Kubevirt 将其他类型的 Pod 或自定义资源定义 (CRD) 添加到 Kubernetes API 服务器
- 用于群集范围逻辑的附加控制器,以支持新型 Pod
- 用于特定于节点的逻辑的其他守护程序,以支持新型 Pod
作为这项新功能的结果,Kubevirt 创建和管理 VirtualMachineInstance
(VMI) 对象。VMI 包含一个名为 (VM) 的 VirtualMachine
工作负载控制器。VM 将保持其 VMI 的持久状态。这使用户能够在其他时间终止和启动 VM,而无需更改数据或状态。此外,您可以将 Kubevirt 部署在 Kubernetes 集群之上,从而管理传统的容器工作负载以及由 Kubevirt 管理的 VMI。VM 可以访问 Kubernetes 群集功能,无需其他权限。
Kubevirt DPDK 实施
Kubevirt 通常不支持用于快速数据包处理的用户空间网络。然而,在云原生 Contrail 网络中,增强功能使 Kubevirt 能够支持 vhostuser
VM 的接口类型。这些接口与 DPDK 虚拟路由器执行用户空间联网,并使 Pod 能够访问 DPDK 虚拟路由器提供的增强性能和数据包处理。
以下是 DPDK 虚拟路由器应用程序的一些好处:
- 数据包处理在用户空间中进行,绕过内核空间。这提高了数据包处理效率。
- 不会发生内核中断和上下文切换,因为数据包会绕过内核空间。这样可以减少 CPU 开销并提高数据吞吐量。
- DPDK 增强了用户空间中 vRouter 的转发平面,提高了性能。
- DPDK 核心在轮询模式下运行。这使得 Lcore 能够在收到数据包后立即接收和处理数据包。
部署 Kubevirt
先决条件
您必须拥有活跃的 Kubernetes 集群并能够使用该 kubectl
客户端才能部署 Kubevirt。
部署云原生 Contrail 网络 Kubevirt Fork
当前的 Kubevirt 版本 (v0.48.0) 不支持启用 vhostuser
该接口的增强功能。瞻博网络维护着一个支持此 DPDK 接口的 Kubevirt 分叉。此 Kubevirt 分支适用于运行云原生 Contrail 网络的环境。对分叉的更改是在 Kubevirt 发行版 (v0.40.0) 之上提交的,并从分叉中标记为/发布为版本 (v.0.40.0-jnpr)。
Kubevirt 运算符和 Kubevirt CR 也从 fork 存储库中释放出来。Kubevirt 操作员管理 Kubevirt 核心组件的生命周期。Kubevirt 运算符和 CR 在您的集群中启用虚拟化。
使用以下命令部署 Kubevirt fork、Kubevirt CR 和 Kubevirt 运算符。记下发行版本 (v0.40.0) 和安装文件路径。
export RELEASE=v0.40.0-jnpr kubectl apply -f https://github.com/cijohnson/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml kubectl apply -f https://github.com/cijohnson/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml kubectl -n kubevirt wait kv kubevirt --for condition=Available
云原生 Contrail 网络 Kubevirt 分叉。
在容器旁边启动 VM
使用 Kubevirt,在 Kubernetes 中启动和管理虚拟机类似于部署 Pod。可以使用 创建 kubectl
虚拟机对象。创建 VM 对象后,该 VM 将处于活动状态并在群集中运行。
使用以下高级步骤在容器旁边启动 VM:
- 创建一个
VirtualNetwork
- 启动虚拟机
启动虚拟机
以下 VirtualMachine
规范是具有不同接口数量的实例的示例 VirtualMachine
。
- 单
vhostuser
界面虚拟机:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-single-virtio namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-single-virtio app: vm-single-virtio-app spec: nodeSelector: master: master terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=
vhostuser
多接口:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-multi-virtio namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-multi-virtio app: vm-multi-virtio-app spec: nodeSelector: worker: worker terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} - name: vhost-user-vn-green vhostuser: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue - name: vhost-user-vn-green multus: networkName: vn-green volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=
- 网桥/
vhostuser
接口虚拟机:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-virtio-veth namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-virtio-veth app: vm-virtio-veth-app spec: nodeSelector: master: master terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} - name: vhost-user-vn-green bridge: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue - name: vhost-user-vn-green multus: networkName: vn-green volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=
创建虚拟网络
以下 net-attach-def
对象是虚拟网络的示例。
apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: name: vn-blue namespace: contrail annotations: juniper.net/networks: '{ "ipamV4Subnet": "19.1.1.0/24" }' labels: vn: vn-blue-vn-green spec: config: '{ "cniVersion": "0.3.1", "name": "nad-blue", "type": "contrail-k8s-cni" }'
启动虚拟机
以下 VirtualMachine
规范是具有不同接口数量的实例的示例 VirtualMachine
。
- 单
vhostuser
界面虚拟机:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-single-virtio namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-single-virtio app: vm-single-virtio-app spec: nodeSelector: master: master terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=
vhostuser
多接口:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-multi-virtio namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-multi-virtio app: vm-multi-virtio-app spec: nodeSelector: worker: worker terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} - name: vhost-user-vn-green vhostuser: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue - name: vhost-user-vn-green multus: networkName: vn-green volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=
- 网桥/
vhostuser
接口虚拟机:apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachine metadata: name: vm-virtio-veth namespace: contrail spec: running: true template: metadata: labels: kubevirt.io/size: small kubevirt.io/domain: vm-virtio-veth app: vm-virtio-veth-app spec: nodeSelector: master: master terminationGracePeriodSeconds: 30 domain: cpu: sockets: 1 cores: 8 threads: 2 #dedicatedCpuPlacement: true memory: hugepages: pageSize: "2Mi" resources: requests: memory: "512Mi" devices: disks: - name: containerdisk disk: bus: virtio - name: cloudinitdisk disk: bus: virtio interfaces: - name: default bridge: {} - name: vhost-user-vn-blue vhostuser: {} - name: vhost-user-vn-green bridge: {} useVirtioTransitional: true networks: - name: default pod: {} - name: vhost-user-vn-blue multus: networkName: vn-blue - name: vhost-user-vn-green multus: networkName: vn-green volumes: - name: containerdisk containerDisk: image: svl-artifactory.juniper.net/atom-docker/dpdk-pktgen/vmdisks/dpdk-pktgen-auto:latest - name: cloudinitdisk cloudInitNoCloud: userDataBase64: SGkuXG4=