简单介绍下 KubeVirt

KubeVirt 简介

KubeVirt 是一个在 Kubernetes 上运行虚拟机(VM)的开源项目。它让 Kubernetes 不仅能管理容器,还能管理虚拟机,实现容器和虚拟机的混合管理。

之前只写了 KubeVirt 怎么安装,一直没写 KubeVirt 是什么,可以做什么,今天简单写下。

KVM

介绍 KubeVirt 之前先回顾一下 KVM。

KVM(Kernel-based Virtual Machine)Linux 内核 内置的一个虚拟化解决方案,它可以将 Linux 变成一个完整的虚拟机管理程序(Hypervisor),可以在 Linux 系统上运行多个完全隔离的虚拟机(VM)

在 Linux 上创建 KVM 虚拟机本质上就是启动一个 KVM 相关的进程:

[root@remote-rhel ~]# virsh list
 Id   Name         State
----------------------------
 1    DNS_Server   running
 3    ldap         running

[root@remote-rhel ~]# ps -ef | grep kvm | grep ldap
qemu        2206       1  2 Jan28 ?        23:35:26 /usr/libexec/qemu-kvm -name guest=ldap,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-3-ldap/master-key.aes"} -machine pc-q35-rhel9.4.0,usb=off,dump-guest-core=off,memory-backend=pc.ram,hpet=off,acpi=on -accel kvm -cpu host,migratable=on -m size=2097152k -object {"qom-type":"memory-backend-ram","id":"pc.ram","size":2147483648} -overcommit mem-lock=off -smp 2,sockets=2,cores=1,threads=1 -uuid 1be408f4-f8f1-4a49-a878-5e8acd73cfa2 -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=30,server=on,wait=off -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-shutdown -global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot strict=on -device {"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"} -device {"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"} -device {"driver":"pcie-root-port","port":18,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x2"} -device {"driver":"pcie-root-port","port":19,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x2.0x3"} -device {"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"} -device {"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"} -device {"driver":"pcie-root-port","port":22,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x2.0x6"} -device {"driver":"pcie-root-port","port":23,"chassis":8,"id":"pci.8","bus":"pcie.0","addr":"0x2.0x7"} -device {"driver":"pcie-root-port","port":24,"chassis":9,"id":"pci.9","bus":"pcie.0","multifunction":true,"addr":"0x3"} -device {"driver":"pcie-root-port","port":25,"chassis":10,"id":"pci.10","bus":"pcie.0","addr":"0x3.0x1"} -device {"driver":"pcie-root-port","port":26,"chassis":11,"id":"pci.11","bus":"pcie.0","addr":"0x3.0x2"} -device {"driver":"pcie-root-port","port":27,"chassis":12,"id":"pci.12","bus":"pcie.0","addr":"0x3.0x3"} -device {"driver":"pcie-root-port","port":28,"chassis":13,"id":"pci.13","bus":"pcie.0","addr":"0x3.0x4"} -device {"driver":"pcie-root-port","port":29,"chassis":14,"id":"pci.14","bus":"pcie.0","addr":"0x3.0x5"} -device {"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"} -device {"driver":"virtio-serial-pci","id":"virtio-serial0","bus":"pci.3","addr":"0x0"} -blockdev {"driver":"file","filename":"/data/vm_pool/ldap.qcow2","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage","backing":null} -device {"driver":"virtio-blk-pci","bus":"pci.4","addr":"0x0","drive":"libvirt-1-format","id":"virtio-disk0","bootindex":1} -netdev {"type":"tap","fd":"31","vhost":true,"vhostfd":"33","id":"hostnet0"} -device {"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:74:b9:92","bus":"pci.1","addr":"0x0"} -chardev pty,id=charserial0 -device {"driver":"isa-serial","chardev":"charserial0","id":"serial0","index":0} -chardev socket,id=charchannel0,fd=28,server=on,wait=off -device {"driver":"virtserialport","bus":"virtio-serial0.0","nr":1,"chardev":"charchannel0","id":"channel0","name":"org.qemu.guest_agent.0"} -device {"driver":"usb-tablet","id":"input0","bus":"usb.0","port":"1"} -audiodev {"id":"audio1","driver":"none"} -vnc 127.0.0.1:2,audiodev=audio1 -device {"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pcie.0","addr":"0x1"} -global ICH9-LPC.noreboot=off -watchdog-action reset -device {"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"} -object {"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"} -device {"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"} -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on

容器

说完 KVM 我们再说说容器。

容器(Container) 是一种轻量级、可移植的虚拟化技术,它可以在同一个操作系统内核上运行多个独立的应用程序,而不会相互影响。容器提供了进程级别的隔离,但不会像传统虚拟机(VM)那样运行完整的操作系统,因此更高效、更轻量

所以容器的本质也是运行进程,只不过通过 Linux 的一些功能(Namespace、Cgroups、UnionFS、Container Runtime 等)实现了隔离,但是运行一个容器就是运行一个进程,只不过容器在实现隔离的时候性能损耗较少。

[root@prometheus ~]# podman exec -it prometheus ps -ef
PID   USER     TIME  COMMAND
    1 nobody    4h58 /bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.enable-admin-api --web.enable-lifecycle --web.console.libraries=/usr/share/prometheus/console_libraries --web.console
   20 nobody    0:00 ps -ef

Kubernetes

再说说 Kubernetes。现在容器很强也很火,Kubernetes 现在也是容器编排的事实标准,但是 Kubernetes 的出现是解决多节点的容器编排,Kubernetes 有很多优点:

  • 支持自动化部署,回滚
  • 天生支持高可用和自愈
  • 支持水平垂直扩展
  • 自带启动、存活和就绪探针,支持健康检测
  • 自带 Service,还可以部署 Ingress,实现四、七层的负载均衡

还有很多,不一一列举了。可以看到 Kubernetes 很强大,但是想要把业务运行在 Kubernetes 就必须要把原有的业务做容器化处理。

如果有一个业务,现在没办法立刻容器化或者由于其他的一些原因无法去做容器化。那么就很可惜,没办法享受到 Kubernetes 带来的便利,有没有一种办法让 Kubernetes 来管理虚拟机呢?答案是有。

KubeVirt

Kubernetes 为什么能够运行虚拟机?

上边说了 KVM 和 容器。KVM 是一个进程,容器又能以一个很低的性能损耗来运行进程,那么容器运行 KVM 进程不就相当于容器运行虚拟机了么,容器和 KVM 都是比较成熟的技术了,所以容器运行虚拟机的稳定性也不是问题。

既然容器能运行虚拟机,Kubernetes 又是容器编排工具,那 Kubernetes 运行虚拟机也不是问题,麻烦的是怎么透过 POD 管理虚拟机。

为了解决这个问题,在 2016 年就有三个 Red Hat 的工程师探索 Kubernetes 运行虚拟机是否可行。然后,开源项目 KubeVirt 就出现了,简单说说这个项目的历史:

时间 事件 & 发展
2016 Red Hat 内部启动 KubeVirt,探索在 Kubernetes 运行虚拟机的可能性。
2017 年 6 月 Red Hat 开源 KubeVirt,提交到 GitHub,项目正式启动。
2018 年 Red Hat 发布的 OpenShift 版本开始推出容器原生虚拟化解决方案(OpenShift Virtualization)
2019 年 9 月 进入 CNCF(云原生计算基金会)Sandbox 阶段,成为云原生生态的一部分。
2022 年 4 月 CNCF 将 KubeVirt 提升为孵化项目,成为主流 Kubernetes 生态的一部分。
2025+ 广泛集成到 OpenShift、OKD、Rancher,支持 K8s 上的混合应用(VM + Pod)。

KubeVirt 可以实现什么?

图片来源官网:https://kubevirt.io/user-guide/architecture/

简化的架构图

KubeVirt 实现的效果

在上图可以看到有了 KubeVirt 后,虚拟机和容器共存变成了可能,这样有以下好处:

  • 通过 Kubernetes 统一管理虚拟机和容器,不再需要虚拟机一个平台,容器一个平台,简化了管理
  • 虚拟机可以通过 K8S 的探针检查和容器编排实现自动回复和高可用
  • 虚拟机可以使用 K8S 的 Service 和 Ingress 的四层和七层代理
  • 可以先以虚拟机的方式将业务迁移到 K8S,作为业务上 K8S 的过度
  • 使用的组件均是开源的,特别是 KVM,多数云和虚拟化厂商都是以 KVM 为基础,不存在厂商绑定。

KubeVirt 架构

图片来源官网:https://kubevirt.io/user-guide/architecture/

架构图

KubeVirt 相关组件和调用流程

通过官网的图可以看到,KubeVirt 为 Kubernetes 添加了一些新的资源,在管理节点添加了 virt-apivirt-controller,在工作节点添加了 virt-handler

  • virt-api 作用:

    virt-api 是 KubeVirt 的 API 服务,提供 VM 相关的 REST API(类似 kube-apiserver)接口。

  • virt-controller 作用:

    virt-controller 是 KubeVirt 的核心控制器,负责调度和管理虚拟机(VM & VMI)(类似 kube-controller-manager)。

  • virt-handler 作用:

    virt-handler 是 KubeVirt 的 VM 运行时管理器,负责创建管理虚拟机(VMI)(类似 kubelet

组件 作用 关键功能
virt-controller 负责 VM 生命周期管理 创建、删除、调度 VMI;Live Migration;协调 virt-handler
virt-api 提供 KubeVirt API 接口 处理 kubectl 和 REST API 请求;权限控制;与 virt-controller 交互
virt-handler 运行 VM 在节点上创建 KVM/QEMU 进程,管理 VM 运行状态,执行迁移

所以创建流程如下:

  1. 用户通过 kubectl 通过 API Servervirt-api 发起创建虚拟机任务;
  2. virt-controller 监听 VirtualMachine 资源(通过 Kubernetes 的 watcher 机制),创建 VMI 资源,并通过 kube-scheduler 进行调度;
  3. virt-handler 通过 watcher 机制监听 VMI 资源,来创建对应的 virt-launcher Pod,virt-launcher Pod 内运行虚拟机。

virt-launcher Pod 内的容器运行 virt-launcher 进程来启动并控制 libvirtdqemu 进程。

[root@base-k8s-master-1 ~]# kubectl exec -it virt-launcher-my-vm-hszfs -- /bin/bash
bash-5.1$ ps -ef
UID          PID    PPID  C STIME TTY          TIME CMD
qemu           1       0  0 Mar04 ?        00:00:00 /usr/bin/virt-launcher-monitor --qemu-timeout 285s --name my-vm --uid 76d04b17-b1e1-4abd-94da-c290fbfc2e93 --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-d
qemu          12       1  0 Mar04 ?        00:00:32 /usr/bin/virt-launcher --qemu-timeout 285s --name my-vm --uid 76d04b17-b1e1-4abd-94da-c290fbfc2e93 --namespace default --kubevirt-share-dir /var/run/kubevirt --ephemeral-disk-dir /var/
qemu          23      12  0 Mar04 ?        00:00:00 /usr/sbin/virtlogd -f /etc/libvirt/virtlogd.conf
qemu          24      12  0 Mar04 ?        00:00:22 /usr/sbin/virtqemud -f /var/run/libvirt/virtqemud.conf
qemu          68       1  0 Mar04 ?        00:05:05 /usr/libexec/qemu-kvm -name guest=default_my-vm,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/run/kubevirt-private/libvirt/qemu/lib/dom
qemu          80       0  0 04:35 pts/0    00:00:00 /bin/bash
qemu          86      80  0 04:35 pts/0    00:00:00 ps -ef

这里多说一个,关闭虚拟机可以通过 virtctl stop 来关闭,除了这个方法通过 kubectl delete pod 正常删除 virt-launcher Pod 也是正常关闭,删除时 Pod 会给内部容器发送 SIGTERM 信号,SIGTERM 信号会触发虚拟机正常关机,强制关机就在删除时加 --force 参数。

简单介绍下 KubeVirt
https://www.linuxstudynotes.com/2025/03/05/k8s/%e7%ae%80%e5%8d%95%e4%bb%8b%e7%bb%8d%e4%b8%8b-kubevirt/
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇