在虚拟机的使用场景中,热迁移可以将虚拟机从一个节点迁移到另一个节点,以便进行诸如节点维护、系统升级和故障转移等操作。然而,KubeVirt 在热迁移过程中面临以下挑战:
-
KubeVirt 默认不支持Bridge网络模式虚拟机进行热迁移。
-
KubeVirt 本身仅处理内存和磁盘迁移,没有针对网络迁移进行特定优化。
-
若虚拟机的 IP 在迁移过程中发生变化,则无法实现无感热迁移。
-
若网络在迁移过程中中断,则无法实现无感热迁移。
Kube-OVN 通过在虚拟机迁移过程中针对上述问题进行了专门处理,用户能够实现无感知的热迁移。经过测试,网络中断时间可以控制在 0.5 秒以内,且不会出现 TCP 链接中断。
使用方法
用户只需在 VM Spec 中添加注解 kubevirt.io/allow-pod-bridge-network-live-migration: "true" 的annotation,Kube-OVN 将在网络迁移过程中自动处理。
1、创建VM
kubectl apply -f - <<EOF
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: testvm
spec:
runStrategy: Always
template:
metadata:
labels:
kubevirt.io/size: small
kubevirt.io/domain: testvm
annotations:
kubevirt.io/allow-pod-bridge-network-live-migration: "true"
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
bridge: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userDataBase64: SGkuXG4=
EOF
2、 SSH 进入虚拟机,并测试网络联通性
# password: gocubsgo
virtctl ssh cirros@testvm
ping 8.8.8.8
3、在另一个终端中执行迁移,并观察虚拟机的网络联通性
virtctl migrate testvm
可以观察到,在虚拟机热迁移过程中,SSH 连接保持不中断,且ping 只是偶尔出现丢包的情况。
热迁移原理
Kube-OVN在热迁移过程中借鉴了《实时迁移--通过多机箱端口绑定减少停机时间》的灵感。
为确保迁移过程中源虚拟机和目标虚拟机的网络一致,在迁移过程中网络中会同时存在两个相同的IP 地址。在这个过程中需要处理网络冲突和流量混乱的问题。具体步骤如下:
1、KubeVirt 发起迁移,并在目标机器上创建相应的 Pod。
2、Kube-OVN 检测到该 Pod 是热迁移的目标 Pod,并复用源 Pod 的网络端口信息。
3、Kube-OVN 设置流量复制,以便网络流量会同时复制到源 Pod 和目标 Pod。以减少网络切换时带来的中断时间。同时将目标 Pod 的网络端口暂时禁用,因此目标 Pod 实际上不会接收复制的流量,避免流量混乱。
4、KubeVirt 进行VM内存同步。
5、KubeVirt 完成内存同步并停用源Pod。此时,源 Pod 将不再处理网络流量。
6、KubeVirt 激活目标 Pod。此时,libvirt 发送 RARP 以激活目标 Pod 的网络端口,目标 Pod 开始处理流量。
7、KubeVirt 删除源 Pod,完成热迁移。Kube-OVN 通过Watch Migration CR监听迁移完成事件,并在迁移完成后停止流量复制。
在这个过程中,网络中断主要发生在步骤 5 和 6 之间。网络中断时间主要取决于 libvirt 发送 RARP 所需的时间。经过测试,网络中断时间可以控制在 0.5 秒以内,且由于 TCP 重试机制,TCP 连接不会中断。