Ingress tutorials
Terminate SSL / TLS
In this section, you will learn how to configure SSL/TLS in HAProxy Kubernetes Ingress Controller.
HAProxy Kubernetes Ingress Controller can terminate SSL/TLS for services in your cluster, meaning it will handle encrypting traffic when it leaves the network and decrypting it when it enters. The ingress controller uses a self-signed TLS certificate by default, if you installed with Helm, but you can replace it with your own.
If all of your services reside under the same hostname, you may decide to configure just one TLS certificate. Or, you can set a certificate per Ingress rule. Note that the TLS certificate you use should match your web application’s hostname to be considered valid by web browsers.
Configure a TLS certificate for all services Jump to heading
To add a TLS certificate that applies to all backend services:
-
Acquire a TLS certificate and key. Be sure that your certificate and key files use the PEM format.
Want to try it out in a non-production environment? Use the following OpenSSL command to create your own self-signed certificate and key:
nixopenssl req -x509 -newkey rsa:2048 -keyout example.key -out example.crt -days 365 -nodes -subj "/C=US/ST=Ohio/L=Columbus/O=MyCompany/CN=example.com"nixopenssl req -x509 -newkey rsa:2048 -keyout example.key -out example.crt -days 365 -nodes -subj "/C=US/ST=Ohio/L=Columbus/O=MyCompany/CN=example.com" -
Create a new TLS secret in your cluster by calling
kubectl create secret
with your TLS certificate and private key files as the--cert
and--key
arguments:nixkubectl create secret tls example-cert --cert="example.crt" --key="example.key"nixkubectl create secret tls example-cert --cert="example.crt" --key="example.key" -
To associate this TLS secret with the ingress controller, you must update the ingress controller’s ConfigMap. First, get the name of the ConfigMap by calling
kubectl get configmaps
. Below, the ConfigMap exists in thehaproxy-controller
namespace and is namedhaproxy-kubernetes-ingress
:nixkubectl get configmaps --namespace haproxy-controllernixkubectl get configmaps --namespace haproxy-controlleroutputtextNAME DATA AGEhaproxy-kubernetes-ingress 0 15houtputtextNAME DATA AGEhaproxy-kubernetes-ingress 0 15h -
Replace the ConfigMap with your own. You can either:
-
Call
kubectl edit configmap
to edit the existing ConfigMap:nixkubectl edit configmap --namespace haproxy-controller haproxy-kubernetes-ingressnixkubectl edit configmap --namespace haproxy-controller haproxy-kubernetes-ingressThen add an
ssl-certificate
field to thedata
section. Set it to your TLS secret’s namespace and name.
or
-
Create a YAML file that replaces the ConfigMap. Set the
ssl-certificate
field in thedata
section to your TLS secret’s namespace and name.example-configmap.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: haproxy-kubernetes-ingressnamespace: haproxy-controllerdata:ssl-certificate: "default/example-cert"example-configmap.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: haproxy-kubernetes-ingressnamespace: haproxy-controllerdata:ssl-certificate: "default/example-cert"Then deploy this to your Kubernetes cluster using
kubectl
.nixkubectl apply -f example-configmap.yamlnixkubectl apply -f example-configmap.yaml
The ingress controller will now use your certificate when serving HTTPS traffic.
-
Configure a TLS certificate for an Ingress rule Jump to heading
This section describes how to configure a TLS certificate for a specific Ingress rule, which allows you to set a different certificate for each hostname.
-
Acquire a TLS certificate and key. Be sure that your certificate and key files use the PEM format.
-
Create a new TLS secret in your cluster by calling
kubectl create secret
with your TLS certificate and private key files as the--cert
and--key
arguments.nixkubectl create secret tls example-cert --cert="example.crt" --key="example.key"nixkubectl create secret tls example-cert --cert="example.crt" --key="example.key" -
Prepare an Ingress resource that sets the secret’s name as the
secretName
field’s value in thetls
section. Note that you will specify the hostnames for which this certificate should apply. The hostnames in thetls
section should match the hostnames in therules
section.example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxytls:- secretName: example-certhosts:- "example.com"rules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080example-ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressspec:ingressClassName: haproxytls:- secretName: example-certhosts:- "example.com"rules:- host: "example.com"http:paths:- path: /pathType: Prefixbackend:service:name: example-serviceport:number: 8080Deploy it with
kubectl apply
:nixkubectl apply -f example-ingress.yamlnixkubectl apply -f example-ingress.yamlThe ingress controller will now use your certificate when serving HTTPS traffic for the
example.com
web application.
Configure a TLS certificate for a TCP service Jump to heading
Available since
- HAProxy Kubernetes Ingress Controller 3.0
- HAProxy Enterprise Kubernetes Ingress Controller - not yet available
This section describes how to configure a TLS certificate when using the TCP
custom resource.
-
Acquire a TLS certificate and key. Be sure that your certificate and key files use the PEM format.
-
Create a new TLS secret in your cluster by calling
kubectl create secret
with your TLS certificate and private key files as the--cert
and--key
arguments. Be sure to create the secret in the same namespace where you have your TCP custom resource.nixkubectl create secret tls example-cert --namespace default --cert="example.crt" --key="example.key"nixkubectl create secret tls example-cert --namespace default --cert="example.crt" --key="example.key" -
Create or update your
TCP
custom resource so that it includes thessl
andssl_certificate
fields, wheressl_certificate
indicates the name of your secret.tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: example-service1-tcpspec:- name: example-tcpfrontend:name: example-frontendtcplog: truebinds:- name: bind1port: 2000ssl: truessl_certificate: example-certservice:name: example-service1port: 3000tcp-customresource.yamlyamlapiVersion: ingress.v1.haproxy.org/v1kind: TCPmetadata:name: example-service1-tcpspec:- name: example-tcpfrontend:name: example-frontendtcplog: truebinds:- name: bind1port: 2000ssl: truessl_certificate: example-certservice:name: example-service1port: 3000 -
Apply the changes:
nixkubectl apply -f tcp-customresource.yamlnixkubectl apply -f tcp-customresource.yamloutputtcp.ingress.v1.haproxy.org/example-service1-tcp configured
outputtcp.ingress.v1.haproxy.org/example-service1-tcp configured
Enable verification of a backend service’s TLS certificate Jump to heading
You can use the server-ca
Ingress annotation to specify the certificate authority that the load balancer will use to check backend certificates. To enable verification of a backend service’s TLS certificate:
Generate certificates for testing
You can generate self-signed certificates for testing.
Caution
You should use these self-signed certificates for testing purposes only in a non-production environment.
Use the following openssl
command to generate a CA certificate and key:
nix
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
nix
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
-
Create a Secret of
generic
type, providing the location of your CA certificate (ca.crt
in this example). Here we create a secret in the default namespace namedca-secret
:nixkubectl create secret generic ca-secret --from-file=tls.crt=ca.crtnixkubectl create secret generic ca-secret --from-file=tls.crt=ca.crtoutputtextsecret/ca-secret createdoutputtextsecret/ca-secret createdNote that when creating the secret, you must assign the certificate to the
tls.crt
data field, as the example above shows. -
Add the following annotations to your Ingress definition and apply the changes:
yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/server-ssl: "true"haproxy.org/server-ca: "default/ca-secret"spec:ingressClassName: haproxy[...]yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/server-ssl: "true"haproxy.org/server-ca: "default/ca-secret"spec:ingressClassName: haproxy[...]server-ssl
enables SSL for backend services.server-ca
sets the name of the secret containing the CA certificate that the load balancer will use for verification of backend certificates. Be sure to include the secret’s namespace (default
in this example).
Your load balancer configuration should look similar to following with ca-file
added to the server line:
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 ca-file /etc/haproxy/certs/ca/default_ca-secret.pem verify requiredserver SRV_1 100.36.0.1:8080 enabled
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 ca-file /etc/haproxy/certs/ca/default_ca-secret.pem verify requiredserver SRV_1 100.36.0.1:8080 enabled
Enable client certificate authentication to a backend service Jump to heading
You can use the server-crt
Ingress annotation to specify the client certificate the load balancer should use with backend services. To enable client certificate authentication:
Generate certificates for testing
To test TLS authentication with your backend services, you can generate self-signed certificates.
Caution
You should use these self-signed certificates for testing purposes only in a non-production environment.
Use the following openssl
command to generate a CA certificate:
nix
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
nix
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
You can then use this CA certificate to generate client certificates. For example, we create a client certificate (client.crt
) and key (client.key
) using our CA certificate (ca.crt
):
nix
openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=loadbalancer1'openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
nix
openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=loadbalancer1'openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
-
Create a Secret of
tls
type, providing the location of your client certificate and key. For example, here we create a secret namedserver-secret
:nixkubectl create secret tls server-secret --cert=client.crt --key=client.keynixkubectl create secret tls server-secret --cert=client.crt --key=client.keyoutputtextsecret/server-secret createdoutputtextsecret/server-secret created -
Add the following annotations to your Ingress definition and apply the changes:
yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/server-ssl: "true"haproxy.org/server-crt: "default/server-secret"spec:ingressClassName: haproxy[...]yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: example-ingressannotations:haproxy.org/server-ssl: "true"haproxy.org/server-crt: "default/server-secret"spec:ingressClassName: haproxy[...]server-ssl
enables SSL for backend services.server-crt
sets the name of the secret containing the client certificate and key that the load balancer will use for backend certificates. Be sure to include the secret’s namespace (default
in this example).
Your load balancer configuration should look similar to following with crt
added to the server line:
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 crt /etc/haproxy/certs/backend/default_server-secret.pem verify noneserver SRV_1 100.36.0.1:8080 enabled
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 crt /etc/haproxy/certs/backend/default_server-secret.pem verify noneserver SRV_1 100.36.0.1:8080 enabled
Enable mTLS for a backend service Jump to heading
To enable mTLS (Mutual TLS) for your backend services, you must both enable verification of a backend service’s TLS certificate and enable client certificate authentication to a backend service.
Once you have completed both of those steps, configuring your certificate authority and client certificate, your resulting automatically generated backend load balancer configuration should look similar to the following:
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 ca-file /etc/haproxy/certs/ca/default_ca-secret.pem crt /etc/haproxy/certs/backend/default_server-secret.pem verify requiredserver SRV_1 100.36.0.2:8080 enabled
haproxy
backend default_example-service_httpmode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check ssl alpn h2,http/1.1 ca-file /etc/haproxy/certs/ca/default_ca-secret.pem crt /etc/haproxy/certs/backend/default_server-secret.pem verify requiredserver SRV_1 100.36.0.2:8080 enabled
This enables mTLS between the load balancer and backend services.
Do you have any suggestions on how we can improve the content of this page?