为虚拟机部署 Kubevirt DPDK 数据平面支持
总结 云原生 Contrail® 网络™ 支持部署 vRouter DPDK 数据板 (Kubevirt),以便在 Kubernetes 中实现高性能虚拟机和容器网络。
Kubevirt 概述
Kubevirt 是一个开源 Kubernetes 项目,支持对 Kubernetes 群集内的虚拟机工作负载 (VM) 和容器工作负载进行管理(调度)。Kubevirt 提供了一个统一的开发平台,开发人员可在通用共享环境中构建、修改和部署同时驻留在应用程序容器和虚拟机中的应用程序。Kubevirt 为您的 Kubernetes 群集提供以下附加功能:
- Kubevirt 在 Kubernetes API 服务器上添加了其他类型的 Pod 或自定义资源定义 (CRD)
- 用于集群范围逻辑的其他控制器,用于支持新型 Pod
- 用于节点特定逻辑的附加守护程序,用于支持新型 Pod
由于这种新功能,Kubevirt 创建和管理 VirtualMachineInstance
(VMI) 对象。VMIS 包含一个称为 VirtualMachine
(VM) 的工作负载控制器。虚拟机保持 VMI 的持久状态。这样用户便可在另一时间终止并启动虚拟机,而不会更改数据或状态。此外,您还可以在 Kubernetes 群集顶部部署 Kubevirt,使您可以管理传统容器工作负载以及由 Kubevirt 管理的 VMI。虚拟机可以访问 Kubernetes 群集功能,无需附加权限。
Kubevirt DPDK 实施
Kubevirt 通常不支持用户空间网络以实现快速数据包处理。但是,在云原生 Contrail 网络中,增强功能使 Kubevirt 能够支持 vhostuser
虚拟机的接口类型。这些接口使用 DPDK vRouter 执行用户空间网络,使 POD 能够访问 DPDK vRouter 提供的更高性能和数据包处理。
以下是 DPDK vRouter 应用程序的一些好处:
- 数据包处理发生在用户空间中,并绕过内核空间。这提高了数据包处理效率。
- 内核中断,且不会发生上下文交换机,因为数据包绕过内核空间。这样可减少 CPU 开销并提高数据吞吐量。
- DPDK 可在用户空间中增强 vRouter 的转发平面,从而提高性能。
- DPDK Lcore 在投票模式下运行。这使得 Lcore 能够在收到数据包后立即接收和处理这些数据包。
Deploy 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 也从叉子库中发布。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 叉。
在容器旁边启动虚拟机
借助 Kubevirt,在 Kubernetes 中启动和管理虚拟机类似于部署 Pod。您可以使用 kubectl
。创建虚拟机对象后,该虚拟机处于活动状态并在集群中运行。
使用以下高级步骤启动虚拟机和容器:
- 创建
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=