Skip to content

Usage Considerations

Some usage notes about the LiteSpeed Ingress Controller:

  • When you install a LiteSpeed Ingress Controller it will immediately behave as a load balancer. Most cloud implementations will assign it an external IP address from which it can be accessed from the outside world. LiteSpeed supports multiple LoadBalancers.
  • Use Kubernetes cert-manager to manage TLS secrets for HTTPS connections. The steps below will help you install cert-manager and specify it in your Ingress definitions.

Multiple Load Balancers

You may want to use multiple load balancers. The advantages of this are:

  • Each LoadBalancer is assigned a separate external IP address by most cloud providers. By having multiple load balancers you can separate traffic.
  • You may wish to separate your definitions by namespace.
  • You may wish to have separate vendor load balancers including cloud-provided load balancers.
  • You wish to separate test from production environments.

When you install the LiteSpeed LoadBalancer by default it will expose to the internet and load balance all Ingress definitions which:

  • Specify an Ingress.spec.ingressClassName which contains the value configured in --ingress-class-controller which defaults to litespeedtech.com/lslbd
  • Specify an Ingress.metadata.annotations.kubernetes.io/ingress.class which contains the value configured in --ingress-class-controller which defaults to litespeedtech.com/lslbd
  • Do not specify either of the above (is the default controller)

The advantage of specifying a specific load balancer is that you'll be able to have multiple load balancers in your environment which may be useful if you need to transition, test or otherwise need multiple load balancers.

Specifying the LiteSpeed Ingress Controller:

To use the LiteSpeed Ingress Controller you must either create an Ingress or modify an existing Ingress and point to the load balancer by either:

Specifying the LiteSpeed Ingress Controller as the default load balancer is not recommended. However the process is discussed here.

Using IngressClass

If your Ingress definitions are in .yaml files, you will have something that looks like this:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ...
spec:
  rules:
  - host: DOMAIN_NAME
...

At the same level as rules if you did not specify an IngressClass definition or modify the default load balancer defined name of lslbd:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ...
spec:
  ingressClassName: lslbd
  rules:
  - host: DOMAIN_NAME
...

You could then apply it using kubectl to take effect immediately.

Using an Annotation

If you already are using an annotation to specify your load balancer, you may choose to use the LiteSpeed Ingress Controller annotation, the default name being litespeedtech.com/lslbd:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    ...
    kubernetes.io/ingress.class: litespeedtech.com/lslbd
...

You could then apply it using kubectl to take effect immediately.

Supported annotations

Besides the ingress.class annotation described above, ingress annotations supported with the controller include rewrite annotations.

Name Description Value Example
ingress.kubernetes.io/app-root Defines the Application Root that the Controller must redirect if it's in / context. string /subdir with a / request will result in a 302 redirecting the request to the same host at /subdir
ingress.kubernetes.io/force-ssl-redirect Forces the redirection to HTTPS even if the Ingress is not TLS Enabled. "true" or "false" Regardless of whether or not there is a SSL secret configured, setting to true will result in all non-https requests returning a 302 Found redirecting to the same host and location using https
ingress.kubernetes.io/rewrite-target Target URI where the traffic must be redirected. string If specified without use-regex can be used for example, to take two paths, say /api/customer/ and /api/customer/ and have them routed to the root by specifying rewrite-target /. If specified with use-regex: "true" you can use numbered groups. For example, if you specify the path /something(/|$)(.*) and rewrite-target: /$2 and the request is for /something/abc it will match the second group and be routed to /abc.
ingress.kubernetes.io/ssl-redirect Indicates if the location section is only accessible via SSL (defaults to true when Ingress contains a Certificate). true or false If there is a SSL secret configured, unless set to false, all non-https requests will result in a 302 Found redirecting to the same host and location using https
ingress.kubernetes.io/use-regex Indicates if the paths defined on an Ingress use regular expressions. true or false If set to true the paths will be examined for regular expressions. For example if the path is set to /foo/\d{5} any requests which are not preceded by /foo/ and 5 numeric digits will be rejected with a 404 Not Found. Any requests which match the requirement will be passed as specified to the backend, unless a rewrite-target is specified.
litespeed.ingress.kubernetes.io/template Specifies a configured, existing Virtual Host Template name. Generally used to add WAF security. string In the documentation, the template comodo is created as an example to demonstrate the feature.

LiteSpeed Ingress Controller as Default

You can make the LiteSpeed Ingress Controller your default Ingress controller; thus if you do not specify an IngressClass or an Annotation (as described above) it will be used. This is not recommended as it precludes the use of other Ingress Controllers.

To do it create an IngressClass (save the below to ingressclass.yaml):

apiVersion: "networking.k8s.io/v1"
kind: "IngressClass"
metadata:
  name: "lslbd"
  annotations:
    ingressclass.kubernetes.io/is-default-class: true
spec:
  controller: "litespeedtech.com/lslbd"

Apply it:

kubectl apply -f ingressclass.yaml

Any future ingress definitions without spec.ingressClassName or metadata.annotions.kubernetes.io/ingress.class will be managed by the LiteSpeed Ingress Controller

Cert-manager

Using the Kubernetes cert-manager simplifies the creation and updating of certificates to guarantee the continuation of HTTPS availability for each of your Ingress defined backends. In particular it generates and manages the certs and the Kubernetes secrets that are used by Ingress definitions. It is strongly recommended that it be used when possible.

The following instructions assume that you use Let’s Encrypt for your certificate renewal. If you're using another service, see the cert-manager instructions which are specific for the type of certificate renewal service you're using.

To use cert-manager it must be installed. If you have already installed it, you can skip this step and proceed to Using Cert-manager.

Install Cert-manager

The easiest way to install cert-manager is with helm:

helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.9.1/cert-manager.crds.yaml
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.9.1

cert-manager has a Kubectl plugin which simplifies some common management tasks. It also lets you check whether cert-manager is up and ready to serve requests.

Install the plugin by downloading its archive and extracting it to the correct directory:

curl -L -o kubectl-cert-manager.tar.gz https://github.com/jetstack/cert-manager/releases/latest/download/kubectl-cert_manager-linux-amd64.tar.gz
tar xzf kubectl-cert-manager.tar.gz
sudo mv kubectl-cert_manager /usr/local/bin

Now use the plugin to check your cert-manager installation is working:

kubectl cert-manager check api

You should see the following output:

The cert-manager API is ready

Now you’re ready to add an issuer to get certificates from Let’s Encrypt.

Creating a ClusterIssuer

A ClusterIssuer definition allows you to create certificates regardless of the namespace and can thus be used for all certificates in the future. Create the following file as issuer.yaml. Replace the ALL CAPS specifications with specifications for your environment.

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-production
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: YOUR EMAIL
    privateKeySecretRef:
      name: letsencrypt-production
    solvers:
      - http01:
          ingress:
            class: litespeedtech.com/lslbd

Once the file is ready, you can apply it:

kubectl apply -f issuer.yaml

When the cert-manager sees an Ingress with an annotation for a defined ClusterIssuer: cert-manager.io/cluster-issuer: letsencrypt-production it will automatically generate a Certificate which is a request for the generation of a certificate. You can see that by entering: kubectl describe certificate which will display details about all of the certificate requests. It will also automatically generate a secret with the name of your DNS in the specified namespace. LiteSpeed will pick it up and use it as soon as it's available.

Using Cert-manager

To use cert-manager with the LiteSpeed Ingress Controller you must:

The combination of the two will result in cert-manager automatically creating and maintaining the certificate and secret that can be used by the LiteSpeed Ingress Controller for HTTPS.

Adding a Cert-manager ClusterIssuer Annotation

Cert-manager will detect Ingresses that have a metadata.annotation.cert-manager.io/cluster-issuer that matches a ClusterIssuer defined in cert-manager, which is created as letsencrypt-production above.

For example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: litespeedtech.com/lslbd
    cert-manager.io/cluster-issuer: letsencrypt-production

Adding a TLS Specification

Also in your Ingress, you will need to add a spec.tls specification that includes your host and a secret name. Replace the ALL CAPS specifications with specifications for your environment:

spec:
  tls:
  - hosts:
    - YOUR DNS NAME
    secretName: YOUR DNS NAME

Testing Cert-manager

The following is a simple Ingress/Service/Deployment definition that you can modify and use to validate exposure and connectivity. It will display the HTTP headers and is thus pretty benign. Note the ALL CAPS sections you should modify with your definitions. In particular note the cert-manager specifics in the Ingress specification.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: litespeedtech.com/lslbd
    cert-manager.io/cluster-issuer: letsencrypt-production
spec:
  rules:
  - host: YOUR DNS NAME
    http:
      paths:
      - pathType: Prefix
        path: "/testonly/"
        backend:
          service:
            name: echo
            port:
              number: 80
  tls:
  - hosts:
    - YOUR DNS NAME
    secretName: YOUR DNS NAME
---
apiVersion: v1
kind: Service
metadata:
  name: echo
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: echo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
spec:
  selector:
    matchLabels:
      app: echo
  replicas: 1
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
      - name: echo
        image: hashicorp/http-echo
        args:
        - "-text=Echo!"
        ports:
        - containerPort: 5678

To apply it you will need to modify and save the file (we recommend echo.yaml) and then enter as the Kubernetes user: kubectl apply -f echo.yaml. You'll know it's accepted by the load balancer if you can curl the IP address of the load balancer. For example if the IP address is 161.35.252.40 you would curl (replacing the ALL CAPS section with your definition): curl http://161.35.252.40/testonly/ -H 'Host: YOUR DNS NAME' and you will see the word Echo!. Note that you must put in the directory /testonly/ or else you will get a 404 Not Found.

You will need to purchase your Web Server's domain name and get it working (with DNS). Each cloud provider has slightly different instructions on how to get a domain name published in their environment. For example, for Digital Ocean, you need to install ExternalDNS and configure it using these instructions. The echo.yaml definition above is from those instructions.

Once you have your DNS name available, you should be able to directly curl to the server using the domain name. For example: curl http://YOUR DNS NAME/ and see the echo headers output you saw above. When the secret is issued, which should not take much time, you should been able to use curl https//YOUR DNS NAME and the same Echo! will be issued.

If you have problems see Troubleshooting Cert-manager below.

Troubleshooting Cert-manager

A Certificate should be issued with YOUR DNS NAME automatically which you should be able to see with kubectl get certificate YOUR DNS NAME -n NAMESPACE and you should see a Status for it which should be Ready.

If you have problems getting the certificate to go to Ready status you can follow the chain of certificate operations using kubectl describe. The sequence of operations is:

  • Certificate
  • CertificateRequest
  • Order
  • Challenge

Thus a kubectl describe Challenge will likely describe the problem at the lowest level, but you may want to follow the entire chain to see what may be wrong.

If no certificate is issued this is often because there is an issue with the Ingress specification. This can include:

  • Missing or incorrect annotations for kubernetes.io/ingress.class or cert-manager.io/cluster-issuer
  • TLS spec is missing the name of the secret

Checking the LiteSpeed Ingress Controller's pod log can be useful in identifying these problems.


Last update: October 20, 2023