Skip to main content

Cluster API Provider

Cluster API (CAPI) is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters. Kubernetes service providers and distribution maintainers implement CAPI providers which allow users to create Kubernetes clusters of their choice with the CAPI tooling. For the vcluster project, we have also implemented a CAPI provider - cluster-api-provider-vcluster. Instructions below will describe how to instantiate a vcluster instance using CAPI tooling.

Prerequisites#

clusterctl (v1.1.5+) CLI tool is used to install the vcluster provider and to generate a custom resource that will serve as a declarative definition of the cluster. It is possible to create the custom resource without clusterctl, but in this guide, we will be using it because it provides access to the templates for the VCluster custom resource. Please follow the official installation instructions for clusterctl.

You will need cluster-admin permissions in a Kubernetes cluster where you wish to install the CAPI stack with the vcluster provider. This is required because vcluster instances that will be created by the vcluster provider may have arbitrary RBAC permission requirements. The vcluster provider installation with a more limited permission scope will be introduced in a future version.

Installing the CAPI stack with the vcluster provider#

Switch your kubectl context to the cluster where you wish to install the CAPI stack with the vcluster provider and run the following command:

clusterctl init --infrastructure vcluster

The "Your management cluster has been initialized successfully!" message should eventually appear in the output.

Creating a vcluster#

We will use the clusterctl CLI tool to generate the Kubernetes resource definitions needed for vcluster creation by the CAPI provider. The output is in YAML format, and it can be saved into a file to be used later, or it can be forwarded in the command line into the kubectl command to immediately apply the resources in the cluster.

A vcluster instance created via vcluster provider is configured using the following environment variables:

  • KUBERNETES_VERSION (required, string - major.minor.patch): sets the major and minor Kubernetes version of the vcluster, but the patch part is ignored(!). The --kubernetes-version flag can be used instead of the environment variable.
  • HELM_VALUES (required, string - YAML formatted): A string representation of your "values.yaml" file, which defines helm values to be used when installing, or upgrading, your vcluster instance using the helm chart. An empty string - "" is an acceptable value.
  • CHART_NAME (optional, string): vcluster helm chart name, defaults to vcluster
  • CHART_REPO (optional, string - url): vcluster helm chart repo, defaults to https://charts.loft.sh
  • CHART_VERSION (optional, string - major.minor.patch): vcluster helm chart version, default value depends on the version of the provider, typicaly latest version at the time of the release
  • VCLUSTER_HOST (optional, string): a vcluster hostname that shall be used to set the .spec.controlPlaneEndpoint.hostname field of the vcluster custom resource, which will be used for example in the generated kubeconfig.
  • VCLUSTER_PORT (optional, number - 0:65535): a vcluster port that shall be used to set the .spec.controlPlaneEndpoint.port field of the vcluster custom resource

We will define some configuration elements (CLUSTER_NAME and CLUSTER_NAMESPACE) as environment variables for easier reuse across the commands. These will be used together with some of the environment variables mentioned above to produce a manifest defining your vcluster instance and apply it in the host cluster:

export CLUSTER_NAME=vcluster
export CLUSTER_NAMESPACE=vcluster
export KUBERNETES_VERSION=1.23.0
export HELM_VALUES=""
kubectl create namespace ${CLUSTER_NAMESPACE}
clusterctl generate cluster ${CLUSTER_NAME} \
--infrastructure vcluster \
--target-namespace ${CLUSTER_NAMESPACE} | kubectl apply -f -
tip

You can populate the HELM_VALUES variable from a values.yaml file using this command: export HELM_VALUES=$(cat values.yaml | python -c 'import yaml,sys; print(yaml.dump(sys.stdin.read()).strip()[1:-1])')

Next, we need to wait until vcluster custom resource reports ready status:

kubectl wait --for=condition=ready vcluster -n $CLUSTER_NAMESPACE $CLUSTER_NAME

The cluster is ready to be used once the command above exits.

Expose vcluster externally#

There are multiple methods for exposing your vcluster instance, and they are described on the exposing vcluster page.

If the documentation instructs you to update your values.yaml file, you will need to update the HELM_VALUES environment variable, execute the clusterctl generate cluster again, and apply the updated output to your cluster.
Alternatively, you can edit the .spec.helmRelease.values field of the vcluster custom resource using kubectl edit vcluster -n $CLUSTER_NAMESPACE $CLUSTER_NAME command. Be mindful of the formatting of the value: the string should be a valid YAML file, with the expected indentation for the various helm values. The vcluster provider is watching for the changes made to vcluster custom resource, and it will automatically update the vcluster instance when changes are detected.

Connecting to your vcluster#

The recommended way of connecting to your vcluster is to use vcluster CLI as described in the accessing vcluster page.

However, if your vcluster is created with the vcluster provider, and you expose your cluster externally, you have an alternative:
clusterctl get kubeconfig ${CLUSTER_NAME} --namespace ${CLUSTER_NAMESPACE} > ./kubeconfig.yaml
More details about this command are in the CAPI docs.