KubeVirt虚拟机资源超卖

SuKai June 18, 2022

使用过虚拟化平台的同学都知道,虚拟化平台可以通过KVM内存ballooning技术动态调整虚拟机的内存配置,实现运行所有VM总内存可以大于物理主机实际内存。当我们在Kubernetes平台通过KubeVirt管理虚拟机时,如何实现资源超卖呢?

基本概念

KubeVirt资源管理

Kubernetes通过Pod的Resource requests来申请占用资源,根据资源请求量Kubernetes计算主机节点资源进行Pod的调度。默认情况下KubeVirt根据虚拟机VM的资源请求从主机申请资源创建虚拟机virt-launcher Pod,Pod调度后调用libvirt创建对应虚拟机,通过这种方式达到了Kubernetes对虚拟机资源的管理和调度。

通过上面介绍,我们知道KubeVirt可以分开配置Pod的资源request与libvirt虚拟机资源,比如通过设置一个比例来达到虚拟机资源超卖。举例说明,如果我们设置内存超卖比例为150%,创建一个虚拟机内存为3072M,那么Pod请求内存资源则为2048M。假设主机内存为100G,不考虑其他组件资源开销,根据Pod请求则可以创建出内存总量为150G的虚拟机。

但由于KubeVirt目前还不支持Memory Ballooning技术,KubeVirt并没有像KVM调用libvirt获取当前内存使用量,动态调整libvirt中虚拟机分配内存。所以KubeVirt中的虚拟机内存占用了的内存无法减少来释放资源。

CPU时间

Kubernetes将CPU一个核切分为1000时间片,使用m作为单位,1m表示千分之一核milliCPU。

操作实践

KubeVirt配置资源分配比例

cpuAllocationRatio指定CPU分配比例2000%,比如虚拟机CPU核数为12核,Pod virt-launcher的CPU资源请求则为600m。memoryOvercommit指定内存分配比例为150%。

kubectl -n kubevirt edit kubevirt
...
spec:
  configuration:
    developerConfiguration:
      cpuAllocationRatio: 20
      featureGates:
      - HardDisk
      - DataVolumes
      memoryOvercommit: 150
...

创建KubeVirt虚拟机

可以看到spec.template.domain下的spec.template.domain.cpu和spec.template.domain.memory指定了创建虚拟机资源。

spec.template.domain.resources.overcommitGuestOverhead配置不请求额外资源开销,管理虚拟机的基础设施组件需要的内存资源。默认为false,当创建一个虚拟机内存为1Gi时,virt-launcher Pod请求的内存资源为1Gi + 200Mi。

spec.template.domain.resources.requests这里仍然指定了requests,virt-launcher Pod将使用这个requests来请求k8s资源,这样就会不使用上面配置的比例。一般情况不需要再这里指定requests,KubeVirt使用比例计算出requests的资源量。

---
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
  labels:
    kubevirt.io/vm: mailserver
  name: ubuntu-c
  namespace: mail263
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/vm: ubuntu-c
      annotations:
        ovn.kubernetes.io/ip_address: 172.16.3.203
        ovn.kubernetes.io/mac_address: 00:00:00:1F:C5:8F
    spec:
      domain:
        cpu:
          cores: 12
          model: host-passthrough
        memory:
          guest: 96Gi
        devices:
          disks:
          - name: bootdisk
            disk:
              bus: virtio
          - disk:
              bus: virtio
            name: cloudinitdisk
          interfaces:
          - name: default
            bridge: {}
            macAddress: 00:00:00:1f:c5:8f
        resources:
          overcommitGuestOverhead: true
          requests:
            memory: 16Gi
      networks:
      - name: default
        pod: {}
      terminationGracePeriodSeconds: 0
      volumes:
      - name: bootdisk
        dataVolume:
          name: ubuntuboot-c
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |-
            #cloud-config
            ssh_pwauth: True
            chpasswd:
              list: |
                ubuntu:ubuntu            

查看KubeVirt的ubuntu-c虚拟机VMI资源定义

spec:
  domain:
    cpu:
      cores: 12
      model: host-passthrough

    memory:
      guest: 96Gi
    resources:
      overcommitGuestOverhead: true
      requests:
        memory: 16Gi

查看virt-launcher Pod资源请求

可以看到CPU根据配置的比例2000%计算得到,内存根据requests指定值申请。

    resources:
      limits:
        devices.kubevirt.io/kvm: "1"
        devices.kubevirt.io/tun: "1"
        devices.kubevirt.io/vhost-net: "1"
      requests:
        cpu: 600m
        devices.kubevirt.io/kvm: "1"
        devices.kubevirt.io/tun: "1"
        devices.kubevirt.io/vhost-net: "1"
        ephemeral-storage: 50M
        memory: 16Gi

查看虚拟机系统资源

ubuntu@ubuntu-c:~$ free -m
              total        used        free      shared  buff/cache   available
Mem:          96575         290       95782           1         503       95442
Swap:             0           0           0
ubuntu@ubuntu-c:~$ top
top - 10:38:49 up 10:17,  1 user,  load average: 0.48, 0.20, 0.08
Tasks: 198 total,   1 running, 197 sleeping,   0 stopped,   0 zombie
%Cpu0  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu2  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu4  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu5  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu8  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu9  :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu10 :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu11 :  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  96575.3 total,  95781.5 free,    290.4 used,    503.4 buff/cache
MiB Swap:      0.0 total,      0.0 free,      0.0 used.  95441.8 avail Mem

总结

虽然KubeVirt目前还没有实现基于内存Ballooning技术的内存动态调整,但初步实现了资源超分的目标,毕竟一般虚拟机申请的资源并没有被完全使用。