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. This section outlines how to expose the platform via an ingress controller (using NGINX ingress controller as an example) and via a LoadBalancer
.
External access via NGINX ingress controller​
- Automatic or existing installation
- Manual ingress controller installation
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.tld
Update the Domain.Make sure you update the hostname in the command.
Set the
VERSION
variable 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_VERSION
with a valid platform version and run:Upgrade the platformvcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
Versions and ValuesThe
$PLATFORM_VERSION
variable is an environment variable set to your desired platform version to deploy. Thevcluster-platform.yaml
file 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-platform
NAME CLASS HOSTS ADDRESS PORTS AGE
loft-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 (x.x.x.x). 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
}
Deploy
nginx-ingress
controller to your cluster. Update$PLATFORM_VERSION
with a valid platform version.Deploy nginx-ingress 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_VERSIONTo 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.
Update to use NGINX ingress controlleringress:
enabled: true
host: "vcluster-platform.mydomain.tld" # Make sure to change this
ingressClass: "nginx" # Optional, nginx is default value!To upgrade the platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platformvcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
Versions and ValuesThe
$PLATFORM_VERSION
variable is an environment variable set to your desired platform version to deploy. Thevcluster-platform.yaml
file 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-platform
NAME CLASS HOSTS ADDRESS PORTS AGE
loft-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 (x.x.x.x). 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: v1
kind: Service
metadata:
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-loadbalancer
namespace: vcluster-platform
spec:
type: LoadBalancer
ports:
- name: http
port: 80
protocol: TCP
targetPort: 8080
- name: https
port: 443
protocol: TCP
targetPort: 10443
selector:
app: loftCreate a LoadBalancer ServiceapiVersion: v1
kind: Service
metadata:
name: vcluster-platform-loadbalancer
namespace: vcluster-platform
spec:
type: LoadBalancer
ports:
- name: https
port: 443
targetPort: 10443
protocol: TCP
selector:
app: loftCreate the load balancer with this command:
Create the LoadBalancer Servicekubectl apply -f vcluster-platform-loadbalancer.yaml
Wait until the load balancer receives an External-IP address:
Get the vcluster-platform-loadbalancer external IP addresskubectl get svc vcluster-platform-loadbalancer -n vcluster-platform
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
vcluster-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-manager
to 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.yaml
file, or create a new file namedvcluster-platform.yaml
with the following content:vcluster-platform.yamlingress:
enabled: true
annotations:
# 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-issuer
tls:
enabled: true
secret: tls-vcluster-platform
certIssuer:
create: true # Change this if you already have your own cert-issuer
name: lets-encrypt-http-issuer
email: "YOUR_EMAIL" # REQUIRED
secretName: vcluster-platform-letsencrypt-credentials
httpResolver:
enabled: true
ingressClass: nginx
resolvers: []
server: https://acme-v02.api.letsencrypt.org/directorySet the
VERSION
variable 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
vcluster
CLI, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm
, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if different
RELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
helm 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-platform
NAME CLASS HOSTS ADDRESS PORTS AGE
loft-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.yaml
file, or create a new file namedvcluster-platform.yaml
with the following content:- Platform ingress handles TLS
- Platform pod handles TLS
- Load balancer handles TLS
vcluster-platform.yaml for ingress TLSingress:
tls:
enabled: true
secret: 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 | base64 -d
Use this output in the
.additionalCA
helm value.vcluster-platform.yaml for pod TLStls:
enabled: true
secret: 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
VERSION
variable 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
vcluster
CLI, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm
, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if different
RELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
helm 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.pem
Create a new Certificate Authority:
Generate CA certificateopenssl req -new -x509 -nodes -days 365000 -key tls.key -out ca.crt
Create a new private key:
Generate private keyopenssl genrsa -out tls.key 4096
Create a file named
ssl.conf
with the following content:ssl.conf[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
req_extensions = v3_req
x509_extensions = usr_cert
[ req_distinguished_name ]
organizationName = Organization Name (for example company)
organizationName_default = vcluster-platform
commonName = Common Name (for example server FQDN or YOUR name)
commonName_default = vcluster-platform.mydomain.tld
[ usr_cert ]
basicConstraints = CA:FALSE
nsCertType = client, server
keyUsage = digitalSignature
extendedKeyUsage = serverAuth, clientAuth
[ v3_req ]
subjectAltName = @alt_names
extendedKeyUsage = serverAuth, clientAuth
basicConstraints = CA:FALSE
keyUsage = digitalSignature
[ alt_names ]
DNS.1 = localhostSet
commonName_default
andDNS.1
to 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 | base64 -d
as an input for the
.additionalCA
helm value.Edit your existing
vcluster-platform.yaml
file, or create a new file namedvcluster-platform.yaml
with the following content:- Platform ingress handles TLS
- Platform pod handles TLS
- Load balancer handles TLS
vcluster-platform.yaml for ingress TLSingress:
tls:
enabled: true
secret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous stepvcluster-platform.yaml for pod TLStls:
enabled: true
secret: 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
VERSION
variable 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
vcluster
CLI, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using vCluster CLIRELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yamlTo upgrade the platform using
helm
, update$PLATFORM_VERSION
with a valid platform version and run:Upgrade the platform using helmRELEASE_NAME=vcluster-platform # Replace with the release name if different
RELEASE_NAMESPACE=vcluster-platform # Replace with the namespace of the platform deployment if different
PLATFORM_VERSION='' # Set this to a specific version or leave empty for latest
helm upgrade $RELEASE_NAME vcluster-platform -n $RELEASE_NAMESPACE --repository-config '' --repo https://charts.loft.sh \
--version $PLATFORM_VERSION \
--reuse-values \
-f vcluster-platform.yaml