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.
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
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
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
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!
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
- nicolasjulian/KubeVirt: Bundle to getting start with KubeVirt - https://github.com/nicolasjulian/KubeVirt
- KubeVirt User-Guide - https://kubevirt.io/user-guide/
- Red Hat Virtualization Life Cycle - Red Hat Customer Portal
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