Contents

Using govc with vcsim in Kubernetes

The vCenter Simulator vcsim is a powerful Go application to simulate VMware vCenter Server environments. I personally use it a lot together with Github Actions as part of continuous integration pipelines, e.g. in the Tanzu Sources for Knative and VMware Event Broker Appliance.

Recently a colleague reached out to me for some help to deploy and use vcsim to verify an upstream contribution. As part of her testing, she wanted to trigger a vCenter event (VmPoweredOffEvent) so her code could react accordingly.

Her code and vcsim were supposed to run inside a Kubernetes environment. This isn’t well documented so she wasn’t quiet sure how to call the vcsim APIs manually from a local command line outside a Kubernetes cluster to trigger the desired event.

So here’s a quick step-by-step tutorial how to use govc, a vSphere CLI built on top of govmomi to perform API calls against vcsim inside a Kubernetes cluster.

Requirements
To follow along you need Docker (Download), kind (Download), kubectl (Download) and govc (Download) installed on your machine.

Create a Kubernetes Cluster

For this demo, we’re using kind (Kubernetes in Docker) which quickly has become one of the most important assets in my toolbox to spin up local Kubernetes environments.

Let’s go ahead and create a cluster.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ kind create cluster --wait 3m --name "vcsim"
Creating cluster "vcsim" ...
 ✓ Ensuring node image (kindest/node:v1.20.2) đŸ–ŧ
 ✓ Preparing nodes đŸ“Ļ
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹ī¸
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Waiting ≤ 3m0s for control-plane = Ready âŗ
 â€ĸ Ready after 28s 💚
Set kubectl context to "kind-vcsim"
You can now use your cluster with:

kubectl cluster-info --context kind-vcsim

Not sure what to do next? 😅  Check out https://kind.sigs.k8s.io/docs/user/quick-start/

kind will correctly set the Kubernetes context (i.e. target cluster), but let’s quickly verify that.

1
2
3
$ kubectl get nodes
NAME                  STATUS   ROLES                  AGE    VERSION
vcsim-control-plane   Ready    control-plane,master   4m9s   v1.20.2

Deploy vcsim

We can use the official vcsim Docker container image, which makes it dead simple to deploy vcsim in a Kubernetes environment. The following command deploys vcsim in the default namespace.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ cat << EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vcsim
spec:
  selector:
    matchLabels:
      app: vcsim
  template:
    metadata:
      labels:
        app: vcsim
    spec:
      containers:
        - name: vcsim
          image: vmware/vcsim:latest
          args: ["/vcsim", "-l", ":8989"]
          ports:
            - name: https
              containerPort: 8989
EOF

We can verify that the deployment succeeded with kubectl wait.

1
2
$ kubectl wait --timeout=3m --for=condition=Available deploy/vcsim
deployment.apps/vcsim condition met
Tip
Alternatively (or in case of trouble) check whether the associated Kubernetes resources were created correctly with kubectl get deploy,rs,pod. You should see a Deployment, ReplicaSet and Pod successfully deployed.

Create Port-Forwarding

To keep this post simple and to not assume any load-balancing infrastructure, we do not create a Kubernetes Service to expose vcsim to the outside world.

Instead, we can create a port-forwarding to directly talk to the deployment from the local machine where we are going to run the govc commands.

1
2
3
$ kubectl port-forward deploy/vcsim 8989:8989
Forwarding from 127.0.0.1:8989 -> 8989
Forwarding from [::1]:8989 -> 8989

The above command will forward traffic against the host-local address 127.0.0.1:8989 to the pod backing the vcsim deployment inside Kubernetes.

Set up govc Environment Variables

As a last step, we need to give govc information about the vCenter (Simulator) API endpoint.

Since kubectl port-forward is a blocking call and needs to remain running 1, the following steps are performed in a separate terminal.

1
2
3
4
5
# ignore self-signed certificate warnings
$ export GOVC_INSECURE=true

# use default credentials and local port-forwarding address
$ export GOVC_URL=https://user:pass@127.0.0.1:8989/sdk

Now verify that we can establish a connection.

1
2
3
4
5
6
# list vcsim inventory
$ govc ls
/DC0/vm
/DC0/host
/DC0/datastore
/DC0/network

Trigger an Event

As a final exercise, let’s trigger an event by powering off a virtual machine.

To see the events, open another terminal and set the environment variables as described above again.

1
2
3
4
5
# tail and follow the vcsim event stream
$ govc events -f

# omitting events generated by the system
[...]

Now go ahead and power off a VM.

1
2
$ govc vm.power -off /DC0/vm/DC0_C0_RP0_VM1
Powering off VirtualMachine:vm-66... OK

Once you powered off the VM via the command below you should see the following events in the other console.

1
2
[Sun May 23 21:42:08 2021] [info] DC0_C0_RP0_VM1 on host DC0_C0_H0 in DC0 is stopping
[Sun May 23 21:42:08 2021] [info] DC0_C0_RP0_VM1 on DC0_C0_H0 in DC0 is powered off

When you’re done you can throw away the environment in one command.

1
2
$ kind delete cluster --name vcsim
Deleting cluster "vcsim" ...

Wrap Up

I really like how easy it is to spin up even complex infrastructure environments on your local machine with the great open source tooling around us these days.

The vCenter Simulator vcsim is a great tool to simplify access to vCenter APIs and can be easily integrated into CI environments, e.g. with Github Actions. To dig deeper, check out the earlier mentioned repositories Tanzu Sources for Knative and VMware Event Broker Appliance for some inspiration how we use vcsim with Kubernetes in Github Actions.

Credits

Photo by ThisisEngineering RAEng on Unsplash


  1. You could also send and resume the command to the background, but I am assuming you know how to perform this in your $SHELL, since you’re asking 😉 ↩︎