Melakukan Orkestrasi Virtual Machine Dengan KubeVirt

November 28, 2022

Melakukan Orkestrasi Virtual Machine Dengan KubeVirt

Cerita tentang bermain (lagi) di Baremetal. KubeVirt, sebuah operator virtual machine yang didesain untuk melakukan management VM melalui Kubernetes CRD.


Latar belakang

Selayaknya hari mager seperti biasa (dikarenakan semuanya sudah beres), saya scroll twitter dengan santuy ... mata saya sekejap melihat akun CNCF Official meberikan re-twitt terhadap post @kubevirt yang berisikan release terbaru dari mereka, dengan rasa penasaran "Apaan nih kubevirt ?" sambil memberikan dugaan awal, saya mengujungi akun tersebut.

Seperti yang saya duga sejak awal, KubeVirt "Paling cuman jalanin VM di container pake virt, manage pake CRD kube". Setelah saya membaca sedikit, saya kembali ke timeline dan melanjutkan scroll ....

Kewajiban pun datang. Seperti kata saudara se-tongkrongan Bekasi JustHumanz satu satunya hal sulit jika bermain di public cloud adalah Cost Optimization.

Saya mendapatkan sebuah situasi dimana ada baremetal yang hanya berisikan 1 VM akan segera Expired (this is cost optimization desicion moment), di sisi lain saya memiliki kubernetes cluster yang berjalan di atas baremetal tanpa ada overlay VMs. Seketika KubeVirt terpanggil di benak saya.

Masalah

Tidak ada masalah, hanya ada "Ini kalau bisa dipindahin ke sini, yang ini bisa di-terminate", Cost Optimization Moment~~

Saya sangat bisa memahami hal tersebut, dan untuk hal ini saya sangat setuju. Maka dari itu saya akan mencari MASALAH solusi memindahkan VM tersebut ke Kubernetes Cluster dengan bantuan KubeVirt.

Solusi

Memahami Arsitektur dari KubeVirt

Dikarenakan bermain dengan virt adalah hal yang sudah pernah saya lakukan di kehidupan sebelumnya (maksudnya di kantor sebelumnya ) hal ini merupakan "gitu gitu doang moment ~~"

Dengan bahasa anak tongkrongan yang "semoga" mudah dimengerti,

KubeVirt adalah operator dengan CRD kubernetes yang nantinya akan melakukan spawn container berisikan kvm dan segala utility-nya seperti libvirtd, virsh, dkk.

Untuk persistent disk, qemu image-nya akan disupply melalui PVC, atau bisa menggunakan epehemeral volume untuk disk yang bersifat temporary, seperti SWAP.

Dikarenakan VM tersebut berada di overlay container, maka networking dari VM akan menggunakan network CNI kubernetes. Sehingga VM dan juga Pod App kita berada di Network yang sama.

Arsitektur KubeVirt

Penjelasan di atas hanya "how it works", dan sependek pengetahuan saya untuk lebih detail, lengkap dan akurat silahkan merujuk ke https://kubevirt.io/user-guide/architecture/

Kembali ke LABtop

Seperti kebiasaan lama, sebelum membawa sesuatu untuk dihidangkan, saya selalu memasak matang - matang hidangan tersebut di Lab pribadi.

Install KubeVirt Operator

# Point at latest release
$ export RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)
# Deploy the KubeVirt operator
$ kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml
# Create the KubeVirt CR (instance deployment request) which triggers the actual installation
$ kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml
# wait until all KubeVirt components are up
$ kubectl -n kubevirt wait kv kubevirt --for condition=Available

Install CDI Operator

Container Data Importer, salah satu komponen yang dibutuhkan untuk management disk PVC pada VM nantinya.

# Point at latest release
$ export TAG=$(curl -s -w %{redirect_url} https://github.com/kubevirt/containerized-data-importer/releases/latest)
$ export VERSION=$(echo ${TAG##*/})
# Deploy CDI operator
$ kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-operator.yaml
$ kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-cr.yaml

Install Kubectl Virt Plugin

Hal ini Opsional, namun untuk hidup yang lebih baik sebaiknya dilakukan, dikarenakan akan digunakan untuk melakukan forwarding ke pod virt-launcer, dan akan otomatis membuka vnc client pada device kita.

krew install virt

Halangan

Backend Storage

Di sini lah sebuah keputusan yang sangat besar perlu ditentukan. Keputusan yang akan berdampak pada kehidupan setelah VM terdeploy.

"choose your backend storage wisely" pertimbangkan dengan seksama. Apa kebutuhannya, dan bagaimana kondisinya.

Pada kasus ini kebutuhan saya hanya memindahkan VM tersebut ke worker kubernetes dengan KubeVirt, lalu kemudahan ketika scaling up disk, cpu, dan ram jika dibutuhkan. Namun keadaannya adalah tidak ada block storage kosong yang dapat digunakan.

Hostpath Operator

Pilihan saya jatuh pada hostpath operator

1. Install Hostpath Provisoner

# Deploy cert-manager, do not required if already deployed (1.7.x up version).
$ kubectl create -f https://github.com/cert-manager/cert-manager/releases/download/v1.7.1/cert-manager.yaml
# Create hostpath-provisioner namespace
$ kubectl create -f https://raw.githubusercontent.com/kubevirt/hostpath-provisioner-operator/main/deploy/namespace.yaml
# Deploy Webhook 
$ kubectl create -f https://raw.githubusercontent.com/kubevirt/hostpath-provisioner-operator/main/deploy/webhook.yaml -n hostpath-provisioner
# Deploy Operator
$ kubectl create -f https://raw.githubusercontent.com/kubevirt/hostpath-provisioner-operator/main/deploy/operator.yaml -n hostpath-provisioner

2. Create Pool and StorageClass

Data dari PVC nanti akan tersimpan pada node2 di folder /data-kubevirt.

apiVersion: hostpathprovisioner.kubevirt.io/v1beta1
kind: HostPathProvisioner
metadata:
  name: hostpath-provisioner-node2
spec:
  imagePullPolicy: Always
  storagePools:
  - name: node-2
    path: /data-kubevirt
  workload:
    nodeSelector:
      kubernetes.io/hostname: node2
---
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: hostpath-csi-node2
parameters:
  storagePool: node-2
provisioner: kubevirt.io.hostpath-provisioner
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer

Kembali ke LAB ( Mari Membuat VMs )

Download Image to PVC with DataVolume

Download Image

kind: DataVolume
apiVersion: cdi.kubevirt.io/v1beta1
metadata:
  name: ubuntu-image
  namespace: default
spec:
  source:
    http:
      url: https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 3Gi
    storageClassName: hostpath-csi-node2

Create Virtual Machine

kind: DataVolume
apiVersion: cdi.kubevirt.io/v1beta1
metadata:
  name: myvm-volume-data
spec:
  source:
    pvc:
      namespace: default
      name: ubuntu-image
  pvc:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 30Gi
    storageClassName: hostpath-csi-node2
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: my-ubuntu
  labels:
    vm: my-ubuntu
spec:
  runStrategy: Always
  template:
    metadata:
      labels:
        vm: my-ubuntu
    spec:
      terminationGracePeriodSeconds: 30
      domain:
        resources:
          requests:
            cpu: 2
            memory: 4092M
        devices:
          disks:
          - name: datavolume-disk1
            disk:
              bus: virtio
          - disk:
              bus: virtio
            name: cloudinitdisk
      volumes:
      - dataVolume:
          name: myvm-volume-data
        name: datavolume-disk1
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |-
            #cloud-config
            password: Hayomaucarileaksdigithubgwya???ngerixxxxxxxxxAdaHeker
            chpasswd: { expire: False }

Operasional VM

Get in to Console

Get to the console with kubectl virt vnc your-vm-name. All YAML that used here is on my github repos here

Get to Console

Resize CPU, and RAM

Change the CPU, and memory section with resource you want, and make sure your worker is have that space.

$ kubectl delete vm/my-ubuntu
$ vim virtualmachine.yaml
[...]
        resources:
          requests:
            cpu: 2
            memory: 4092M
[...]
$ kubectl apply -f virtualmachine.yaml

Scale Up Disk

In this case, resize disk become tricky, because hostpath-provisioner is different than real storage cluster like Rook, longhorn. So we need to scale image manualy with qemu-img comand

$ kubectl delete vm/my-ubuntu
$ kubectl virt guestfs myvm-volume-data --root --image=quay.io/kubevirt/libguestfs-tools:v0.57.1
[...]
bash-4.4 # qemu-img resize disk.img 10G
[...]
$ kubectl apply -f virtualmachine.yaml

Resize Disk

Expose VM Port with Service

You can expose the what you want trough service kubernetes.

apiVersion: v1
kind: Service
metadata:
  name: vmiservice
spec:
  ports:
  - port: 27017
    protocol: TCP
    targetPort: 22
  selector:
    vm: my-ubuntu
  type: LoadBalancer
---    
apiVersion: v1
kind: Service
metadata:
  name: ubuntu-domain
spec:
  ports:
  - port: 9100
    protocol: TCP
    targetPort: 9100
    name: metrics
  - port: 8080
    protocol: TCP
    targetPort: 8080
    name: app
  selector:
    vm: my-ubuntu
  type: ClusterIP

Akhiran (Opinion are my own)

Singkat cerita setelah mengimplementasi hal tersebut saya berhasil memindahkan 1 VM tersebut ke Managed by KubeVirt yang berdampak baik karena tentu saja mengurangi biaya server.

TLDR; Saya menghadiri Kubernetes Comunity Day, dan di sana saya sempat berbincang di booth RedHat, karena saya melihat mereka melakukan demostrasi terhadap provisioning Virtual Machine di Openshift mereka.

Pada Cluster Openshift mereka saya melihat bagaimana KubeVirt yang sebenarnya terintegrasi dengan backend storage yang proper. Tanpa tricky tricks seperti pada kasus saya.

Saya dan sobat nongs warga Bekasi kabupaten Ammarun tentu saja membredel berbagai pertanyaan kepada sales Redhat (karena rasa penasaran) mereka juga menjawab dengan senang hati. Lalu warlo(c)k Tambun ini mengajukan pertanyaan terkait "Mengapa yang di show nga ada Openstack ? kan monitornya 2" they said "Kita sudah lebih fokus ke CloudNative, development Openstack saat ini lebih ke Telco". Bahkan kata mereka, Redhat melakukan stop development terhadap RHV (No new feature, just fix bugs. Link announcement ada di referensi).

So where the world of cloud will moving ?, will everything is Webhook Kubernetes in Future ?

Well my opinions everything should be back to what you have, and what you need. That's it. Running openshift for Small company with small scale of loads is overkill, probably what you need is just couple of VMs in Digital Ocean or something.

But if you have your own Data Center, or you Running a Banking system that used by millions of people dependen on your Infrastructure, considering have something that make your life is more easier is something that you have to contemplate. It's does't have to be openshift, or kubernetes in general.

So the Kubernetes-ing is just an option, i guess. Option to manage your repetitive task and automating it. The cloud providers will have their own option to choose what they need with what they have. BUT IF I WAS THE ONE WHO CHOOSE WHAT STACK. DEFINITELY KUBERNETES ON OF TOP BAREMETAL IS THE ONE!

Redhat Openshif with KubeVirt

My Talk at Open Infra - Bekasi, Jawa Barat, Indonesia

Saya juga mebawakan materi tersebut pada acara meetup reguler Open Infra Indonesia, pada bulan februari 2023 kemarin.

Live Stream

Google Slides

Referensi

https://access.redhat.com/support/policy/updates/rhev

  • OpenShift virtualization: Not as scary as it seems

https://www.redhat.com/en/blog/openshift-virtualization-not-scary-it-seems


Profile picture

Written by Nicolas Julian Seseorang yang mencoba berkarya. Chit Chat with me in Twitter