Skip to main content

Bootstrapping vClusters

In this hands-on tutorial, we’ll look at how to configure newly provisioned virtual clusters with init manifests (Kubernetes YAML) and Helm charts that are applied automatically after the virtual cluster is created. This feature lets you configure your virtual clusters fully or install other tools that will configure them, depending on your needs.

If you’re new to vcluster, you may want to go through our introductory hands-on tutorial first.


The only prerequisite is a Kubernetes cluster that you can run the virtual cluster in. Any Kubernetes cluster, local or remote, should work.

Install the vcluster CLI

If you use a Mac with Homebrew, you can install the CLI with this command:

brew install vcluster

For other platforms, see the installation docs. The CLI is supported on macOS, Linux, and Windows.

Apply a manifest on initialization

The manifests we’re referring to are any valid Kubernetes YAML that you could apply with kubectl apply -f. Being able to apply Kubernetes YAML immediately after the cluster is created allows us to automate just about anything we’d want to do when creating or configuring a cluster.

Let’s look at an example. Create a file called values.yaml with the following contents:

manifests: |-
apiVersion: v1
kind: Namespace
name: nginx
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
namespace: nginx
app: nginx
replicas: 2
app: nginx
- name: nginx
image: nginx:1.25.1
- containerPort: 80

Let’s break down what’s happening here.

The first two lines specify that this is the init.manifest section of the vcluster YAML file and that what follows are the manifests to be applied.

The next four lines create a namespace in the virtual cluster called nginx.

Then there is a separator, which needs to be present between each manifest.

The rest of the file creates a deployment to launch two NGINX pods in the nginx namespace that was just created. It will launch two pods in the virtual cluster with a label of nginx.

Next, let’s create a virtual cluster that will automatically apply those manifests. The manifests will be applied in the order they appear in the file.

Make sure you are pointed at the kube context for the host cluster you use. Then create the virtual cluster.

vcluster create init-tutorial -f values.yaml

This will create a virtual cluster with the name init-tutorial, and a namespace to run it in.

You should see output like:

info   Creating namespace vcluster-init-tutorial
info failed to find IPv6 service CIDR: couldn't find host cluster Service CIDR ("Service "test-service-9wpzn" is invalid: spec.clusterIPs[0]: Invalid value: []string{"2001:DB8::1"}: IPv6 is not configured on this cluster")
info Detected local kubernetes cluster docker-desktop. Will deploy vcluster with a NodePort & sync real nodes
info Create vcluster init-tutorial...
info execute command: helm upgrade init-tutorial /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/vcluster-0.15.2.tgz-86186483 --kubeconfig /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/3759283775 --namespace vcluster-init-tutorial --install --repository-config='' --values /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/1562320995 --values values.yaml
done √ Successfully created virtual cluster init-tutorial in namespace vcluster-init-tutorial
info Waiting for vcluster to come up...
done √ Switched active kube context to vcluster_init-tutorial_vcluster-init-tutorial_docker-desktop
- Use `vcluster disconnect` to return to your previous kube context
- Use `kubectl get namespaces` to access the vcluster

The exact output will depend a bit on how your host cluster is set up.

If your host cluster is local (Docker Desktop, Minikube, etc.), vcluster will configure it to use a NodePort and connect to it automatically.

For remote clusters, vcluster will connect using port forwarding.

Now that we’re connected to the virtual cluster, we can run kubectl commands against it like any other cluster. Let’s look at the pods that are running.

kubectl get pods -n nginx

You should see output like:

NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
nginx nginx-deployment-775b6549b5-nr8jh 1/1 Running 0 68s
nginx nginx-deployment-775b6549b5-vcx7w 1/1 Running 0 68s

In this example, the two NGINX pods are running in the nginx namespace. The pods and the namespace were created automatically as soon as the vcluster was created.

Now let’s disconnect from the virtual cluster and delete it to clean up.

vcluster disconnect

Disconnecting will switch you back to the context of the host cluster. Then run:

vcluster delete init-tutorial

Apply a Helm chart on initialization

Now let’s create an NGINX namespace and deploy again, but this time instead of creating the deployment manually, we’ll install NGINX with a public Helm chart.

First, edit the values.yaml. Remove the previous contents and set them to:

- chart:
name: nginx
# optional field
values: |-
replicaCount: 2
name: nginx
namespace: nginx

As you can see, we specify the chart name and repo first. Then we can optionally include Helm values for the chart inline (we’ve set the replica count to 2). And last, the release section contains the name (the pods will use this name) and the namespace that’s being used.

Create the vcluster:

vcluster create init-tutorial-2 -f values.yaml

Once again you should be automatically connected to the vcluster. And we can view the NGINX pods with:

kubectl get pods -n nginx

Your output should look like:

NAME                     READY   STATUS    RESTARTS   AGE
nginx-769c898b4f-g922n 1/1 Running 0 108s
nginx-769c898b4f-vwh6w 1/1 Running 0 108s

And that’s the process for automatically applying a Helm chart when the vcluster is initialized.

We can clean up once again with:

vcluster disconnect
vcluster delete init-tutorial-2

You can also apply private Helm charts when vclusters are initialized from a private repo or your local filesystem. For more info, see the docs.


A quick note on troubleshooting. When a virtual cluster is initialized with manifests or Helm charts, you won’t see any errors that result in the output from the vcluster create command. You can see more information in the host cluster’s logs, though.

First, if you are connected to the virtual cluster, disconnect with the vcluster disconnect command. Then run this command against the host cluster:

kubectl logs -n vcluster-NAME -l app=vcluster,release=NAME -c syncer

Substitute the name you gave your virtual cluster in the vcluster connect command for NAME in both places. By default, vcluster prepends the string vcluster- to the name of the virtual cluster’s namespace.