Skip to main content

Accessing vcluster

There are multiple ways how you can access a vcluster with an external application like kubectl.

Using the vcluster CLI#

Please make sure to install the vcluster CLI. Create a kubeconfig via:

# Create a kubeconfig.yaml
vcluster connect my-vcluster -n my-vcluster
# Execute a command directly with vcluster context
vcluster connect my-vcluster -n my-vcluster -- kubectl get namespaces
vcluster connect my-vcluster -n my-vcluster -- bash

Depending on if the vcluster was created with the --expose flag, the CLI will either start port-forwarding or create a kubeconfig that can be used directly.

If you have manually exposed the vcluster, you can specify the domain where the vcluster is reachable via the --server flag:

# Will create a kube config that uses https://my-domain.org as endpoint
vcluster connect my-vcluster -n my-vcluster --server my-domain.org

Connect via Service Accounts#

By default, vcluster will create a kube config to access the vcluster that contains the default admin client certificate and client key to authenticate to the vcluster. This means that all kube configs generated will have cluster admin access within the vcluster.

Often this might not be desired. Instead of giving a user admin access to the virtual cluster, you can also use service account authentication to the virtual cluster. Let's say we want to create a kube config that only has view access in the virtual cluster. Then you would create a new service account inside the vcluster and assign it the cluster role view via a cluster role binding. Then we would generate a service account token and use that instead of the client-cert and client-key inside the kube config.

With vcluster version v0.6.0 and higher you can automatically do this via the CLI:

vcluster connect my-vcluster -n my-vcluster --service-account kube-system/my-user --cluster-role view
# OR: create a kube config for a cluster admin
vcluster connect my-vcluster -n my-vcluster --service-account kube-system/my-user --cluster-role cluster-admin
# OR: create a kube config that expires after an hour
vcluster connect my-vcluster -n my-vcluster --service-account kube-system/my-user --cluster-role view --token-expiration 3600

This will create a kube config similar to this as well as create the needed service account and cluster role binding:

apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0t...
server: https://localhost:8443
name: local
contexts:
- context:
cluster: local
namespace: default
user: user
name: Default
current-context: Default
kind: Config
preferences: {}
users:
- name: user
user:
token: eyJhbGc...

As you can see the service account token is used in this kube config here instead of the client-cert and client-key that is used by default. Trying to create a namespace with this config will yield:

export KUBECONFIG=kubeconfig.yaml
# This will work as we have view access
kubectl get namespaces
# This won't work
kubectl create namespace test
Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount:kube-system:my-user" cannot create resource "namespaces" in API group "" at the cluster scope

You can replace the token field in the kube config with any other service account token from inside the vcluster to act as this service account against the vcluster. For more information about service accounts and tokens, please refer to the official Kubernetes documentation.

Retrieving the kube config from the vcluster secret#

There might be cases where connecting to a vcluster with the CLI is not feasible or the CLI cannot be installed. For such cases, you can retrieve the vcluster kube config from a secret that is created automatically in the vcluster namespace.

The secret is prefixed with vc- and ends with the vcluster name, so a vcluster called my-vcluster in namespace test would create a secret called vc-my-vcluster in the namespace test. You can retrieve the kube config after the vcluster has started via:

kubectl get secret vc-my-vcluster -n test --template={{.data.config}} | base64 -D

The secret will hold a kube config in this format:

apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0t...
server: https://localhost:8443
name: local
contexts:
- context:
cluster: local
namespace: default
user: user
name: Default
current-context: Default
kind: Config
users:
- name: user
user:
client-certificate-data: LS0tLS...
client-key-data: LS0tLS...

By default, the server https://localhost:8443 is used that would work if you port forward the vcluster with:

kubectl port-forward my-vcluster-0 -n test 8443
tip

With the syncer flag --out-kube-config-secret-namespace you can specify a different namespace where the kube config secret should be created in. Keep in mind that you have to manually apply RBAC permissions for the vcluster to allow creation and retrieving of secrets in that namespace.

Externally accessible vclusters#

If you have exposed the vcluster, you can also tell the vcluster to create the kube config secret with another server endpoint through the --out-kube-config-server flag.

For example, if you want to expose a vcluster at https://my-domain.org, you can create a values.yaml like this:

# Make sure vcluster will sign the server certs for my-domain.org
# and use it in the generated kube config secret.
syncer:
extraArgs:
- --tls-san=my-domain.org
- --out-kube-config-server=https://my-domain.org

Then you can create or upgrade the vcluster with:

vcluster create my-vcluster -n my-vcluster -f values.yaml

Wait until the vcluster has started and you can retrieve the kube config via:

kubectl get secret vc-my-vcluster -n my-vcluster --template={{.data.config}} | base64 -D