vcluster Inception Video

Rich Burroughs
Minute Read

Running a virtual cluster inside a Kubernetes cluster is cool, but running a virtual cluster inside a virtual cluster is some real inception. Watch this YouTube video to see how you can do this with our open source virtual cluster tool called vcluster, or read the transcript below if you prefer.

{{< youtube KFbAzoUzFO8 >}}

Transcript

Hi, I'm Rich with Loft Labs. Recently, I did a video introducing our open source virtual cluster tool for Kubernetes called vcluster, which lets you run a virtual cluster entirely within a namespace of your host cluster. During the video, I mentioned that you can actually run a vcluster inside of a vcluster, and I thought I'd show you how this vcluster inception works. Let's get to a shell and have a look.

Here's level one, my host cluster. First I'll started up an Nginx deployment with a single pod in the host cluster.

$ kubectl create deployment nginx-deployment -n default --image=nginx --replicas=1

deployment.apps/nginx-deployment created

Okay. We now have a single Nginx pod running. Now let's drop down to level two and create our first vcluster.

$ vcluster create vc-level-2 -n level2

[info]   Creating namespace level2
[info]   execute command: helm upgrade vc-level-2 vcluster --repo https://charts.loft.sh --kubeconfig /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/525221466 --namespace level2 --install --repository-config='' --values /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/595064305
[done] √ Successfully created virtual cluster vc-level-2 in namespace level2. Use 'vcluster connect vc-level-2 --namespace level2' to access the virtual cluster

vclusters are deployed using Helm. Our vcluster is running in a namespace on the host cluster called level2.

$ kubectl get pods -n level2

NAME           READY   STATUS    RESTARTS   AGE
vc-level-2-0   0/2     Pending   0          2s

In that namespace you can see the vcluster pod running. vcluster uses k3s under the hood, so there's a full-blown API server running in that pod. Let's connect to the vcluster.

$ vcluster connect vc-level-2 -n level2

[info]   Waiting for vCluster to come up...
[done] √ Virtual cluster kube config written to: ./kubeconfig.yaml. You can access the cluster via `kubectl --kubeconfig ./kubeconfig.yaml get namespaces`
[info]   Starting port forwarding: kubectl port-forward --namespace level2 vc-level-2-0 8443:8443
Forwarding from 127.0.0.1:8443 -> 8443
Forwarding from [::1]:8443 -> 8443

vcluster connect sets up port forwarding. We'll leave that running and open a new shell.

vcluster connect also creates a kubeconfig file that points at the virtual cluster. Let's point our local kubectl at that kubeconfig.

$ export KUBECONFIG=./kubeconfig.yaml

And then look at the namespaces.

$ kubectl get namespaces

NAME              STATUS   AGE
default           Active   15m
kube-system       Active   15m
kube-public       Active   15m
kube-node-lease   Active   15m

$ kubectl get pods

No resources found in default namespace.

We don't see the level2 namespace that was created in the host cluster. Our virtual cluster is running entirely inside of that namespace. We don't see the Nginx deployment that's running in the host cluster either. Let's create an Nginx deployment with two replicas here at level2.

$ kubectl create deployment nginx-deployment -n default --image=nginx --replicas=2

deployment.apps/nginx-deployment created

$ kubectl get pods

NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-84cd76b964-kp4w6   0/1     ContainerCreating   0          1s
nginx-deployment-84cd76b964-78wnp   0/1     ContainerCreating   0          1s

Okay. Now for the real inception action. Let's create a vcluster inside of our vcluster.

$ vcluster create vc-level-3 -n level3

[info]   Creating namespace level3
[info]   execute command: helm upgrade vc-level-3 vcluster --repo https://charts.loft.sh --kubeconfig /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/088217689 --namespace level3 --install --repository-config='' --values /var/folders/gy/d3_c4t1x731_hl8qtrfkhr_h0000gn/T/968839140
[done] √ Successfully created virtual cluster vc-level-3 in namespace level3. Use 'vcluster connect vc-level-3 --namespace level3' to access the virtual cluster

And then connect to it. We have to use the level2 kubeconfig and specify a different local port for port forwarding.

$ vcluster connect vc-level-3 -n level3 --local-port=8444

[info]   Waiting for vCluster to come up...
[done] √ Virtual cluster kube config written to: ./kubeconfig.yaml. You can access the cluster via `kubectl --kubeconfig ./kubeconfig.yaml get namespaces`
[info]   Starting port forwarding: kubectl port-forward --namespace level3 vc-level-3-0 8444:8443
Forwarding from 127.0.0.1:8444 -> 8443
Forwarding from [::1]:8444 -> 8443

We'll open one more tab for level three and use its kubeconfig. Let's make an Nginx deployment here with three replicas.

$ export KUBECONFIG=./kubeconfig.yaml
$ kubectl create deployment nginx-deployment -n default --image=nginx --replicas=3

deployment.apps/nginx-deployment created

$ kubectl get pods

NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-84cd76b964-czlpz   0/1     ContainerCreating   0          3s
nginx-deployment-84cd76b964-l292w   0/1     ContainerCreating   0          3s
nginx-deployment-84cd76b964-ph79t   0/1     ContainerCreating   0          3s

And we only see the three Nginx pods. Let's take a look at our host cluster again. We'll switch to that kubeconfig.

$ export KUBECONFIG=~/.kube/config
$ kubectl get pods --all-namespaces

NAMESPACE     NAME                                                              READY   STATUS    RESTARTS   AGE
default       nginx-deployment-84cd76b964-64tbh                                 1/1     Running   0          24m
kube-system   coredns-f9fd979d6-mlctd                                           1/1     Running   0          77m
kube-system   coredns-f9fd979d6-pgnh8                                           1/1     Running   0          77m
kube-system   etcd-docker-desktop                                               1/1     Running   0          76m
kube-system   kube-apiserver-docker-desktop                                     1/1     Running   0          76m
kube-system   kube-controller-manager-docker-desktop                            1/1     Running   0          76m
kube-system   kube-proxy-j42rb                                                  1/1     Running   0          77m
kube-system   kube-scheduler-docker-desktop                                     1/1     Running   0          76m
kube-system   storage-provisioner                                               1/1     Running   0          77m
kube-system   vpnkit-controller                                                 1/1     Running   0          77m
level2        coredns-66c464876b-bg95z-x-kube-system-x-vc-level-3--e33a70f289   1/1     Running   0          8m56s
level2        coredns-66c464876b-gl66g-x-kube-system-x-vc-level-2               1/1     Running   0          24m
level2        nginx-deployment-84cd76b964-78wnp-x-default-x-vc-level-2          1/1     Running   0          9m17s
level2        nginx-deployment-84cd76b964-czlpz-x-default-x-vc-lev-af1154c6f7   1/1     Running   0          9s
level2        nginx-deployment-84cd76b964-kp4w6-x-default-x-vc-level-2          1/1     Running   0          9m17s
level2        nginx-deployment-84cd76b964-l292w-x-default-x-vc-lev-91ce9ee9e0   1/1     Running   0          9s
level2        nginx-deployment-84cd76b964-ph79t-x-default-x-vc-lev-5cdee9fab0   1/1     Running   0          9s
level2        vc-level-2-0                                                      2/2     Running   0          24m
level2        vc-level-3-0-x-level3-x-vc-level-2                                2/2     Running   0          9m9s

Here we see the Nginx deployment from our host cluster and the two virtual clusters. How does this all work? Each vcluster has an API server inside of it, but it doesn't have a scheduler. So the pods are synced to the host cluster and run there.

And that's a quick look at vcluster inception. You might not have a use case for running nested vclusters, but maybe you do. You could assign each developer at your company a namespace with a vcluster running, and allow them to create additional vclusters inside of it. Either way, it's great to know that to the person using a virtual cluster, it looks like a real Kubernetes cluster.

To learn more about vcluster go to vcluster.com or have a look at the code at github.com/loft-sh/vcluster.

Sign up for our newsletter

Be the first to know about new features, announcements and industry insights.