Deploy vCluster in an air-gapped environment
This feature is an Enterprise feature. See our pricing plans or contact our sales team for more information.
This document explains how to deploy vCluster in environments without internet access, known as air-gapped environments.
Enterprise features require the vCluster Platform.
If you deploy a vCluster in an air-gapped environment and want to use enterprise features, you must also deploy the platform in air-gapped mode and connect the vCluster to it. A standalone air-gapped vCluster does not support any enterprise capabilities.
Overview​
When deploying vCluster, there are artifacts that are typically accessed using an internet connection, but without access to the internet, these artifacts need to be available to the Kubernetes cluster through a private registry:
- vCluster Helm chart—Typically retrieved from the LoftLabs Helm chart repository.
- Container images referenced in the Helm chart—Usually pulled from various public container registries.
After uploading the required artifacts to your private registry, create the vcluster.yaml
configuration file and prepare the host cluster for deployment.
When using virtual clusters in air-gapped environments, the
config.experimental.deploy.vcluster.helm
configuration setting does not work with external Helm repositories since they cannot be accessed. This means custom Helm charts from repositories like charts.bitnami.com
cannot be used for virtual cluster deployments.
Prerequisites​
You must have the vCluster Platform deployed in your air-gapped environment to use this guide. To prepare your environment for air-gapped deployment, see the platform air-gapped installation guide.
Registry requirements​
- OCI-compliant private registry with a
/charts
folder - A private registry accessible to both the Kubernetes host cluster and a separate, internet-connected machine. - Ability to push images and Helm charts to your private registry.
Deployment requirements​
Ensure you have the following:
-
Administrator access to a Kubernetes cluster: See Accessing Clusters with kubectl for more information. Run the command
kubectl auth can-i create clusterrole -A
to verify that your current kube-context has administrative privileges.infoTo obtain a kube-context with admin access, ensure you have the necessary credentials and permissions for your Kubernetes cluster. This typically involves using
kubectl config
commands or authenticating through your cloud provider's CLI tools. -
helm
: Helm v3.10 is required for deploying the platform. Refer to the Helm Installation Guide if you need to install it. -
kubectl
: Kubernetes command-line tool for interacting with the cluster. See Install and Set Up kubectl for installation instructions.
-
Access to pull the Helm chart and images from the private registry
-
On the internet-connected machine for populating the registry:
wget
installeddocker
installed- You are logged into GitHub Container Registry
Populate images to a private registry​
Each vCluster release includes multiple assets to help you upload the images to your private registry.
images.txt
- The required images to run vCluster, which assumes using the default Kubernetes version.images-optional.txt
- An optional set of images to run vCluster using a different Kubernetes version.download-images.sh
- A bash script that quickly iterates over all the images files to pull them and package them into a tarball to a machine that has internet access.push-images.sh
- A bash script that takes the tarball generated from the download script to push them to your private registry.
Pull and push images​
Set environment variables for the version of vCluster that you want to deploy and the private registry.
Export environment variablesexport VCLUSTER_VERSION=0.25.0 # Replace with the desired version
export REGISTRY=ecr.io/myteam # This should be a prefix; do not include any image pathsDownload the assets from the vCluster GitHub release and make the scripts executable.
noteThe
images.txt
contains all distributions for the default Kubernetes version. You can edit the file and remove the images for unused distributions.Download assets and prepare scriptswget https://github.com/loft-sh/vcluster/releases/download/v"${VCLUSTER_VERSION}"/images.txt
wget https://github.com/loft-sh/vcluster/releases/download/v"${VCLUSTER_VERSION}"/download-images.sh
wget https://github.com/loft-sh/vcluster/releases/download/v"${VCLUSTER_VERSION}"/push-images.sh
chmod +x ./download-images.sh
chmod +x ./push-images.shRun
download-images.sh
to pull all images and create a tarball of the images.Review the output to confirm all images were pulled successfully and packaged in the tarball.
Download and package images./download-images.sh --image-list images.txt
Run
push-images.sh
to upload all required images to your private registry.When pushing images into your private registry, the public private registry is removed and only the repository and image name are pushed. This allows vCluster to set your private registry to use for all images used in deploying vCluster.
Push images to private registry./push-images.sh --registry ${REGISTRY}
Optional: If you want to deploy vCluster with a different Kubernetes version, download the
images-optional.txt
file. It contains additional container images required for that version, which you'll need to pull and push to your private registry.The
images-optional.txt
contains multiple Kubernetes distributions and versions. You can edit the file and remove the images for the unwanted distributions and versions.noteThe
images-optional.txt
contains multiple Kubernetes distributions and versions. You can edit the file and remove the images for the unused distributions and versions.wget https://github.com/loft-sh/vcluster/releases/download/v${VCLUSTER_VERSION}/images-optional.txt
./download-images.sh --image-list images-optional.txt --images vcluster-images-optional.tar.gz
./push-images.sh --registry ${REGISTRY} --images vcluster-images-optional.tar.gz
Populate the vCluster Helm chart to a private registry​
You must push the vCluster Helm chart to your OCI-compliant private registry.
Pull and push the vCluster Helm chart​
Optional: If you haven’t already set the environment variables, set them now before continuing.
The private registry assumes having a
/charts
folder, which is where to push all the Helm charts.Export environment variablesexport VCLUSTER_VERSION=0.25.0 # Replace with the desired version
export REGISTRY=ecr.io/myteam # A charts folder is expectednoteThe private registry assumes having a
/charts
folder, which is where to push all the Helm charts.Pull the vCluster Helm chart and push it into your private registry with the OCI protocol.
Pull and push the Helm chart to your private registryhelm pull vcluster --repo https://charts.loft.sh --version ${VCLUSTER_VERSION}
helm push vcluster-${VCLUSTER_VERSION}.tgz oci://${REGISTRY}/charts
Configure vCluster​
The vcluster.yaml
file contains all configuration settings for your vCluster deployment.
Use a private registry without credentials
Set the default private registry that doesn't have authentication.
controlPlane:
advanced:
defaultImageRegistry: ecr.io/myteam # Replace with your private registry
Use an authenticated private registry
For registries that require authentication, create a Kubernetes secret in the namespace where you deploy the vCluster. Assign the secret as an image pull secret for the vCluster control plane to access required images.
Optionally, you can use the same image pull secret for workloads inside the vCluster that pull from the same registry.
controlPlane:
advanced:
defaultImageRegistry: ecr.io/myteam # Replace with your private image registry
serviceAccount:
imagePullSecrets: # Uses credentials for the vCluster control plane
- name: registry-credentials-secret-name # Replace with the name of the secret deployed on the host cluster of where the vCluster is deployed
workloadServiceAccount: # Uses credentials for any workloads created in the vCluster
imagePullSecrets:
- name: registry-credentials-secret-name # Replace with the name of the secret deployed on the host cluster of where your vCluster is deployed
Use a non-default Kubernetes version
If you downloaded images-optional.txt
to use a different Kubernetes version, configure vCluster to use that version in your deployment.
controlPlane:
distro:
k8s:
image:
tag: v1.31.1 # Replace with the Kubernetes version that you have chosen
Replace the alpine image
If you use the sync.toHost.pods.rewriteHosts
feature, manually replace the full path of the alpine image with your private registry path.
The defaultImageRegistry
setting does not apply to this image.
sync:
toHost:
pods:
rewriteHosts:
initContainer:
image: your-registry/library/alpine:3.20
Create a platform access key​
Before deploying vCluster, you must create an access key to authenticate your virtual cluster. This step is essential for connecting your air-gapped vCluster to the platform.
Deploy vCluster​
After the platform is deployed, the access key is created, and your private registry is populated with the required images and charts, you can proceed with deploying the vCluster.
Set up the host cluster and deploy​
On the host cluster, create the namespace for the vCluster, where the secrets and vCluster control plane pod are to be deployed in:
Create vCluster namespaceexport VCLUSTER_NAMESPACE=vcluster-my-vcluster # Replace with the name of the namespace you want to deploy your vCluster into
kubectl create namespace ${VCLUSTER_NAMESPACE}Optional: Create a secret to authenticate to your private registry.
If your private registry requires authentication, create a Kubernetes secret that stores your login credentials. Place this secret in the same namespace where the vCluster is deployed so the control plane can pull the required container images.
Create Kubernetes secret for login credentialskubectl create -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: registry-credentials-secret-name
namespace: ${VCLUSTER_NAMESPACE}
type: Opaque
data:
# Credentials based on your private registry
EOFReview your
vcluster.yaml
file.vcluster.yaml configurationcontrolPlane:
advanced:
defaultImageRegistry: ecr.io/myteam # Replace with your private image registry
serviceAccount:
imagePullSecrets:
- name: registry-credentials-secret-name # Replace with the name of the registry credentials secret
workloadServiceAccount:
imagePullSecrets:
- name: registry-credentials-secret-name # Replace with the name of the registry credentials secret
external:
platform:
apiKey:
secretName: vcluster-platform-api-key # Name of the secret containing the access key
namespace: vcluster-platform # Namespace where the secret is located (optional)
createRBAC: true # Automatically create RBAC to access the secretDeploy vCluster into the namespace where you deployed the secrets.
Deploy vCluster with Helmexport VCLUSTER_VERSION=0.25.0 # Replace with the chart version that was pushed into your private registry
export REGISTRY=myecr.io/team # Replace with the private registry
export VCLUSTER_NAME="my-vcluster" # Replace with what you want to name your vCluster
helm upgrade --install "${VCLUSTER_NAME}" oci://${REGISTRY}/charts/vcluster:${VCLUSTER_VERSION} \
--version ${VCLUSTER_VERSION} \
--values vcluster.yaml \
--namespace ${VCLUSTER_NAMESPACE} \
Air-gapped vCluster with FIPS images​
To run vCluster in a FIPS-compliant environment, you must push FIPS-compliant images to your private registry.
Push the following images, using the appropriate Kubernetes version as the tag.
Tags are listed in the images.txt
and images-optional.txt
files.
ghcr.io/loft-sh/vcluster-pro-fips
ghcr.io/loft-sh/kubernetes-fips
The steps for pulling, tagging, and pushing these images are the same as for standard images. The only difference is that you reference the FIPS-compliant images instead.
For more details on FIPS, refer to the FIPS configuration guide.
The following is an example vcluster.yaml
configuration with the FIPS compliant images.
FIPS configuration
controlPlane:
advanced:
defaultImageRegistry: ghcr.io
virtualScheduler:
enabled: true
backingStore:
etcd:
embedded:
enabled: true
coredns:
embedded: true
distro:
k8s: # FIPS support is only available for the K8s distribution
enabled: true
image:
repository: loft-sh/kubernetes-fips
tag: v1.28.14
hostPathMapper:
enabled: true
statefulSet:
image:
repository: loft-sh/vcluster-pro-fips
resources:
limits:
cpu: 2
memory: 4Gi
requests:
cpu: 0
memory: 0
scheduling:
podManagementPolicy: OrderedReady
external:
platform:
apiKey:
secretName: license
policies:
limitRange:
enabled: false
podSecurityStandard: privileged
resourceQuota:
enabled: false
pro: true
external:
platform:
apiKey:
secretName: vcluster-platform-api-key