加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

如何运用 Kubevirt 管理 Kubernetes 中的虚拟机

发布时间:2022-07-10 07:48:03 所属栏目:Linux 来源:互联网
导读:本文中所有涉及的代码可以从我的 Github(https://github.com/SimpCosm/manifest/tree/master/kubevirt) 中找到。 背景介绍 CRD 设计 Kubevirt 主要实现了下面几种资源,以实现对虚拟机的管理: VirtualMachineInstance(VMI) : 类似于 kubernetes Pod,是
  本文中所有涉及的代码可以从我的 Github(https://github.com/SimpCosm/manifest/tree/master/kubevirt) 中找到。
 
  背景介绍
  CRD 设计
  Kubevirt 主要实现了下面几种资源,以实现对虚拟机的管理:
 
  VirtualMachineInstance(VMI) : 类似于 kubernetes Pod,是管理虚拟机的最小资源。一个 VirtualMachineInstance 对象即表示一台正在运行的虚拟机实例,包含一个虚拟机所需要的各种配置。通常情况下用户不会去直接创建 VMI 对象,而是创建更高层级的对象,即 VM 和 VMRS。
  VirtualMachine(VM) : 为集群内的 VirtualMachineInstance 提供管理功能,例如开机/关机/重启虚拟机,确保虚拟机实例的启动状态,与虚拟机实例是 1:1 的关系,类似与 spec.replica 为 1 的 StatefulSet。
  VirtualMachineInstanceReplicaSet : 类似 ReplicaSet,可以启动指定数量的 VirtualMachineInstance,并且保证指定数量的 VirtualMachineInstance 运行,可以配置 HPA。

  通过访问这个 NodePort 服务,既可以:
 
  接下来就可以像 https://www.cnblogs.com/ryanyangcs/p/14079144.html 里面指导的一样,安装 Windows 操作系统了。
 
  配置远程连接
  尽管 VNC 可以远程访问 Windows 图形界面,但是操作体验比较难受。当系统安装完成后,就可以使用 Windows 的远程连接协议 RDP。选择开始 >设置 >系统>远程桌面,打开启用远程桌面就好了。
 
  现在可以通过 telnet 来测试 RDP 端口 3389 的连通性:
 
  复制
  [root@VM-4-27-centos ~]# telnet 172.16.0.32 3389
  Trying 172.16.0.32...
  Connected to 172.16.0.32.
  Escape character is '^]'.
  1.
  2.
  3.
  4.
  如果你的本地电脑能够直连 Pod IP 和 SVC IP,现在就可以直接通过 RDP 客户端来远程连接 Windows 了。如果你的本地电脑不能直连 Pod IP 和 SVC IP,但可以直连 Kubernetes 集群的 Node IP,可以通过 NodePort 来暴露 RDP 端口。具体操作是创建一个 Service,类型为 NodePort:
 
  复制
  [root@VM-4-27-centos ~]# virtctl expose vm win10  --name win10-rdp --port 3389 --target-port 3389 --type NodePort
  Service win10-rdp successfully exposed for vm win10
  [root@VM-4-27-centos ~]#
  [root@VM-4-27-centos ~]# kubectl get svc
  NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
  kube-user    LoadBalancer   172.16.253.39   10.3.4.28     443:31525/TCP    27h
  kubernetes   ClusterIP      172.16.252.1    <none>        443/TCP          42h
  win10-rdp    NodePort       172.16.255.78   <none>        3389:32200/TCP   8s

  然后就可以通过 Node IP 来远程连接 Windows 了。如果你的本地操作系统是 Windows 10,可以在任务栏的搜索框中,键入“远程桌面连接”,然后选择“远程桌面连接”。在“远程桌面连接”中,键入你想要连接的电脑的名称(从步骤 1),然后选择“连接”。如果你的本地操作系统是 macOS,需要在 App Store 中安装 Microsoft Remote Desktop。
 
  对于以上使用了
 
  windows 访问外网
 
  外网访问 windows
 
  在 Windows 虚拟机中安装 nginx 服务,可以在 Windows 中访问:

 
  这个时候直接访问 Windows 虚拟机对应的 IP,既可以在集群内访问 Nginx 服务:

  存储
  虚拟机镜像(磁盘)是启动虚拟机必不可少的部分,KubeVirt 中提供多种方式的虚拟机磁盘,虚拟机镜像(磁盘)使用方式非常灵活。这里列出几种比较常用的:
 
  PersistentVolumeClaim: 使用 PVC 做为后端存储,适用于数据持久化,即在虚拟机重启或者重建后数据依旧存在。使用的 PV 类型可以是 block 和 filesystem
  使用 filesystem 时,会使用 PVC 上的 /disk.img,格式为 RAW 格式的文件作为硬盘。
  block 模式时,使用 block volume 直接作为原始块设备提供给虚拟机。
  ephemeral : 基于后端存储在本地做一个写时复制(COW)镜像层,所有的写入都在本地存储的镜像中,VM 实例停止时写入层就被删除,后端存储上的镜像不变化。
  containerDisk : 基于 scratch 构建的一个 docker image,镜像中包含虚拟机启动所需要的虚拟机镜像,可以将该 docker image push 到 registry,使用时从 registry 拉取镜像,直接使用 containerDisk 作为 VMI 磁盘,数据是无法持久化的。
  hostDisk : 使用节点上的磁盘镜像,类似于 hostpath,也可以在初始化时创建空的镜像。
  dataVolume : 提供在虚拟机启动流程中自动将虚拟机磁盘导入 pvc 的功能,在不使用 DataVolume 的情况下,用户必须先准备带有磁盘映像的 pvc,然后再将其分配给 VM 或 VMI。dataVolume 拉取镜像的来源可以时 http,对象存储,另一块 PVC 等。
  更多参考 https://kubevirt.io/user-guide/virtual_machines/disks_and_volumes/
 
  全局路由模式 bridge 网络原理
  虚拟机网络就是pod网络,virt-launcher pod网络的网卡不再挂有pod ip,而是作为虚拟机的虚拟网卡的与外部网络通信的交接物理网卡,virt-launcher实现了简单的单ip dhcp server,就是需要虚拟机中启动dhclient,virt-launcher 服务会分配给虚拟机。
 
  出向:目的地为集群外地址
  在虚拟机中查看路由:
 
  复制
  [fedora@testvmi-nocloud2 ~]$ ip route
  default via 172.16.0.1 dev eth0 proto dhcp metric 100
  172.16.0.0/26 dev eth0 proto kernel scope link src 172.16.0.24 metric 100
  1.
  2.
  3.
  虚拟机 Node1 上所有 Pod 属于同一个 IP 子网 172.20.0.0/26,这些 Pod 都连接到了虚拟网桥 cbr0 上。如上面路由表的第二条路由条目所示,目地地为子网 172.20.0.0/26 的流量将通过虚拟机的 eth0 发出去,eth0 的 Veth pair 对端网卡处于网桥上,因此网桥会收到该数据包。网桥收到数据包后,通过二层转发将该数据包从网桥上连接到目的 Pod 的端口发送出去,数据将到达该端的 Veth pair 对端,即该数据包的目的 Pod 上。
  如果是发往外界的 IP,则默认发给网关 172.16.0.1。这里的网关是宿主机上面 cbr0 的地址。
  其实这里虚拟机的路由都来自于 launcher Pod 中的路由信息。此时查看 launcher Pod 中的路由信息,已经为空:
 
  复制
  [root@VM-4-27-centos ~]# ip r
  [root@VM-4-27-centos ~]# ip n
  1.
  2.
  查看虚拟机 IP 信息,可以看到虚拟机 IP 为 172.16.0.24,MAC 为 5e:04:61:17:c1:c9,这也是从 launcher Pod 拿来的。
 
  复制
  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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
     link/ether 5e:04:61:17:c1:c9 brd ff:ff:ff:ff:ff:ff
     altname enp1s0
     inet 172.16.0.24/26 brd 172.16.0.63 scope global dynamic noprefixroute eth0
        valid_lft 85794782sec preferred_lft 85794782sec
     inet6 fe80::5c04:61ff:fe17:c1c9/64 scope link
        valid_lft forever preferred_lft forever

  查看 launcher Pod 中现有的接口,
 
  eth0-nic 为 Pod 原来 eth0 的 interface
  tap0 为虚拟机 eth0 对应的 tap 设备
  k6t-eth0 为 launcher Pod 中的网桥

  接下来会在 Pod 原来的网口 eth0-nic 上抓到包,源和目的地址都不变:
 
  复制
  [root@VM-4-27-centos ~]# tcpdump -ieth0-nic -nnvve host 8.8.8.8
  dropped privs to tcpdump
  tcpdump: listening on eth0-nic, link-type EN10MB (Ethernet), capture size 262144 bytes
  20:30:02.087639 5e:04:61:17:c1:c9 > 92:3f:13:e2:55:c9, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 2902, offset 0, flags [DF], proto ICMP (1), length 84)
     172.16.0.24 > 8.8.8.8: ICMP echo request, id 11, seq 94, length 64
  20:30:02.088959 92:3f:13:e2:55:c9 > 5e:04:61:17:c1:c9, ethertype IPv4 (0x0800), length 98: (tos 0x64, ttl 117, id 0, offset 0, flags [none], proto ICMP (1), length 84)
     8.8.8.8 > 172.16.0.24: ICMP echo reply, id 11, seq 94, length 64

  网桥 k6t-eth0 是怎么知道应该把包给到 eth0-nic 呢?这里是在 k6t-eth0 网桥这里做了flood,所有挂接到网桥上的接口都可以抓到访问 8.8.8.8。

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!