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 secretwith your TLS certificate and private key files as the--certand--keyarguments: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-controllernamespace 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 configmapto edit the existing ConfigMap:nixkubectl edit configmap --namespace haproxy-controller haproxy-kubernetes-ingressnixkubectl edit configmap --namespace haproxy-controller haproxy-kubernetes-ingressThen add an
ssl-certificatefield to thedatasection. Set it to your TLS secret’s namespace and name.
or
-
Create a YAML file that replaces the ConfigMap. Set the
ssl-certificatefield in thedatasection 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 secretwith your TLS certificate and private key files as the--certand--keyarguments.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
secretNamefield’s value in thetlssection. Note that you will specify the hostnames for which this certificate should apply. The hostnames in thetlssection should match the hostnames in therulessection.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.comweb 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 3.0
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 secretwith your TLS certificate and private key files as the--certand--keyarguments. 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
TCPcustom resource so that it includes thesslandssl_certificatefields, wheressl_certificateindicates 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 configuredoutputtcp.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:
nixopenssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
nixopenssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
-
Create a Secret of
generictype, providing the location of your CA certificate (ca.crtin 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.crtdata 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-sslenables SSL for backend services.server-casets 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 (defaultin this example).
Your load balancer configuration should look similar to following with ca-file added to the server line:
haproxybackend 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
haproxybackend 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:
nixopenssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=loadbalancer1'
nixopenssl 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):
nixopenssl 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
nixopenssl 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
tlstype, 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-sslenables SSL for backend services.server-crtsets 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 (defaultin this example).
Your load balancer configuration should look similar to following with crt added to the server line:
haproxybackend 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
haproxybackend 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:
haproxybackend 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
haproxybackend 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?