KubeVirt 网络

Kubernetes 运行虚拟机的网络问题

如何保证访问 Pod 的流量转发给虚拟机

KubeVirt 使用 Pod 运行虚拟机,运行虚拟机很容易,运行个进程就行,但是如何保证流量能够正确的从 Pod 到虚拟机?

如何实现虚拟机多个网卡

虚拟机肯定不会只有一个网卡,那么 KubeVirt 如何实现虚拟机多个网卡?

简单说下

我们知道 Kubernetes 启动的 Pod 地址都是随机的,并且每次 Pod 重启地址都会变化。Kubernetes 通过 ServiceHeadless Service 来暴漏 Pod,然后可以通过 ServiceHeadless Service 来访问 Pod。

然后 KubeVirt 可以利用网桥或者 nftables 规则实现流量转发,保证到达 Pod 的流量能够全部发送给虚拟机,这样就保证虚拟机是可以访问的。

对于添加网卡,之前写过如何用 NMstate 和 Multus 为 Pod 添加网卡,KubeVirt 支持利用这两个组件来为虚拟机添加网卡。并且,Pod 的地址是不断变化的,但是虚拟机肯定不希望网卡地址是一直变化的,通过添加网卡这个方式就可以保证虚拟机地址是固定的。

image-20250308172219175

这个方法不仅仅只是一个开源的解决方案,在 KubeVirt 的商业版产品 Openshift Virtualization 中也是用这个方式实现虚拟机的网卡添加的。

KubeVirt 虚拟机支持的网卡类型

KubeVIrt 的虚拟机有如下几个网卡类型

  • masquerade
  • bridge
  • sriov

这里常用的是前两个。

类型 描述
bridge 使用 Linux 网桥进行连接
sriov 通过 vfio 使用直通 SR-IOV VF 进行连接
masquerade 使用 nftables 规则将流量连接到出口和入口的 NAT

一般情况下,创建虚拟机时,虚拟机网卡默认为 bridge 模式,且虚拟机第一个网卡默认和 Pod 网卡关联。

Masquerade 模式

Masquerade 模式下的地址状态

现在有一个虚拟机 vm-alpine,网卡为 Masquerade 模式。

[root@base-k8s-master-1 ~]# kubectl get vm vm-alpine -o jsonpath='{.spec.template.spec.domain.devices}' | jq
{
  "disks": [
    {
      "disk": {
        "bus": "virtio"
      },
      "name": "containerdisk"
    }
  ],
  "interfaces": [
    {
      "masquerade": {},
      "model": "virtio",
      "name": "default"
    }
  ]
}

查看运行虚拟机 Pod 的网卡信息:

[root@base-k8s-master-1 ~]# kubectl exec -it virt-launcher-vm-alpine-gs5mx -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 7a:50:cd:02:bf:9d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.100.223.30/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::7850:cdff:fe02:bf9d/64 scope link
       valid_lft forever preferred_lft forever
4: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.1/24 brd 10.0.2.255 scope global k6t-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc fq_codel master k6t-eth0 state UP group default qlen 1000
    link/ether 96:3d:3c:22:61:29 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::943d:3cff:fe22:6129/64 scope link
       valid_lft forever preferred_lft forever
[root@base-k8s-master-1 ~]# kubectl exec -it virt-launcher-vm-alpine-gs5mx -- ip route
default via 169.254.1.1 dev eth0
10.0.2.0/24 dev k6t-eth0 proto kernel scope link src 10.0.2.1
169.254.1.1 dev eth0 scope link

查看虚拟机内的网卡信息:

[root@base-k8s-master-1 ~]# virtctl console vm-alpine
Successfully connected to vm-alpine console. The escape sequence is ^]

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc pfifo_fast qlen 1000
    link/ether de:f1:44:95:72:ec brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.2/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::dcf1:44ff:fe95:72ec/64 scope link
       valid_lft forever preferred_lft forever

Pod 内有一个 10.0.2.1/24 的网卡 k6t-eth0,也有路由 10.0.2.0/24 dev k6t-eth0 proto kernel scope link src 10.0.2.1,虚拟机的地址是 10.0.2.2/24

可以看到虚拟机的网卡地址和 Pod 的不一样,访问虚拟机的时候中间会有 nft 将流量转发给虚拟机。

查看 nft 规则

# 查看虚拟机所在节点
[root@base-k8s-master-1 ~]# kubectl get vmi
NAME            AGE    PHASE     IP              NODENAME                        READY
vm-alpine       43h    Running   10.100.223.30   base-k8s-worker-1.example.com   True

# 查看虚拟机进程
[root@base-k8s-worker-1 ~]# ps -ef | grep qemu | grep vm-alpine
...output omitted...
qemu      116859  116552  0 Mar07 ?        00:03:29 /usr/libexec/qemu-kvm -name guest=default_vm-alpine,debug-threads=on ......

# 进入对应进程的网络 namespace
[root@base-k8s-worker-1 ~]# nsenter -t 116859 -n

# 查看 nft 规则
[root@base-k8s-worker-1 ~]# nft list ruleset
table ip nat {
        chain prerouting {
                type nat hook prerouting priority dstnat; policy accept;
                iifname "eth0" counter packets 3 bytes 180 jump KUBEVIRT_PREINBOUND
        }

        chain input {
                type nat hook input priority 100; policy accept;
        }

        chain output {
                type nat hook output priority -100; policy accept;
                ip daddr 127.0.0.1 counter packets 0 bytes 0 dnat to 10.0.2.2
        }

        chain postrouting {
                type nat hook postrouting priority srcnat; policy accept;
                ip saddr 10.0.2.2 counter packets 0 bytes 0 masquerade
                oifname "k6t-eth0" counter packets 6 bytes 340 jump KUBEVIRT_POSTINBOUND
        }

        chain KUBEVIRT_PREINBOUND {
                counter packets 3 bytes 180 dnat to 10.0.2.2
        }

        chain KUBEVIRT_POSTINBOUND {
                ip saddr 127.0.0.1 counter packets 0 bytes 0 snat to 10.0.2.1
        }
}

通过这些规则可以实现,访问 Pod 的 127.0.0.1 时,流量自动转发给 10.0.2.2,也就是虚拟机。

什么时候选择 Masquerade 模式?

使用 Pod 默认网卡的虚拟机网卡使用 Masquerade 模式。

在 Openshift Virtualization 中,要求虚拟机默认的连接 Pod 的网卡必须是 Masquerade 模式。

Bridge 模式

Bridge 模式下的地址状态

现在有一个虚拟机 vm-bridge,网卡为 Bridge 模式。

[root@base-k8s-master-1 kubevirt]# kubectl get vm vm-bridge -o jsonpath='{.spec.template.spec.domain.devices}' | jq
{
  "disks": [
    {
      "disk": {
        "bus": "virtio"
      },
      "name": "containerdisk"
    }
  ],
  "interfaces": [
    {
      "bridge": {},
      "model": "virtio",
      "name": "default"
    }
  ]
}

查看运行虚拟机 Pod 的网卡信息:

[root@base-k8s-master-1 kubevirt]# kubectl exec -it virt-launcher-vm-bridge-gdlf8 -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0-nic@if110: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue master k6t-eth0 state UP group default qlen 1000
    link/ether ca:da:2e:fb:67:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::c8da:2eff:fefb:6728/64 scope link
       valid_lft forever preferred_lft forever
4: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 16:98:43:25:4f:2c brd ff:ff:ff:ff:ff:ff
    inet 169.254.75.10/32 scope global k6t-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::c8da:2eff:fefb:6728/64 scope link
       valid_lft forever preferred_lft forever
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc fq_codel master k6t-eth0 state UP group default qlen 1000
    link/ether 16:98:43:25:4f:2c brd ff:ff:ff:ff:ff:ff
    inet6 fe80::1498:43ff:fe25:4f2c/64 scope link
       valid_lft forever preferred_lft forever
6: eth0: <BROADCAST,NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ether 9e:ca:72:f5:d2:cd brd ff:ff:ff:ff:ff:ff
    inet 10.100.171.29/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9cca:72ff:fef5:d2cd/64 scope link
       valid_lft forever preferred_lft forever

查看虚拟机内的网卡信息:

[root@base-k8s-master-1 kubevirt]# virtctl console vm-bridge
Successfully connected to vm-bridge console. The escape sequence is ^]

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc pfifo_fast qlen 1000
    link/ether 9e:ca:72:f5:d2:cd brd ff:ff:ff:ff:ff:ff
    inet 10.100.171.29/32 brd 10.255.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9cca:72ff:fef5:d2cd/64 scope link
       valid_lft forever preferred_lft forever

这个模式下虚拟机地址和 Pod 的一样,所有网卡都是通过 bridge 的方式连接。(这里有个奇怪的地方,Pod 里能看到一个和虚拟机网卡 MAC 地址一样的网卡,不知道为什么会存在这个网卡。)

[root@base-k8s-master-1 ~]# kubectl exec -it virt-launcher-vm-bridge-gdlf8 -- /bin/bash
bash-5.1$ virsh domiflist default_vm-bridge
Authorization not available. Check if polkit service is running or see debug message for more information.
 Interface   Type       Source   Model                     MAC
------------------------------------------------------------------------------
 tap0        ethernet   -        virtio-non-transitional   9e:ca:72:f5:d2:cd

bash-5.1$ /tmp/brctl show
bridge name     bridge id               STP enabled     interfaces
k6t-eth0                8000.169843254f2c       no              eth0-nic
                                                        tap0

和 Masquerade 不同,Bridge 模式的 Pod 没有路由信息,ip route 为空。

[root@base-k8s-master-1 kubevirt]# kubectl exec -it virt-launcher-vm-bridge-gdlf8 -- ip route

什么情况下选择 Bridge 模式?

一般除了第一块默认网卡外,其他的都用 Bridge 模式。

网卡 MAC 检测的 nftables 规则

之前在创建 NetworkAttachmentDefinition 的时候设置了 macspoofchk,表示开启 MAC 地址检查。

apiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
  name: linux-bridge-br-1
  namespace: default
spec:
  config: '{
      "name":"br-1",
      "type":"bridge",
      "cniVersion":"0.3.1",
      "bridge":"br-1",
      "macspoofchk":true,
      "ipam": {
          "type": "host-local",
          "subnet": "192.168.255.0/24",
          "routes": [
               {
                 "dst": "0.0.0.0/0",
                 "gw": "192.168.255.254"
               }
             ]
        },
      "preserveDefaultVlan":false
    }'

我们来看看 nftables 规则,当某个物理节点运行了带有 MAC 检测功能的网卡的 Pod 时,会添加 nftables 规则:

[root@base-k8s-master-1 ~]# ssh base-k8s-worker-1
[root@base-k8s-worker-1 ~]# nft list ruleset
...output omitted...
table bridge nat {
        chain PREROUTING {
                type filter hook prerouting priority dstnat; policy accept;
                iifname "vethe686a67c" jump cni-br-iface-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25 comment "macspoofchk-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25"
        }

        chain cni-br-iface-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25 {
                jump cni-br-iface-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25-mac comment "macspoofchk-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25"
        }

        chain cni-br-iface-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25-mac {
                ether saddr 7e:b2:29:d6:66:b3 return comment "macspoofchk-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25"
                drop comment "macspoofchk-cd8cc64d3f7f8fbd5027610a4ab78dec0c94479401005c760079613f112c25ad-pod6c270ef2f25"
        }
}

配置虚拟机网卡模式为 Masquerade 模式

虚拟机默认网卡模式为 bridge。

虚拟机的默认网卡(第一个网卡)一般是和 Pod 的网卡相关联,一般这个网卡需要修改为 Masquerade 模式。

虚拟机的 YAML 文件添加或修改成如下字段:

[root@base-k8s-master-1 kubevirt]# kubectl get vm vm-masquerade -o yaml
...output omitted...
spec:
  template:
    spec:
      domain:
        devices:
          interfaces:
          - masquerade: {}
            model: virtio
            name: default
      networks:
      - name: default
        pod: {}

重启虚拟机。

虚拟机网卡热插拔

https://kubevirt.io/user-guide/network/hotplug_interfaces/#hotplug-network-interfaces

先说三条官网的要求:

  • KubeVirt 支持将网络接口热插拔到运行中的虚拟机(VM)上。
  • 使用 virtio 模型通过网桥绑定或 SR-IOV 绑定连接的接口支持热插拔。
  • 只有通过网桥绑定连接的接口才支持热拔插。

v1.4 之前的版本需要开启 HotplugNICs 特性门控。

版本 v0.59.0 及更低版本的现有虚拟机不支持热拔出接口。

再说说对网络组件的要求:

  • Multus 动态网络控制器:该守护进程将侦听注释更改,并触发 Multus 为该 pod 配置新附件。
  • Multus CNI 作为厚插件运行:该 Multus 版本提供了一个端点,可按需为指定 pod 创建附件。

如果没有 Multus 条件,可以尝试使用热迁移的方式添加,热迁移能保证虚拟机不中断的情况下重建 Pod。

部署 multus-dynamic-networks-controller

之前写过部署 Kubernetes-nmstate 和 Multus-cni 以实现为 Pod 添加网卡。这个实现了网卡添加,但是只能在 Pod 创建的时候添加网卡,所以还需要补充一个 multus-dynamic-networks-controller。

Multus Dynamic Networks Controller 是 Multus CNI 的一个扩展组件,它的核心功能是动态管理 Pod 的附加网络在 Pod 运行时添加或删除网络接口,而无需重启 Pod

[root@base-k8s-master-1 multus-cni]# git clone https://github.com/k8snetworkplumbingwg/multus-dynamic-networks-controller.git
Cloning into 'multus-dynamic-networks-controller'...
remote: Enumerating objects: 14249, done.
remote: Counting objects: 100% (1032/1032), done.
remote: Compressing objects: 100% (397/397), done.
remote: Total 14249 (delta 758), reused 634 (delta 634), pack-reused 13217 (from 4)
Receiving objects: 100% (14249/14249), 19.26 MiB | 2.98 MiB/s, done.
Resolving deltas: 100% (6398/6398), done.
[root@base-k8s-master-1 multus-cni]# cd multus-dynamic-networks-controller/
[root@base-k8s-master-1 multus-dynamic-networks-controller]# kubectl apply -f manifests/dynamic-networks-controller.yaml
clusterrole.rbac.authorization.k8s.io/dynamic-networks-controller created
clusterrolebinding.rbac.authorization.k8s.io/dynamic-networks-controller created
serviceaccount/dynamic-networks-controller created
configmap/dynamic-networks-controller-config created
daemonset.apps/dynamic-networks-controller-ds created

为虚拟机添加新的网卡

在 VM 的 YAML 文件下添加字段:

[root@base-k8s-master-1 kubevirt]# kubectl get vm vm-masquerade -o yaml
...output omitted...
spec:
  template:
    spec:
      domain:
        devices:
          interfaces:
          - masquerade: {}
            model: virtio
            name: default
          - name: net1
            model: virtio
            bridge: {}
      networks:
      - name: default
        pod: {}
      - name: net1
        multus:
          networkName: linux-bridge-br-1

查看 VMI 信息:

[root@base-k8s-master-1 ~]# kubectl get vmi vm-masquerade -ojsonpath="{ @.status.interfaces }" | jq
[
  {
    "infoSource": "domain",
    "ipAddress": "10.100.171.36",
    "ipAddresses": [
      "10.100.171.36"
    ],
    "mac": "ba:66:90:ab:4d:5d",
    "name": "default",
    "queueCount": 1
  },
  {
    "infoSource": "domain, multus-status",
    "ipAddress": "192.168.255.106",
    "ipAddresses": [
      "192.168.255.106"
    ],
    "mac": "7a:2d:f9:35:a6:5e",
    "name": "net1",
    "queueCount": 1
  }
]

查看虚拟机网卡信息:

[root@base-k8s-master-1 ~]# virtctl console vm-masquerade
Successfully connected to vm-masquerade console. The escape sequence is ^]

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc pfifo_fast qlen 1000
    link/ether ba:66:90:ab:4d:5d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.2/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::b866:90ff:feab:4d5d/64 scope link
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
    link/ether 7a:2d:f9:35:a6:5e brd ff:ff:ff:ff:ff:ff

可以看到多了一个网卡。

再查看下 Pod 网卡信息:

[root@base-k8s-master-1 ~]kubectl exec -it virt-launcher-vm-masquerade-tmlft -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if134: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether ba:66:90:ab:4d:5d brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.100.171.36/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::b866:90ff:feab:4d5d/64 scope link
       valid_lft forever preferred_lft forever
4: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.1/24 brd 10.0.2.255 scope global k6t-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc fq_codel master k6t-eth0 state UP group default qlen 1000
    link/ether aa:df:af:de:1d:bb brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a8df:afff:fede:1dbb/64 scope link
       valid_lft forever preferred_lft forever
6: 6c270ef2f25-nic@if135: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master k6t-6c270ef2f25 state UP group default
    link/ether be:fa:93:c3:ed:86 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::bcfa:93ff:fec3:ed86/64 scope link
       valid_lft forever preferred_lft forever
7: k6t-6c270ef2f25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 9e:df:7f:90:61:e8 brd ff:ff:ff:ff:ff:ff
    inet 169.254.75.10/32 scope global k6t-6c270ef2f25
       valid_lft forever preferred_lft forever
    inet6 fe80::bcfa:93ff:fec3:ed86/64 scope link
       valid_lft forever preferred_lft forever
8: tap6c270ef2f25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master k6t-6c270ef2f25 state UP group default qlen 1000
    link/ether 9e:df:7f:90:61:e8 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::9cdf:7fff:fe90:61e8/64 scope link
       valid_lft forever preferred_lft forever
9: pod6c270ef2f25: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 7a:2d:f9:35:a6:5e brd ff:ff:ff:ff:ff:ff
    inet 192.168.255.106/24 brd 192.168.255.255 scope global pod6c270ef2f25
       valid_lft forever preferred_lft forever
    inet6 fe80::782d:f9ff:fe35:a65e/64 scope link
       valid_lft forever preferred_lft forever

如果发现没生效可以先用 virtctl restart 重启虚拟机看看,这个方法重启会重建 Pod。

虚拟机网卡热删除

在需要删除的网卡上添加一个字段 state: absent

[root@base-k8s-master-1 ~]# kubectl edit vm vm-masquerade
...output omitted...
spec:
  template:
    spec:
      domain:
        devices:
          interfaces:
...output omitted...
          - bridge: {}
            model: virtio
            name: net1
            state: absent   # 添加这个

然后去检查虚拟机:

[root@base-k8s-master-1 ~]# virtctl console vm-masquerade
Successfully connected to vm-masquerade console. The escape sequence is ^]

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc pfifo_fast qlen 1000
    link/ether 7e:57:47:45:cc:3a brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.2/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::7c57:47ff:fe45:cc3a/64 scope link
       valid_lft forever preferred_lft forever

再查看 Pod 的网卡:

[root@base-k8s-master-1 ~]# kubectl exec -it virt-launcher-vm-masquerade-fqvj4 -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: eth0@if89: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 4a:73:68:69:c0:2f brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 10.100.223.52/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::4873:68ff:fe69:c02f/64 scope link
       valid_lft forever preferred_lft forever
4: 6c270ef2f25-nic@if90: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 46:ae:57:a9:fa:b6 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::44ae:57ff:fea9:fab6/64 scope link
       valid_lft forever preferred_lft forever
5: k6t-eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc noqueue state UP group default qlen 1000
    link/ether 02:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.1/24 brd 10.0.2.255 scope global k6t-eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::ff:fe00:0/64 scope link
       valid_lft forever preferred_lft forever
6: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1480 qdisc fq_codel master k6t-eth0 state UP group default qlen 1000
    link/ether 66:f8:14:63:d4:15 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::64f8:14ff:fe63:d415/64 scope link
       valid_lft forever preferred_lft forever
KubeVirt 网络
https://www.linuxstudynotes.com/2025/03/11/k8s/kubevirt-%e7%bd%91%e7%bb%9c/
暂无评论

发送评论 编辑评论


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