1、Kubevirt 虚机 CPU 绑定配置
1.1 为 QEMU 模拟器分配独立 CPU 配置
在 KVM 虚拟机中,KVM 负责 CPU 和内存的虚拟化,不能模拟其他设备,对于 IO 设备(网卡、磁盘)的模拟,必须用到 QEMU 模拟器,但 QEMU 在模拟 IO 操作任务时,也要消耗 CPU 资源。因为 kubevirt 中 KVM 和 QEMU 默认跑在同一个 pod 中,所以他们会使用相同的 vCPU, 这样对 VMI 的性能会有影响。为了提供更好的性能,kubevirt 又额外为 QEMU 分配了一个 cpu ,这样模拟器和 VMI 所使用的 vCPU 相对独立。
开启这个功能需要在 VMI 的 yaml 配置文件 spec.domain.cpu 中添加 isolateEmulatorThread: true,并且需要和 dedicatedCpuPlacement: true 一起用。
apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachineInstance spec: domain: cpu: dedicatedCpuPlacement: true isolateEmulatorThread: true resources: limits: cpu: 2 memory: 2Gi |
1.2 为支持CPU绑定的 node 节点添加标签
在 yaml 配置文件里做了配置还不够,要想能调度到 node上,还要给支持 CPU 绑定的 node 手动添加标签 cpumanager=true
# 手动添加标签 kubectl label node [node_name] cpumanager=true # 查看标签 kubectl describe nodes |
1.3 配置 Kubevirt 识别支持 CPU 绑定的 node
为了让添加了 CPU manager 标签的 node 节点能被自动识别,还需要在 kubevirt-config 的 config map feature-gates下添加 CPUManager,或者编辑已存在的 kubevirt-config:
kubectl edit configmap kubevirt-config -n kubevirt # 举例: apiVersion: v1 kind: ConfigMap metadata: name: kubevirt-config namespace: kubevirt labels: kubevirt.io: "" data: feature-gates: "DataVolumes,CPUManager" |
1.4 Kubevirt 中使用 Sidecar 容器
Kubevirt 有时用 Sidecar 容器(伴生容器)来为 VMI 挂载磁盘,要想使用 Sidecar 伴生容器,kubevirt 需要在 kubevirt-config 的 ConfigMap feature-gates下添加 Sidecar 配置。
... data: feature-gates: "DataVolumes,CPUManager,Sidecar" |
伴生容器默认的资源是:CPU:200m, Memory:64M
因为 CPU 资源默认没有配成整数,所以 CPU manager 不会对伴生容器的 CPU 做绑定。
二、验证
2.1 编辑 VMI 的 yaml 配置文件
# vim vmi-cpu-pin-vm.yaml apiVersion: kubevirt.io/v1alpha3 kind: VirtualMachineInstance metadata: name: vmi-cpu-pin spec: terminationGracePeriodSeconds: 5 domain: cpu: sockets: 2 cores: 1 threads: 1 dedicatedCpuPlacement: true isolateEmulatorThread: true resources: requests: memory: 1024M devices: disks: - name: containerdisk disk: bus: virtio volumes: - name: containerdisk containerDisk: image: harbor.ctyun.dev:1443/kv-os/centos7-genericcloud:v1907 |
Kubevirt 虚机的 vCPU 数是用户设置的 spec.domain.cpu (sockets, cores, threads) 或 spec.domain.resources.[requests/limits].cpu 的值。
如果 spec.domain.cpu 设置了,vCPU 数是 sockets * cores * threads,如果 spec.domain.cpu 没设置,vCPU 数则取 spec.domain.resources.requests.cpu 或 spec.domain.resources.limits.cpu 的值。
提示:
(1)spec.domain.cpu 和 spec.domain.resources.[requests/limits].cpu 不需要同时设置;
(2)如果设置了spec.domain.resources.[requests/limits].cpu,spec.domain.resources.requests.cpu 和 spec.domain.resources.limits.cpu 的值必须一致;
(3)对于多 CPU 的情况,建议使用 spec.domain.cpu.sockets 代替 spec.domain.cpu.cores,性能会更好。
2.2 创建 VMI
# 创建 [ecf@server19 kubevirt]$ kubectl create -f vmi-cpu-pin.yaml virtualmachineinstance.kubevirt.io/vmi-cpu-pin created # 查看 [ecf@server19 kubevirt]$ kubectl get vmi NAME AGE PHASE IP NODENAME dcache 8d Running 10.244.0.44/24 server19 testvm 10d Running 10.244.0.17 server19 vmi-cpu-pin 23s Running 10.244.0.210 server19 |
2.3 进入 libvirt 容器查看 CPU 绑定情况
[ecf@server19 kubevirt]$ docker ps -a |grep vmi-cpu-pin 96e316cafadc a937ac91ab35 "/usr/bin/container-…" 50 seconds ago Up 44 seconds k8s_volumecontainerdisk_virt-launcher-vmi-cpu-pin-mgq6r_default_038ba55f-ced5-4d91-ad82-dbd7fcdc6475_0 6576d9f09468 c6672d186608 "/usr/bin/virt-launc…" 50 seconds ago Up 50 seconds k8s_compute_virt-launcher-vmi-cpu-pin-mgq6r_default_038ba55f-ced5-4d91-ad82-dbd7fcdc6475_0 c822eda00e62 k8s.gcr.io/pause:3.1 "/pause" 51 seconds ago Up 50 seconds k8s_POD_virt-launcher-vmi-cpu-pin-mgq6r_default_038ba55f-ced5-4d91-ad82-dbd7fcdc6475_0 # 进入容器 [ecf@server19 kubevirt]$ docker exec -it -u root k8s_compute_virt-launcher-vmi-cpu-pin-mgq6r_default_038ba55f-ced5-4d91-ad82-dbd7fcdc6475_0 /bin/bash [root@vmi-cpu-pin /]# virsh list Id Name State ------------------------------------- 1 default_vmi-cpu-pin running # libvirt 容器内查看虚机 xml 文件 [root@vmi-cpu-pin /]# virsh dumpxml 1 |more <domain type='kvm' id='1'> <name>default_vmi-cpu-pin</name> <uuid>b0a47815-bc43-4c45-bd43-0a1bb9441b62</uuid> <metadata> <kubevirt xmlns="http://kubevirt.io"> <uid>1307155b-05eb-4685-8a59-2eb39d1934aa</uid> <graceperiod> <deletionGracePeriodSeconds>5</deletionGracePeriodSeconds> </graceperiod> </kubevirt> </metadata> <memory unit='KiB'>1000448</memory> <currentMemory unit='KiB'>1000448</currentMemory> <vcpu placement='static'>2</vcpu> <iothreads>1</iothreads> <cputune> <vcpupin vcpu='0' cpuset='0'/> <vcpupin vcpu='1' cpuset='1'/> <emulatorpin cpuset='23'/> </cputune> |
2.4 查看 VMI 的 QoS 类
[ecf@server19 kubevirt]$ kubectl describe vmi vmi-cpu-pin Name: vmi-cpu-pin Namespace: default Labels: kubevirt.io/nodeName=server19 Annotations: kubevirt.io/latest-observed-api-version: v1alpha3 kubevirt.io/storage-observed-api-version: v1alpha3 API Version: kubevirt.io/v1alpha3 Kind: VirtualMachineInstance ...... Node Name: server19 Phase: Running Qos Class: Guaranteed Events: <none> |