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
LoadBalancer
s. - 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 tolitespeedtech.com/lslbd
- Specify an
Ingress.metadata.annotations.kubernetes.io/ingress.class
which contains the value configured in--ingress-class-controller
which defaults tolitespeedtech.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:
- Ingress spec.ingressClassName (recommended) or
- Ingress metadata.annotations.kubernetes.io/ingress.class
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 192.0.2.0
you would curl (replacing the ALL CAPS section with your definition): curl http://192.0.2.0/testonly/ -H 'Host: example.com'
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://example.com/
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://example.com
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 example.com -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
orcert-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.