Configure External Access & TLS
After deploying the platform, you may want to access the deployment via a routable IP address or a resolvable domain name. You may also wish to secure the deployment with a TLS certificate. This is particularly useful for sharing platform access with other team members who may or may not have direct access to Kubernetes.
Setting up the platform for access via routable IP or domain name, and securing it via TLS requires the following:
- The cluster where the platform is deployed must have an available load balancer or ingress controller
- Appropriate DNS settings must be in place
- A mechanism for assigning TLS certificates (such as cert-manager) must be available
External access​
The platform, like any other service in Kubernetes, can be exposed in multiple ways. The LoadBalancer method is recommended. The NGINX ingress controller examples below are preserved for reference but the ingress-nginx project is deprecated upstream. Use a LoadBalancer or a Gateway API-compatible controller for new deployments.
[Deprecated]: External access via NGINX ingress controller​
- Automatic or existing installation
- Manual ingress controller installation
The ingress-nginx project has been deprecated. We recommend using a different ingress controller.
This section assumes you already have the nginx ingress controller installed, if you don't, check out the 'Manual Ingress Controller Installation' tab.
Run the command:
Start the platformvcluster platform start --host=vcluster-platform.mydomain.tldUpdate the Domain.Make sure you update the hostname in the command.
Set the
VERSIONvariable to the platform version you want to upgrade to or set it to the current version using:Set VERSION variableCHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})VERSION=${CHART:5}To upgrade the platform via vCluster CLI, update
$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platformvcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yamlVersions and ValuesThe
$PLATFORM_VERSIONvariable is an environment variable set to your desired platform version to deploy. Thevcluster-platform.yamlfile is an optional YAML file that contains Helm values you would like to use when upgrading your platform deployment.Determine the External-IP address:
Get the loft-ingress external IP addresskubectl get ingress -n vcluster-platformNAME CLASS HOSTS ADDRESS PORTS AGEloft-ingress <none> vcluster-platform.mydomain.tld x.x.x.x 80, 443 10mAddressIf you never get a valid IP Address in the ADDRESS column shown in the command, you might need to work with your Kubernetes administrator to ensure your ingress is properly configured.
Set up a DNS A record to the ingress address. Make sure the platform is reachable at the address, you can check that with curl as shown below, or simply browse to the address in your browser of choice:
Check the platform versioncurl https://vcluster-platform.mydomain.tld/version --insecure | jq{"kind": "Version","apiVersion": "version.loft.sh","metadata": {"creationTimestamp": null},"version": "v3.0.0","major": "3","minor": "0","instance": "","kubeVersion": "v1.24.2","newerVersion": "","shouldUpgrade": false}
The ingress-nginx project has been deprecated. We recommend using a different ingress controller.
[Deprecated]: Deploy
nginx-ingresscontroller to your cluster. Update$PLATFORM_VERSIONwith a valid platform version.[Deprecated- the ingress-nginx project has been deprecated]: Deploy ingress-nginx controllerhelm upgrade --install ingress-nginx ingress-nginx \--repository-config='' \-n ingress-nginx \--create-namespace \--repo https://kubernetes.github.io/ingress-nginx \--set-string controller.config.hsts=false \--wait \--version $PLATFORM_VERSION[Deprecated]: To update the platform deployment to use the NGINX ingress controller, create a simple values file that tells the platform to do just that. If you created a values file during your initial deployment, you can simply edit that file, if you did not, you can create a new file with the following contents.
[Deprecated- the ingress-nginx project has been deprecated]: Update to use NGINX ingress controlleringress:enabled: truehost: "vcluster-platform.mydomain.tld" # Make sure to change thisingressClass: "nginx" # Optional, nginx is default value!To upgrade the platform via vCluster CLI, update
$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platformvcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yamlVersions and ValuesThe
$PLATFORM_VERSIONvariable is an environment variable set to your desired platform version to deploy. Thevcluster-platform.yamlfile is an optional YAML file that contains Helm values you would like to use when upgrading your platform deployment.Determine the External-IP address:
Get the loft-ingress external IP addresskubectl get ingress -n vcluster-platformNAME CLASS HOSTS ADDRESS PORTS AGEloft-ingress <none> vcluster-platform.mydomain.tld x.x.x.x 80, 443 10mAddressIf you never get a valid IP Address in the ADDRESS column shown in the command, you might need to work with your Kubernetes administrator to ensure your ingress is properly configured.
Set up a DNS A record to the ingress address. Make sure the platform is reachable at the address, you can check that with curl as shown below, or simply browse to the address in your browser of choice:
Check the platform versioncurl https://vcluster-platform.mydomain.tld/version --insecure | jq{"kind": "Version","apiVersion": "version.loft.sh","metadata": {"creationTimestamp": null},"version": "v3.0.0","major": "3","minor": "0","instance": "","kubeVersion": "v1.24.2","newerVersion": "","shouldUpgrade": false}
External access via LoadBalancer​
- AWS ELB + ACM
- Other load balancers
AWS Load BalancersIf you are using AWS, make sure you are using a Network Load Balancer (NLB) to route traffic, since other load balancers do not support the SPDY protocol Kubernetes requires.
Create a LoadBalancer ServiceapiVersion: v1kind: Servicemetadata:annotations:# Make sure to adjust the next line:service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:eu-west-2:xxx:certificate/xxx"service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "tcp"service.beta.kubernetes.io/aws-load-balancer-type: "nlb"name: vcluster-platform-loadbalancernamespace: vcluster-platformspec:type: LoadBalancerports:- name: httpport: 80protocol: TCPtargetPort: 8080- name: httpsport: 443protocol: TCPtargetPort: 10443selector:app: loftCreate a LoadBalancer ServiceapiVersion: v1kind: Servicemetadata:name: vcluster-platform-loadbalancernamespace: vcluster-platformspec:type: LoadBalancerports:- name: httpsport: 443targetPort: 10443protocol: TCPselector:app: loftCreate the load balancer with this command:
Create the LoadBalancer Servicekubectl apply -f vcluster-platform-loadbalancer.yamlWait until the load balancer receives an External-IP address:
Get the vcluster-platform-loadbalancer external IP addresskubectl get svc vcluster-platform-loadbalancer -n vcluster-platformNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEvcluster-platform-loadbalancer LoadBalancer 10.112.2.142 x.x.x.x 443:30933/TCP 3m16sMake sure the platform is reachable at the load balancer's external address, you can check that with curl as shown below, or simply browse to the address in your browser of choice:
Check the platform versioncurl https://x.x.x.x/version --insecure | jq{"kind": "Version","apiVersion": "version.loft.sh","metadata": {"creationTimestamp": null},"version": "v3.0.0","major": "3","minor": "0","instance": "","kubeVersion": "v1.24.2","newerVersion": "","shouldUpgrade": false}
Configure TLS​
This section provides various options for configuring TLS for your platform deployment. Choose the method that best fits your infrastructure and requirements.
Cert-Manager​
Install
cert-managerto your cluster:Install cert-managerhelm upgrade --install cert-manager cert-manager --repository-config=''\--namespace cert-manager --create-namespace \--repo https://charts.jetstack.io \--set installCRDs=true \--waitEdit your existing
vcluster-platform.yamlfile, or create a new file namedvcluster-platform.yamlwith the following content:vcluster-platform.yamlingress:enabled: trueannotations:# Make sure the following line matches the name of your issuer (or use the section below to create one)cert-manager.io/cluster-issuer: lets-encrypt-http-issuertls:enabled: truesecret: tls-vcluster-platformcertIssuer:create: true # Change this if you already have your own cert-issuername: lets-encrypt-http-issueremail: "YOUR_EMAIL" # REQUIREDsecretName: vcluster-platform-letsencrypt-credentialshttpResolver:enabled: trueingressClass: nginx # the ingress-nginx project has been deprecatedresolvers: []server: https://acme-v02.api.letsencrypt.org/directorySet the
VERSIONvariable to the platform version you want to upgrade to or set it to the current version using:Set VERSION variableCHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})VERSION=${CHART:5}Upgrade the platform
Upgrade considerations- Review the release notes for the target version to understand any breaking changes or new features.
- Test the upgrade in a non-production environment before applying it to your production setup.
Upgrade the platform via:
- CLI
- Helm
To upgrade the platform using the
vclusterCLI, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latestvcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if differentRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latesthelm upgrade $RELEASE_NAME vcluster-platform -n $RELEASE_NAMESPACE --repository-config '' --repo https://charts.loft.sh \--version $PLATFORM_VERSION \--reuse-values \-f vcluster-platform.yaml
AWS Certificate Manager (ACM)​
- Domain via ingress
- Domain via load balancer
Determine the External-IP address of your ingress:
Get ingress external IPkubectl get ingress -n vcluster-platformNAME CLASS HOSTS ADDRESS PORTS AGEloft-ingress <none> vcluster-platform.mydomain.tld x.x.x.x 80, 443 10m^^^^^^^Find the AWS Elastic Load Balancer (ELB) for this IP address in the AWS console.
Switch to the "Listeners" tab.
In the "SSL Certificates" column, click on the "View/edit certificates" link.
Click on the "+" symbol next to the "Certificates" tab and add your Access Control Manager (ACM) managed certificate to the ingress controller's Load Balancer.
Make sure to follow the Load Balancer > AWS ELB + ACM guide above.
Manually provisioned certificate​
Create a Kubernetes secret from your certificate:
Create TLS secretkubectl create secret generic tls-vcluster-platform -n vcluster-platform --type=kubernetes.io/tls \--from-file=tls.crt=tls.crt \--from-file=tls.key=tls.keyEdit your existing
vcluster-platform.yamlfile, or create a new file namedvcluster-platform.yamlwith the following content:- Platform ingress handles TLS
- Platform pod handles TLS
- Load balancer handles TLS
vcluster-platform.yaml for ingress TLSingress:tls:enabled: truesecret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous stepIf you want to configure the platform with additionalCA, the Certificate Authority used for signing this certificate has to be added as a base64 encoded value:
Encode CA certificatecat ca.crt | base64Use this output in the
.additionalCAhelm value.vcluster-platform.yaml for pod TLStls:enabled: truesecret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous stepThis must be configured outside of the platform deployment.
Set the
VERSIONvariable to the platform version you want to upgrade to or set it to the current version using:Set VERSION variableCHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})VERSION=${CHART:5}Upgrade the platform
Upgrade considerations- Review the release notes for the target version to understand any breaking changes or new features.
- Test the upgrade in a non-production environment before applying it to your production setup.
Upgrade the platform via:
- CLI
- Helm
To upgrade the platform using the
vclusterCLI, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latestvcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if differentRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latesthelm upgrade $RELEASE_NAME vcluster-platform -n $RELEASE_NAMESPACE --repository-config '' --repo https://charts.loft.sh \--version $PLATFORM_VERSION \--reuse-values \-f vcluster-platform.yaml
Self-signed certificate​
For testing or internal use, you can create and use a self-signed certificate.
Create a new private key for Certificate Authority:
Generate CA private keyopenssl genrsa 2048 > ca-key.pemCreate a new certificate authority:
Generate CA certificateopenssl req -new -x509 -nodes -days 365000 -key ca-key.pem -out ca.crtCreate a new private key:
Generate private keyopenssl genrsa -out tls.key 4096Create a file named
ssl.confwith the following content:ssl.conf[ req ]default_bits = 4096distinguished_name = req_distinguished_namex509_extensions = v3_careq_extensions = v3_reqx509_extensions = usr_cert[ req_distinguished_name ]organizationName = Organization Name (for example company)organizationName_default = vcluster-platformcommonName = Common Name (for example server FQDN or YOUR name)commonName_default = vcluster-platform.mydomain.tld[ usr_cert ]basicConstraints = CA:FALSEnsCertType = client, serverkeyUsage = digitalSignatureextendedKeyUsage = serverAuth, clientAuth[ v3_req ]subjectAltName = @alt_namesextendedKeyUsage = serverAuth, clientAuthbasicConstraints = CA:FALSEkeyUsage = digitalSignature[ alt_names ]DNS.1 = localhostSet
commonName_defaultandDNS.1to the domain you want to use.Create a certificate signing request:
Generate certificate signing requestopenssl req -new -sha256 \-out tls.csr \-key tls.key \-config ssl.confGenerate the certificate:
Generate certificateopenssl x509 -req \-sha256 \-days 3650 \-in tls.csr \-out tls.crt \-extensions v3_req \-extfile ssl.conf \-CA ca.crt \-CAkey ca-key.pemCreate a Kubernetes secret from your certificate:
Create TLS secretkubectl create secret generic tls-vcluster-platform -n vcluster-platform --type=kubernetes.io/tls \--from-file=tls.crt=tls.crt \--from-file=tls.key=tls.keyIf you want to configure the platform with additionalCA, use:
Encode CA certificatecat ca.crt | base64as an input for the
.additionalCAhelm value.Edit your existing
vcluster-platform.yamlfile, or create a new file namedvcluster-platform.yamlwith the following content:- Platform ingress handles TLS
- Platform pod handles TLS
- Load balancer handles TLS
vcluster-platform.yaml for ingress TLSingress:tls:enabled: truesecret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous steptls:enabled: true # Virtual clusters running on the same host as the platform directly use the platform service.secret: tls-vcluster-platform # Ensure this matches the name of your cert from the previous stepvcluster-platform.yaml for pod TLStls:enabled: truesecret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous stepThis must be configured outside of the platform deployment.
Set the
VERSIONvariable to the platform version you want to upgrade to or set it to the current version using:Set VERSION variableCHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})VERSION=${CHART:5}Upgrade the platform
Upgrade considerations- Review the release notes for the target version to understand any breaking changes or new features.
- Test the upgrade in a non-production environment before applying it to your production setup.
Upgrade the platform via:
- CLI
- Helm
To upgrade the platform using the
vclusterCLI, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latestvcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm, update$PLATFORM_VERSIONwith a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if differentRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if differentPLATFORM_VERSION='' # Set this to a specific version or leave empty for latesthelm upgrade $RELEASE_NAME vcluster-platform -n $RELEASE_NAMESPACE --repository-config '' --repo https://charts.loft.sh \--version $PLATFORM_VERSION \--reuse-values \-f vcluster-platform.yaml
Import tenant clusters with certificate validation​
When importing externally managed tenant clusters, you can enable secure communication by using the same certificate authority configured for the platform.
- Get the current certificate authority value from your platform:
helm get values --namespace $RELEASE_NAMESPACE $RELEASE_NAME --all | grep additionalCA
- Import the tenant cluster with certificate validation:
vcluster platform add vcluster <VCLUSTER_NAME> \
--namespace=<VCLUSTER_NAMESPACE> \
--project=<PROJECT_NAME> \
--ca-data <BASE64_CA_VALUE>
The imported tenant cluster restarts and reports Ready once it establishes a secure connection to the platform.