Configure External Access & TLS
After deploying vCluster Platform, you may want to be able 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 of course extra useful for sharing vCluster Platform access with other members of your team who may or may not have direct access to Kubernetes.
Getting vCluster Platform set up to be accessed via routable IP or domain name, and to be secured via TLS requires the cluster that vCluster Platform is deployed in to have an available load balancer or ingress controller, appropriate DNS settings to be in place, and some mechanism for assigning TLS certificates (that is cert-manager).
External Access
vCluster Platform, like any other service in Kubernetes, can be exposed in a few ways -- in this section
we'll outline how to expose vCluster Platform via an ingress controller (nginx ingress controller in this
example), as well as by 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:
vcluster platform start --host=vcluster-platform.mydomain.tld
Update the Domain.Make sure you update the hostname in the above command.
Set the
VERSION
variable to the vCluster Platform version you want to upgrade to OR set it to the current version using:CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
VERSION=${CHART:5}To upgrade vCluster Platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid vCluster Platform version and run:vcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
Versions and ValuesThe
$PLATFORM_VERSION
variable above is an environment variable set to your desired vCluster 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 vCluster Platform deployment.Determine the External-IP address:
kubectl 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 above, you will 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 vCluster 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:
curl 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 vCluster Platform version.helm 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 vCluster Platform deployment to use the NGINX ingress controller, we can create a simple values file that tells vCluster 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.
ingress:
enabled: true
host: "vcluster-platform.mydomain.tld" # Make sure to change this
ingressClass: "nginx" # Optional, nginx is default value!To upgrade vCluster Platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid vCluster Platform version and run:vcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
Versions and ValuesThe
$PLATFORM_VERSION
variable above is an environment variable set to your desired vCluster 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 vCluster Platform deployment.Determine the External-IP address:
kubectl 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 above, you will 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 vCluster 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:
curl 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.
apiVersion: 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: loftapiVersion: 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:
kubectl apply -f vcluster-platform-loadbalancer.yaml
Wait until the load balancer receives an External-IP address:
kubectl 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 vCluster 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:
curl 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
Cert-Manager
Install
cert-manager
to your cluster:helm 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 content:ingress:
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 vCluster Platform version you want to upgrade to OR set it to the current version using:CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
VERSION=${CHART:5}Upgrade vCluster Platform via:
- CLI
- helm
To upgrade vCluster Platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid vCluster Platform version and run:vcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
To upgrade vCluster Platform via
helm
, update$PLATFORM_VERSION
with a valid vCluster Platform version and run:helm upgrade loft vcluster-platform -n vcluster-platform --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:
kubectl 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 tab
Listeners
In the column "SSL Certificates", click on the link
View/edit certificates
Click on the
+
Synbol next to the tabCertificates
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:
kubectl 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 content:- vCluster Platform Ingress handles TLS
- vCluster Platform Pod handles TLS
- Load Balancer handles TLS
ingress:
tls:
enabled: true
secret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous stepIf you want to configure vCluster Platform with additionalCA, Certificate Authority used for signing this certificate has to be added as a base64 encoded:
cat ca.crt | base64 -d
in
.additionalCA
helm value.tls:
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 vCluster Platform deployment
Set the
VERSION
variable to the vCluster Platform version you want to upgrade to OR set it to the current version using:CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
VERSION=${CHART:5}Upgrade vCluster Platform via:
- CLI
- helm
To upgrade vCluster Platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid vCluster Platform version and run:vcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
To upgrade vCluster Platform via
helm
, update$PLATFORM_VERSION
with a valid vCluster Platform version and run:helm upgrade loft vcluster-platform -n vcluster-platform --repository-config '' --repo https://charts.loft.sh \
--version $PLATFORM_VERSION \
--reuse-values \
-f vcluster-platform.yaml
Self-Signed Certificate
Create a new private key for Certificate Authority:
openssl genrsa 2048 >ca-key.pem
Create a new Certificate Authority:
openssl req -new -x509 -nodes -days 365000 -key tls.key -out ca.crt
Create a new private key:
openssl genrsa -out tls.key 4096
Create a file named
ssl.conf
with the following content:[ 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 = localhostPlease set
commonName_default
andDNS.1
to the domain you want to use.Create a certificate signing request:
openssl req -new -sha256 \
-out tls.csr \
-key tls.key \
-config ssl.confGenerate the certificate:
openssl 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:
kubectl 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 vCluster Platform with additionalCA, use
cat ca.crt | base64 -d
as an input for
.additionalCA
helm value.Edit your existing
vcluster-platform.yaml
file, or create a new file namedvcluster-platform.yaml
with content:- vCluster Platform Ingress handles TLS
- vCluster Platform Pod handles TLS
- Load Balancer handles TLS
ingress:
tls:
enabled: true
secret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous steptls:
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 vCluster Platform deployment
Set the
VERSION
variable to the vCluster Platform version you want to upgrade to OR set it to the current version using:CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
VERSION=${CHART:5}Upgrade vCluster Platform via:
- CLI
- helm
To upgrade vCluster Platform via vCluster CLI, update
$PLATFORM_VERSION
with a valid vCluster Platform version and run:vcluster platform start --upgrade --version=$PLATFORM_VERSION --values=vcluster-platform.yaml
To upgrade vCluster Platform via
helm
, update$PLATFORM_VERSION
with a valid vCluster Platform version and run:helm upgrade loft vcluster-platform -n vcluster-platform --repository-config '' --repo https://charts.loft.sh \
--version $PLATFORM_VERSION \
--reuse-values \
-f vcluster-platform.yaml