Skip to main content

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.

Requirements

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

Heads up.

This section assumes you already have the nginx ingress controller installed, if you don't, check out the 'Manual Ingress Controller Installation' tab.

  1. Run the command:

    vcluster platform start --host=vcluster-platform.mydomain.tld
    Update the Domain.

    Make sure you update the hostname in the above command.

  2. Set the VERSION variable to the platform version you want to upgrade to or set it to the current version using:

    Set VERSION variable
    CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
    VERSION=${CHART:5}
  3. 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 Values

    The $PLATFORM_VERSION variable above is an environment variable set to your desired vCluster Platform version to deploy. The vcluster-platform.yaml file is an optional YAML file that contains Helm values you would like to use when upgrading your vCluster Platform deployment.

  4. 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 10m
    Address

    If 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.

  5. 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 Load Balancers

    If 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: loft
  1. Create the load balancer with this command:

    kubectl apply -f vcluster-platform-loadbalancer.yaml
  2. 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 3m16s
  3. Make 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

  1. 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 \
    --wait
  2. Edit your existing vcluster-platform.yaml file, or create a new file named vcluster-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/directory
  3. Set the VERSION variable to the platform version you want to upgrade to or set it to the current version using:

    Set VERSION variable
    CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
    VERSION=${CHART:5}
  4. 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:

    To upgrade the platform using the vcluster CLI, update $PLATFORM_VERSION with a valid platform version and run:

    Upgrade the platform using vCluster CLI
    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

    vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yaml

AWS Certificate Manager (ACM)

  1. 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
    ^^^^^^^
  2. Find the AWS Elastic Load Balancer(ELB) for this IP address in the AWS console

  3. Switch to the tab Listeners

  4. In the column "SSL Certificates", click on the link View/edit certificates

  5. Click on the + Synbol next to the tab Certificates and add your Access Control Manager (ACM) managed certificate to the ingress controller's Load Balancer

Manually Provisioned Certificate

  1. 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.key
  2. Edit your existing vcluster-platform.yaml file, or create a new file named vcluster-platform.yaml with content:

    ingress:
    tls:
    enabled: true
    secret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous step

    If 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.

  3. Set the VERSION variable to the platform version you want to upgrade to or set it to the current version using:

    Set VERSION variable
    CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
    VERSION=${CHART:5}
  4. 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:

    To upgrade the platform using the vcluster CLI, update $PLATFORM_VERSION with a valid platform version and run:

    Upgrade the platform using vCluster CLI
    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

    vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yaml

Self-Signed Certificate

  1. Create a new private key for Certificate Authority:

        openssl genrsa 2048 >ca-key.pem
  2. Create a new Certificate Authority:

    openssl req -new -x509 -nodes -days 365000 -key tls.key -out ca.crt
  3. Create a new private key:

    openssl genrsa -out tls.key 4096
  4. 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 = localhost

    Please set commonName_default and DNS.1 to the domain you want to use.

  5. Create a certificate signing request:

    openssl req -new -sha256 \
    -out tls.csr \
    -key tls.key \
    -config ssl.conf
  6. Generate 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.pem
  7. 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.key

    If you want to configure vCluster Platform with additionalCA, use

    cat ca.crt | base64 -d

    as an input for .additionalCA helm value.

  8. Edit your existing vcluster-platform.yaml file, or create a new file named vcluster-platform.yaml with content:

    ingress:
    tls:
    enabled: true
    secret: tls-vcluster-platform # Make sure this matches the name of your cert from the previous step
  9. Set the VERSION variable to the platform version you want to upgrade to or set it to the current version using:

    Set VERSION variable
    CHART=$(kubectl get service loft -n vcluster-platform -o jsonpath={.metadata.labels.chart})
    VERSION=${CHART:5}
  10. 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:

    To upgrade the platform using the vcluster CLI, update $PLATFORM_VERSION with a valid platform version and run:

    Upgrade the platform using vCluster CLI
    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

    vcluster platform start --upgrade --version=$PLATFORM_VERSION --namespace=$RELEASE_NAMESPACE --values=vcluster-platform.yaml