由 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技术的内存动态调整,但初步实现了资源超分的目标,毕竟一般虚拟机申请的资源并没有被完全使用。