KubeVirt
简体中文 | English
介绍
Spiderpool 能保证 kubevirt VM 的 Pod 在重启、重建场景下,持续获取到相同的 IP 地址。
KubeVirt 网络搭配
Spiderpool underlay 网络解决方案可给 KubeVirt 赋予介入 underlay 的能力:
-
对于 KubeVirt 的 passt 网络模式,可搭配 Spiderpool macvlan 集成方案使用。在该网络模式下,支持 Service Mesh 的所有功能,不过只能使用**单网卡**,且不支持热迁移。
-
对于 KubeVirt 的 bridge 网络模式,可搭配 OVS CNI 使用。在该网络模式下,不支持 Service Mesh 功能,可使用**多网卡**,不支持热迁移。
KubeVirt VM 固定地址
KubeVirt VM 会在以下一些场景中会出现固定地址的使用:
-
VM 的热迁移,期望迁移过后的 VM 仍能继承之前的 IP 地址。
-
VM 资源对应的 Pod 出现了重启的情况。
-
VM 资源对应的 VMI(VirtualMachineInstance) 资源被删除的情景。
此外,KubeVirt VM 固定 IP 地址与 StatefulSet 的表现形式是不一样的:
-
对于 VM ,Pod 重启前后,其 Pod 的名字是会发生变化的,但是其对应的 VMI 不论重启与否,其名字都不会发生变化。因此,我们将会以 VM 为单位来记录其固定的 IP 地址(我们的 SpiderEndpoint 资源将会继承使用 VM 资源的命名空间以及名字)。
-
对于 StatefulSet,Pod 副本重启前后,其 Pod 名保持不变,我们 Spiderpool 会因此以 Pod 为单位来记录其固定的 IP 地址。
该功能默认开启。若开启,无任何限制,VM 可通过有限 IP 地址集合的 IP 池来固化 IP 的范围,但是,无论 VM 是否使用固定的 IP 池,它的 Pod 都可以持续分到相同 IP。 若关闭,VM 对应的 Pod 将被当作无状态对待,使用 Helm 安装 Spiderpool 时,可通过
--set ipam.enableKubevirtStaticIP=false
关闭。
实施要求
-
一套 Kubernetes 集群。
-
已安装 Helm。
步骤
以下流程将会演示 KubeVirt 的 passt 网络模式搭配 macvlan CNI 以使得 VM 获得 underlay 接入能力,并通过 Spiderpool 实现分配固定 IP 的功能。
Notice:当前 macvlan 和 ipvlan 并不适用于 KubeVirt 的 bridge 网络模式,因为对于 bridge 网络模式会将 Pod 网卡的 MAC 地址移动到 VM,使得 Pod 使用另一个不同的地址。而 macvlan 和 ipvlan CNI 要求 Pod 的网卡接口具有原始 MAC 地址。
安装 Spiderpool
请参考 Macvlan Quick Start 安装 Spiderpool. 其中,可确保 helm 安装选项 ipam.enableKubevirtStaticIP=true
创建 KubeVirt VM 应用
underlay 单网卡场景
以下的示例 Yaml 中,会创建 1 个使用 KubeVirt passt 网络模式搭配 macvlan 的 KubeVirt VM 应用,其中:
v1.multus-cni.io/default-network
:为应用选择一张默认网卡的 CNI 配置。
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-cirros
labels:
kubevirt.io/vm: vm-cirros
spec:
runStrategy: Always
template:
metadata:
annotations:
v1.multus-cni.io/default-network: kube-system/macvlan-ens192
labels:
kubevirt.io/vm: vm-cirros
spec:
domain:
devices:
disks:
- name: containerdisk
disk:
bus: virtio
- name: cloudinitdisk
disk:
bus: virtio
interfaces:
- name: default
passt: {}
resources:
requests:
memory: 64M
networks:
- name: default
pod: {}
volumes:
- name: containerdisk
containerDisk:
image: quay.io/kubevirt/cirros-container-disk-demo
- name: cloudinitdisk
cloudInitNoCloud:
userData: |
#!/bin/sh
echo 'printed from cloud-init userdata'
最终,在 KubeVirt VM 应用被创建时,Spiderpool 会从指定 IPPool 中随机选择一个 IP 来与应用形成绑定关系。
~# kubectl get spiderippool
NAME VERSION SUBNET ALLOCATED-IP-COUNT TOTAL-IP-COUNT DEFAULT
test-ippool 4 10.6.0.0/16 1 10 false
~# kubectl get po -l vm.kubevirt.io/name=vm-cirros -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
virt-launcher-vm-cirros-rg6fs 2/2 Running 0 3m43s 10.6.168.105 node2 <none> 1/1
重启 KubeVirt VM Pod, 观察到新的 Pod 的 IP 不会变化,符合预期。
~# kubectl delete pod virt-launcher-vm-cirros-rg6fs
pod "virt-launcher-vm-cirros-rg6fs" deleted
~# kubectl get po -l vm.kubevirt.io/name=vm-cirros -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
virt-launcher-vm-cirros-d68l2 2/2 Running 0 1m21s 10.6.168.105 node2 <none> 1/1
重启 KubeVirt VMI,观察到后续新的 Pod 的IP 也不会变化,符合预期。
~# kubectl delete vmi vm-cirros
virtualmachineinstance.kubevirt.io "vm-cirros" deleted
~# kubectl get po -l vm.kubevirt.io/name=vm-cirros -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
virt-launcher-vm-cirros-jjgrl 2/2 Running 0 104s 10.6.168.105 node2 <none> 1/1
VM 也可与其他 underlay Pod 的通信。
~# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daocloud-2048-5855b45f44-bvmdr 1/1 Running 0 5m55s 10.6.168.108 spider-worker <none> <none>
~# kubectl virtctl console vm-cirros
$ ping -c 1 10.6.168.108
PING 10.6.168.108 (10.6.168.108): 56 data bytes
64 bytes from 10.6.168.108: seq=0 ttl=255 time=70.554 ms
--- 10.6.168.108 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 70.554/70.554/70.554 ms
VM 也可访问 cluster IP。
~# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
daocloud-2048-svc ClusterIP 10.233.36.38 <none> 80/TCP 3m50s app=daocloud-2048
~# curl -I 10.233.36.38:80
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Tue, 17 Oct 2023 06:50:04 GMT
Content-Type: text/html
Content-Length: 4090
Last-Modified: Tue, 17 Oct 2023 06:40:53 GMT
Connection: keep-alive
ETag: "652e2c75-ffa"
Accept-Ranges: bytes
underlay 多网卡场景
以下的示例 Yaml 中,会创建 1 个使用 KubeVirt bridge 网络模式搭配 ovs-cni 的 KubeVirt VM 应用,其中:
ipam.spidernet.io/ippools
: 为应用指定每张网卡选择使用哪些 IP 池。(你也可使用 multus 实例中指定的 CNI 配置文件级别默认 IP 池)- 要求 multus 实例
kube-system/ovs-vlan30
和kube-system/ovs-vlan40
启用 coordinator 插件来协调多网卡默认路由。 - ovs-cni 不支持 clusterIP 访问。
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: vm-centos
spec:
runStrategy: Always
template:
metadata:
annotations:
ipam.spidernet.io/ippools: |-
[{
"ipv4": ["vlan30-v4-ippool"],
"ipv6": ["vlan30-v6-ippool"]
},{
"ipv4": ["vlan40-v4-ippool"],
"ipv6": ["vlan40-v6-ippool"]
}]
spec:
architecture: amd64
domain:
cpu:
cores: 1
model: host-model
sockets: 2
threads: 1
devices:
disks:
- disk:
bus: virtio
name: containerdisk
- disk:
bus: virtio
name: cloudinitdisk
interfaces:
- bridge: {}
name: ovs-bridge1
- bridge: {}
name: ovs-bridge2
features:
acpi:
enabled: true
machine:
type: q35
resources:
requests:
memory: 1Gi
networks:
- multus:
default: true
networkName: kube-system/ovs-vlan30
name: ovs-bridge1
- multus:
networkName: kube-system/ovs-vlan40
name: ovs-bridge2
volumes:
- name: containerdisk
containerDisk:
image: release-ci.daocloud.io/virtnest/system-images/centos-7.9-x86_64:v1
- cloudInitNoCloud:
networkData: |
version: 2
ethernets:
eth0:
dhcp4: true
eth1:
dhcp4: true
userData: |
#cloud-config
ssh_pwauth: true
disable_root: false
chpasswd: {"list": "root:dangerous", expire: False}
runcmd:
- sed -i "/#\?PermitRootLogin/s/^.*$/PermitRootLogin yes/g" /etc/ssh/sshd_config
name: cloudinitdisk
总结
Spiderpool 能保证 KubeVirt VM Pod 在重启、重建场景下,持续获取到相同的 IP 地址,能很好的满足 KubeVirt 虚拟机的固定 IP 需求。并可配合 macvlan 或 OVS CNI 与 KubeVirt 的多种网络模式实现 VM underlay 接入能力。