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>
|