返回归档
🪩技术分享

从0到1,利用kubevirt构建ubuntu虚拟机

文章目录

kubevirt是什么

  • 一个开源项目,CNCF sandbox
  • 将虚拟机(VM)运行引入了 k8s 集群中,使得用户可以在 k8s 中同时管理容器和虚拟机工作负载
  • 帮助企业和开发者通过 k8s 统一管理虚拟机和容器,方便地运行和迁移传统的虚拟机工作负载到云原生环境中

特点

  1. 虚拟机和容器共存:KubeVirt 将虚拟机作为 Kubernetes CRD 来进行管理,从而允许在 Kubernetes 集群内同时调度和运行虚拟机和容器
  2. Kubernetes 原生支持:KubeVirt 完全整合到 Kubernetes 生态系统中。通过 Kubernetes API,用户可以像管理容器一样管理虚拟机(VM),包括启动、停止、扩展、迁移等操作
  3. 支持传统和现代应用:通过 KubeVirt,可以将遗留系统或传统应用程序从虚拟化平台迁移到 Kubernetes,方便地与现代云原生应用程序一起运行,助力企业数字化转型。
  4. 无缝的网络和存储集成:KubeVirt 使用 Kubernetes 的网络和存储资源,这意味着虚拟机可以使用 Kubernetes 的网络插件(如 Calico、Flannel 等)和持久存储卷(如 NFS、Ceph 等)
  5. 虚拟机的动态调度和负载均衡:KubeVirt 支持虚拟机的动态调度和负载均衡功能,可以根据集群状态自动调度虚拟机到合适的节点
  6. Live Migration(在线迁移):KubeVirt 支持虚拟机的在线迁移功能,即在不中断服务的情况下将虚拟机从一个节点迁移到另一个节点
  7. 支持多种操作系统:KubeVirt 支持运行多种操作系统,包括 Linux 和 Windows。这使得它在多种业务场景下都能胜任

kubevirt架构

image

kubevirt以CRD的形式将VM管理接口接入到kubernetes中,通过一个pod去使用libvirtd管理VM的方式,实现pod与VM的一一对应,做到如同容器一般去管理虚拟机,并且做到与容器一样的资源管理、调度规划

  1. VirtualMachine(VM):这是 KubeVirt 中的核心资源类型。每个 VirtualMachine 对象定义了虚拟机的配置,比如 CPU、内存、磁盘、网络等信息
  2. VirtualMachineInstance(VMI):当你启动一个虚拟机时,会创建一个 VMI 对象,表示该虚拟机的运行实例。这个对象包含虚拟机的运行时状态信息
  3. **virt-api:**其是所有虚拟化操作的入口,包括常规的CRD更新验证、console、vm 的start和stop操作
  4. virt-controller:其是 KubeVirt 的控制器,负责监视和管理 VirtualMachine 和 VirtualMachineInstance 的生命周期,比如启动、停止、重启和迁移等操作
  5. virt-handler:其会以deamonset的形式部署在每一个node上,负责监控node上的每个虚拟机实例状态变化
  6. virt-launcher:这是一个短生命周期的 Pod,每个 VMI 都会有一个对应的 virt-launcher Pod,负责在节点上启动和管理实际的虚拟机进程
root@master01:/home/ubuntu/yst/cdi-manage-vm-disk-image# k exec -it virt-launcher-vm1-7kxt5 -- pstree -U
virt-launcher-m─┬─qemu-kvm───5*[{qemu-kvm}]
                ├─virt-launcher─┬─virtlogd
               ├─virtqemud───18*[{virtqemud}]
               └─15*[{virt-launcher}]
                └─7*[{virt-launcher-m}]
  1. virt-launcher-m: 这是一个管理虚拟机的进程,负责启动和管理虚拟机实例。它是 Kubernetes 中 KubeVirt 的一部分,KubeVirt 用于在 Kubernetes 环境中运行虚拟机。
  2. qemu-kvm: 是虚拟机的实际运行进程,负责运行用户自定义的镜像操作系统,模拟虚拟的硬件环境,包括CPU、内存、磁盘和网络情况
  3. 子进程: 在进程树中,可以看到许多子进程:
  • 5*[{qemu-kvm}]: 这是 qemu-kvm 的工作线程,表明有 5 个线程在处理虚拟机的请求。
  • virtlogd: 这是一个用于管理虚拟机日志的守护进程,负责收集和存储虚拟机的日志信息。
  • virtqemud: 这是一个用于管理 QEMU 实例的守护进程,也可能有多个线程(18*[{virtqemud}] 表示有 18 个线程)。

4.进程树的结构: 每一层的缩进表示进程之间的父子关系。例如,virt-launcher 是 virt-launcher-m 的子进程,而 qemu-kvm 是 virt-launcher-m 的子进程。

deploy kubevirt & install virtctl

bookmark

构建基础镜像

首先,选择基础镜像,这里我们选择 ubuntu22.04LST

curl -L -o jammy-server-cloudimg-amd64.img https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

安装需要的包

sudo apt update
sudo apt install qemu-utils qemu-kvm qemu-system cloud-image-utils genisoimage

设置登陆密码

# 1.这里的 cloudconfig 创建了一个密码为 root,其用户名默认为ubuntu 
cat >user-data <<EOF
#cloud-config
password: root
chpasswd: { expire: False }
ssh_pwauth: True
EOF

#2.创建一个空的 meta-data
cat >meta-data<<EOF
EOF

将创建的 user-data转化为qemu可以使用的img格式的文件

cloud-localds user-data.img user-data

默认的系统盘只有2G,后续安装可能会爆磁盘空间不足的错误,可以提前扩容(正好凑够20G,按需扩容)

sudo qemu-img resize ./jammy-server-cloudimg-amd64.img +18G

启动虚拟机

sudo qemu-system-x86_64 -smp 4 -m 16384m -nographic -drive file=jammy-server-cloudimg-amd64.img,format=qcow2 -drive file=user-data.img,format=raw -device virtio-net,netdev=net0 -netdev user,id=net0,hostfwd=tcp::2333-:22

配置root密码、开启自启动DHCP

# 注意下面操作的内容是永久生效的
# 1. 允许root登陆
sudo sed -i 's/\#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
# 2. 设置root密码,其中root用户的密码我设置为root 
sudo passwd root
# 3.修改网卡自动dhcp
sudo apt-get install isc-dhcp-client
sudo vi /etc/rc.local
添加一下内容
#!/bin/bash
dhclient -v
# 4.授权
sudo chmod 755 /etc/rc.local

下载docker并设置自启动

# 添加docker官方 GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# 添加repo到 Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

#安装docker及其组件
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

#验证
sudo docker version
sudo docker run hello-world

#将docker设置为自启动
sudo systemctl enable docker
#验证是否成功
sudo systemctl is-enabled docker

最终

此时的img就是一个包含我们自己安装的img了,可以按需,利用此基础镜像img进行扩展

可以将此img镜像打包为docker镜像进行保存

#将 img 文件转换为 qcow2 格式
sudo qemu-img convert -p -c -O qcow2 jammy-server-cloudimg-amd64.img jammy-server-cloudimg-amd64.qcow2

#编写Dockerfile
sudo vi Dockerfile
#添加一下内容
FROM scratch
COPY --chown=107:107 jammy-server-cloudimg-amd64.qcow2 /disk/
#构建镜像,注意上下文
sudo docker build -t kubevirt-image/ubuntu22.04lts:with-docker

构建VM

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu
  labels:
    vmName: ubuntu
    sshtest: "true"
spec:
  dataVolumeTemplates:
    - metadata:
        name: sys-dv
      spec:
        storage:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 50Gi
          storageClassName: openebs-lvmpv
        source:
          registry:
            url: docker://....
  running: true
  template:
    metadata:
      labels:
        vmName: ubuntu
        sshtest: "true"
    spec:
      domain:
        cpu:
          cores: 4
        devices:
          disks:
            - name: datavolumevolume
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
          interfaces:
            - name: default
              masquerade: {}
        resources:
          requests:
            memory: 8Gi
      networks:
        - name: default
          pod: {}
      volumes:
        - name: datavolumevolume
          persistentVolumeClaim:
            claimName: sys-dv
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: vm1
              ssh_pwauth: True
              disable_root: false
              ssh_authorized_keys:
                - ssh-rsa ....
              chpasswd:
                list: |
                  ubuntu:ubuntu
                expire: False

运行

virtctl console vmname