How to Setup KubeVirt with PMK

This blog post will go over how to setup KubeVirt using PMK. We will create a cluster with KubeVirt enabled, install add-ons for kubectl, and then deploy a virtual machine using the KubeVirt examples in the post. This post also overlaps with videos we have created showing the same demo, as well as an AMA session. Follow along with the post or watch the video and check out the bottom of the post for VMI and service examples.

Videos

Account Setup

There is a quick setup guide that goes over some of the setup, however we are going to choose additional options as this guide goes over installation on BareOS – https://platform9.com/docs/kubevirt/quick-setup-guide

Cluster Creation with KubeVirt Enabled

After you have created an account we will need to deploy a cluster – this is where we can setup KubeVirt on the cluster at deployment time.

  • First we need to create a cluster. Select the Add Cluster drop down and then select Create Cluster.

Platform9 Clusters

  • Next we are going to pick our infrastructure. In our example we’re using BareOS Virtual Machines, however you can deploy other types of infrastructure. (If you run into issues or have questions please join our Slack Community.) We are going to create a single master cluster so that we can show off functionality without using a large amount of resources.

  • We will name our cluster demoKubeVirt and select the latest version of K8s (at the time of this writing.)

  • The most important part of the guide – we will select Enable KubeVirt. If you are running on BareOS we should also select Deploy MetalLB so that we can use LoadBalancers, however it is not required if you want to use a NodePort instead. (Our Service example assumes MetalLB is installed.) Select next and proceed to the next configuration page.

KubeVirt Enabled

  • We are setting up a single master cluster so we will need to select a master node. Pick a node and select Next.

  • Now we need to select the worker nodes. In this example we are using two worker nodes. Select the nodes and select Finish and Review. There are additional options if you select Next however for the purpose of this guide we aren’t modifying any of the preconfigured options.

  • Now that we have configured our cluster we can review our selections. If everything looks good then select Complete.

  • After selecting complete you’ll be presenting with a screen showing the deployment status. This process will take a few minutes.

  • Finally the cluster has deployed, it should show up as Connected and Healthy. At this point we can navigate to the Virtual Machines section.

  • The Virtual Machines section is currently in Early Access. The UI is mostly read only, however you can view information about the Virtual Machines after they have been deployed. We are going to be using the CLI to deploy the VMs.

KubeVirt Virtual Machine Instances UI

Kubectl Add-ons

First we need to install Krew so that we can easily install additional add-ons. Krew is a Kubernetes SIG project :

https://github.com/kubernetes-sigs/krew

Installation guides for Krew can be found here:

https://krew.sigs.k8s.io/docs/user-guide/setup/install/

After we have installed Krew we can use it to install the kubectl-virt plugin.

kubectl krew install virt

KubeVirt Virtual Machine Instance Examples

At this point we should have KubeVirt running in our cluster and the Virt add-on installed using Krew. Below are the example YAMLs that were used in the videos posted above.

The first example is a VirtualMachineInstance, which will automatically start once we create/apply with kubectl. Some of the configuration options to note:

  • SSH Key is setup using a Secret. The secret will contain your public key. Another option would be to use cloud-config to setup your SSH Keys.
  • The Container Image used is an Ubuntu cloud image expanded into a container image. Other options would be to create a volume and expand a cloud image into the volume and then attach it to the container instead. This will allow you to control the disk size.
  • Cloud-Config is installing a couple of packages that are useful for getting information about the Virtual Machine. The information can be pulled with kubectl virt guestosinfo. Qemu-Guest-Agent is used to pull this information.
apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
  name: demo-vmi
  labels:
    vmi : demo-vmi
spec:
  terminationGracePeriodSeconds: 30
  domain:
    resources:
      requests:
        memory: 1024M
    devices:
      disks:
      - name: containerdisk
        disk:
          bus: virtio
      - name: emptydisk
        disk:
          bus: virtio
      - disk:
          bus: virtio
        name: cloudinitdisk
  accessCredentials:
  - sshPublicKey:
      source:
        secret:
          secretName: mpetersen-pub-key
      propagationMethod:
        qemuGuestAgent:
          users:
          - "ubuntu"
  volumes:
  - name: containerdisk
    containerDisk:
      image: mpetason/ubuntu:20.04
  - name: emptydisk
    emptyDisk:
      capacity: "10Gi"
  - name: cloudinitdisk
    cloudInitNoCloud:
      userData: |-
        #cloud-config
        password: ubuntu
        chpasswd: { expire: False }
        package_update: true
        package_upgrade: true
        packages: 
        - qemu-guest-agent
        runcmd:
        - [ systemctl, start, qemu-guest-agent ]

Extra Example using Cloud-Config for SSH Keys, installing apache2 and qemu-guest-agent:

apiVersion: kubevirt.io/v1
kind: VirtualMachineInstance
metadata:
  name: demo-vmi
  labels:
    vmi : demo-vmi
spec:
  terminationGracePeriodSeconds: 30
  domain:
    resources:
      requests:
        memory: 1024M
    devices:
      disks:
      - name: containerdisk
        disk:
          bus: virtio
      - disk:
          bus: virtio
        name: cloudinitdisk
  volumes:
  - name: containerdisk
    containerDisk:
      image: mpetason/ubuntu:20.04
  - name: cloudinitdisk
    cloudInitNoCloud:
      userData: |-
        #cloud-config
        password: ubuntu
        chpasswd: { expire: False }
        ssh_authorized_keys:
        - YOUR PUBLIC SSH KEY
        package_update: true
        package_upgrade: true
        packages: 
        - qemu-guest-agent
        - apache2
        runcmd:
        - [ systemctl, start, qemu-guest-agent ]

If you are using either of the examples above – save the data as a yaml file, in my example I’m naming the file ubuntu-vmi.yaml so that I can use kubectl to create it.

kubectl create -f ubuntu-vmi.yaml

After we have created the VM we need a way to communicate with it. Using an LoadBalancer or NodePort will expose the VM to external networks. In this example I’m exposing port 80 for Apache2, and port 22 for SSH. This Service example is being applied to the YAML file above, which installs apache2.

apiVersion: v1
kind: Service
metadata:
  name: vmi-lb
spec:
  ports:
  - port: 22
    name: ssh
    protocol: TCP
    targetPort: 22
  - port: 80
    name: http
    protocol: TCP
    targetPort: 80
  selector:
    vmi : demo-vmi  
  type: LoadBalancer

We will also need to save the service file in a separate YAML, I have named it service-ubuntu-vmi.yaml however you could also have everything in a single YAML file with separators for each service. To create the service can we run:

kubectl create -f service-ubuntu-vmi.yaml

If you’re using MetalLB, or a cloud provider, you should be able to find the Service IP address which can be used to SSH to the VM. For this example we’re using Ubuntu so the username is ubuntu. If you’re using the example with Apache2 installed then you can also Curl the address to see it working. Assuming we’re in the default namespace we can run:

kubectl get service
ssh ubuntu@IPofLoadBalancer
curl http://IPofLoadBalancer

Conclusion

PMK makes it quick and easy to setup a cluster with KubeVirt. Once KubeVirt is running you can re-use some of the cloud images you are used to using with other Virtual Machine infrastructure such as OpenStack. There’s a decent amount of overlap in how KubeVirt works within the container which can help bridge the gap between VM infrastructure and Kubernetes.

Mike Petersen

You may also enjoy

Exploring Platform9 Managed OpenStack as a modern virtualization alternative

By Peter Fray

KubeVirt: Tearing Down Another Silo

By Platform9

The browser you are using is outdated. For the best experience please download or update your browser to one of the following:

Learn the FinOps best practices to maximize your cloud usage & budget:Register Now
+