Skip to main content
Version: v0.25 Stable

Deploy vCluster in an air-gapped environment

Enterprise-Only Feature

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.

important

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.

warning

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​

note

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.

    info

    To 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 installed
    • docker 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​

  1. Set environment variables for the version of vCluster that you want to deploy and the private registry.

    Export environment variables
     export 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 paths
  2. Download the assets from the vCluster GitHub release and make the scripts executable.

    note

    The 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 scripts
    wget 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.sh
  3. Run 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
  4. 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}
  5. 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.

    note

    The 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​

  1. 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 variables
    export VCLUSTER_VERSION=0.25.0 # Replace with the desired version
    export REGISTRY=ecr.io/myteam # A charts folder is expected
    note

    The private registry assumes having a /charts folder, which is where to push all the Helm charts.

  2. 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 registry
    helm 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.

Setting the private registry
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.

Image pull secrets configuration
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.

Specific Kubernetes version configuration
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.

Replace the alpine 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​

  1. 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 namespace
    export VCLUSTER_NAMESPACE=vcluster-my-vcluster  # Replace with the name of the namespace you want to deploy your vCluster into
    kubectl create namespace ${VCLUSTER_NAMESPACE}
  2. 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 credentials
    kubectl 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
    EOF
  3. Review your vcluster.yaml file.

    vcluster.yaml configuration
    controlPlane:
    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 secret
  4. Deploy vCluster into the namespace where you deployed the secrets.

    Deploy vCluster with Helm
    export 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
tip

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
vcluster.yaml configuration for FIPS compliant environment
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