Ingress tutorials
Load balance FastCGI applications
Implementing FastCGI with HAProxy Kubernetes Ingress Controller Jump to heading
This tutorial will walk you through configuring the HAProxy Kubernetes Ingress Controller to enable direct communication using the FastCGI protocol with PHP-FPM applications deployed in Kubernetes. You will also deploy and configure a test application to demonstrate how HAProxy can integrate with PHP applications by routing requests to the appropriate PHP test programs acting as backend microservices.
HAProxy supports the FastCGI protocol. When you use a web server, such as Apache, that can translate HTTP requests to FastCGI requests, you can instead use HAProxy. You can configure HAProxy to handle routing and translating requests to PHP applications. There is no need for additional web servers, therefore removing unnecessary hops. Although the HAProxy Kubernetes Ingress Controller doesn’t natively support FastCGI, you can enable the underlying HAProxy load balancer to use FastCGI by incorporating custom configurations. There are plans for the HAProxy Kubernetes Ingress Controller to support the protocol natively in the future.
Configure the HAProxy Kubernetes Ingress Controller for FastCGI Jump to heading
To configure the HAProxy Kubernetes Ingress Controller for the demo application, you must declare an fcgi-app in your HAProxy configuration, along with a few PHP-related configuration directives, and you must also declare Ingress definitions for the PHP microservices. The following steps show how to use an auxiliary HAProxy configuration in combination with an Ingress definition to define and configure the ingress controller for FastCGI.
Create the ConfigMap for the auxiliary configuration Jump to heading
To enable communication between the ingress controller and FastCGI applications, you must add additional directives to your HAProxy configuration. While you can’t add this configuration block using an Ingress resource annotation, you can instead use an auxiliary config file. The ingress controller manages the main HAProxy configuration, and editing or adding to the configuration requires an auxiliary configuration file. To make the ingress controller and its underlying load balancer aware of this auxiliary config, create this file in the container using a ConfigMap.
To create the ConfigMap in your cluster:
-
Create a file named
haproxy-aux.yaml
and add the following to it:haproxy-aux.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: haproxy-auxiliary-configmapnamespace: haproxy-controllerdata:haproxy-auxiliary.cfg: |fcgi-app php-fpmlog-stderr globaldocroot /var/www/htmlpath-info ^(/.+\.php)(/.*)?$haproxy-aux.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: haproxy-auxiliary-configmapnamespace: haproxy-controllerdata:haproxy-auxiliary.cfg: |fcgi-app php-fpmlog-stderr globaldocroot /var/www/htmlpath-info ^(/.+\.php)(/.*)?$This will create a file in the ingress controller’s container named
haproxy-auxiliary.cfg
. Here, you are specifying the following:- An
fcgi-app
namedphp-fpm
. - Log
STDERR
messages received by the FastCGI application. - The
docroot
, the location of the PHP scripts on the PHP-FPM pods, is located at/var/www/html
. In subsequent steps for the test application, the PHP-FPM image you will use expects scripts to be located in this directory. - A regular expression for extracting the name of the appropriate script from the URL with
path-info
.
When HAProxy starts, it will load these additional configuration directives from the file.
- An
-
Apply the ConfigMap. You should create it in the
haproxy-controller
namespace. The HAProxy Ingress Controller should also be deployed in this namespace.nixkubectl apply -f haproxy-aux.yaml -n haproxy-controllernixkubectl apply -f haproxy-aux.yaml -n haproxy-controlleroutputtextconfigmap/haproxy-aux createdoutputtextconfigmap/haproxy-aux created
Next, you will mount the data
from the haproxy-aux.yaml
file into the container as /usr/local/etc/haproxy/haproxy-aux.cfg
.
Mount the ConfigMap in the ingress controller container Jump to heading
Once the ConfigMap exists within your cluster, you must mount it as a file in the container. Mounting the file at /usr/local/etc/haproxy/haproxy-aux.cfg
will make the HAProxy Ingress Controller inject the contents of the file into its main configuration. When the ingress controller is installed with Helm, you can mount this file using the extraVolumes
and extraVolumeMounts
properties of the Helm values file.
To mount the auxiliary configuration file:
-
Create a file named
values.yaml
and add the following to it:values.yamlyamlcontroller:volumeMounts:- name: haproxy-auxiliary-volumeconfigMap:name: haproxy-auxiliary-configmapextraVolumeMounts:- name: haproxy-auxiliary-volumemountPath: /usr/local/etc/haproxy/haproxy-aux.cfgsubPath: haproxy-auxiliary.cfgvalues.yamlyamlcontroller:volumeMounts:- name: haproxy-auxiliary-volumeconfigMap:name: haproxy-auxiliary-configmapextraVolumeMounts:- name: haproxy-auxiliary-volumemountPath: /usr/local/etc/haproxy/haproxy-aux.cfgsubPath: haproxy-auxiliary.cfg -
Perform a Helm upgrade using the values file. This will reconfigure the ingress controller with the properties specified in the values file:
nixhelm upgrade -f values.yaml haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \--create-namespace \--namespace haproxy-controllernixhelm upgrade -f values.yaml haproxy-kubernetes-ingress haproxytech/kubernetes-ingress \--create-namespace \--namespace haproxy-controlleroutputtextNAME: haproxy-kubernetes-ingressLAST DEPLOYED: Wed Jul 24 19:27:16 2024NAMESPACE: haproxy-controllerSTATUS: deployed[...]outputtextNAME: haproxy-kubernetes-ingressLAST DEPLOYED: Wed Jul 24 19:27:16 2024NAMESPACE: haproxy-controllerSTATUS: deployed[...]
The HAProxy Kubernetes Ingress Controller is now deployed and is aware of its auxiliary configuration. You can see this in the ingress controller logs using the kubectl logs
command with the name of the haproxy-kubernetes-ingress
pod:
nix
kubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller
nix
kubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller
outputtext
2024/07/26 20:23:24 INFO controller/monitor.go:118 restart required : auxiliary configuration file created2024/07/26 20:23:24 INFO controller/monitor.go:122 Auxiliary HAProxy config '/etc/haproxy/haproxy-aux.cfg' updated
outputtext
2024/07/26 20:23:24 INFO controller/monitor.go:118 restart required : auxiliary configuration file created2024/07/26 20:23:24 INFO controller/monitor.go:122 Auxiliary HAProxy config '/etc/haproxy/haproxy-aux.cfg' updated
Tip
You can find the name of your haproxy-kubernetes-ingress
pods using the command kubectl get pods -n haproxy-controller
.
Create ingress definitions for the test PHP microservices Jump to heading
To route HTTP requests to the Services for the PHP microservices, you must add an Ingress definition.
Info
You will create the Services for the PHP microservices in subsequent steps.
To create the Ingress definition:
-
Create a file named
ingress.yaml
and add the following to it:ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: myapp-ingressannotations:haproxy.org/path-rewrite: (\/plants\/|\/grocery\/)(.*) /\2spec:ingressClassName: haproxyrules:- host: "yourdomain.com"http:paths:- path: /grocery/pathType: Prefixbackend:service:name: grocery-serviceport:number: 9000- path: /plants/pathType: Prefixbackend:service:name: plants-serviceport:number: 9000ingress.yamlyamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata:name: myapp-ingressannotations:haproxy.org/path-rewrite: (\/plants\/|\/grocery\/)(.*) /\2spec:ingressClassName: haproxyrules:- host: "yourdomain.com"http:paths:- path: /grocery/pathType: Prefixbackend:service:name: grocery-serviceport:number: 9000- path: /plants/pathType: Prefixbackend:service:name: plants-serviceport:number: 9000Here, you define the following:
- An Ingress resource in the default namespace named
myapp-ingress
. - The host as
yourdomain.com
for this demo application. Be sure to replace this with the domain name for your application! - Requests to this host will be routed to the appropriate Service on port 9000 based on the URL path. In this example, there are two Services:
grocery-service
andplants-service
. You will define and create these Services in subsequent steps. - A
path-rewrite
annotation that will strip away part of the URL before sending the requests to the Services. Your PHP microservices will expect to receive a URL with the name of the PHP file only, and these annotations accomplish this, effectively turning/grocery/grocery.php
into justgrocery.php
, for example.
- An Ingress resource in the default namespace named
-
Create the Ingress resource using
kubectl apply
.nixkubectl apply -f ingress.yamlnixkubectl apply -f ingress.yamloutputtextingress.networking.k8s.io/example-ingress createdoutputtextingress.networking.k8s.io/example-ingress createdCreate this in the default namespace, as this is where you will deploy the application Services and Deployments.
This configures the ingress controller for FastCGI. Next, you will create the Services for the PHP microservices and deploy a test application.
Deploy a test PHP FastCGI application Jump to heading
For your typical productionized application, you would create Kubernetes Deployments that would manage one or more pods (depending on the number of replicas) containing your application code and a FastCGI runtime. For this test example, you will deploy containers with php-fpm built in using the php:8-fpm image and mount .php
code files into them at /www/var/html
. This is the default location this image expects to find .php
files. For the test application, you will deploy two containers, each acting as a separate microservice, to which the ingress controller will route requests based on paths.
If you have ready a containerized PHP application for your Kubernetes cluster, you could use it for testing in place of this demo application; just be sure that your auxiliary configuration you defined earlier includes the correct location for your PHP application. This is the docroot
directive in the HAProxy auxiliary configuration. Also, per the configuration you deployed earlier, HAProxy expects your FastCGI application to be listening on port 9000. This port is configurable in your Service and Ingress settings.
To create the test PHP microservices, you will create ConfigMaps. These ConfigMaps will contain test code that you will then mount into the PHP-FPM containers at /www/var/html
. The PHP-FPM process will be able to see these files and serve them upon request.
For testing only
Note that this method of deploying a PHP FastCGI application, that is, mounting PHP code via ConfigMaps, is for testing only and shouldn’t be used for production; its purpose is for simplicity, brevity, and ease of deployment within this tutorial. For your production deployment, you would have a containerized PHP application that includes your runtime and application code.
Also, the contents of the ConfigMap you will define are executable PHP code. As always, be sure to review any code and ensure that you are comfortable with executing it in your environment before you deploy. See the next steps for an explanation of this test code.
Create a ConfigMap to mount test PHP microservices code Jump to heading
To create the ConfigMap:
-
Create a file named
scripts.yaml
and copy the following into it.scripts.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: grocery-scriptdata:grocery.php: |<?php$jsonData = array('bananas' => 3,'bread' => 2,'bacon' => 1);header('Content-Type: application/json');echo json_encode($jsonData);?>---apiVersion: v1kind: ConfigMapmetadata:name: plants-scriptdata:plants.php: |<?php$jsonData = array('tree' => 'oak','flower' => 'rose','vegetable' => 'carrot');header('Content-Type: application/json');echo json_encode($jsonData);?>scripts.yamlyamlapiVersion: v1kind: ConfigMapmetadata:name: grocery-scriptdata:grocery.php: |<?php$jsonData = array('bananas' => 3,'bread' => 2,'bacon' => 1);header('Content-Type: application/json');echo json_encode($jsonData);?>---apiVersion: v1kind: ConfigMapmetadata:name: plants-scriptdata:plants.php: |<?php$jsonData = array('tree' => 'oak','flower' => 'rose','vegetable' => 'carrot');header('Content-Type: application/json');echo json_encode($jsonData);?>This file has two ConfigMaps, each containing one PHP file. These PHP files are two scripts that execute PHP code and return results as JSON. The first script,
grocery.php
, will return a listing and quantity for a grocery shopping list. The second script,plants.php
, will return a JSON mapping of some plants, perhaps a secondary shopping list. You will query for these files in subsequent steps to verify your configuration. -
Create the ConfigMap in the default namespace:
nixkubectl apply -f scripts.yamlnixkubectl apply -f scripts.yamloutputtextconfigmap/grocery-script createdconfigmap/plants-script createdoutputtextconfigmap/grocery-script createdconfigmap/plants-script created
Create Deployments for the test PHP microservices Jump to heading
To create Deployments for the PHP microservices:
-
Create a file named
deployments.yaml
and add the following to it:deployments.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: grocery-deploymentlabels:app: groceryspec:replicas: 1selector:matchLabels:app: grocerytemplate:metadata:labels:app: groceryspec:containers:- name: groceryimage: php:8-fpmvolumeMounts:- name: grocery-scriptmountPath: /var/www/htmlvolumes:- name: grocery-scriptconfigMap:name: grocery-script---apiVersion: apps/v1kind: Deploymentmetadata:name: plants-deploymentlabels:app: plantsspec:replicas: 1selector:matchLabels:app: plantstemplate:metadata:labels:app: plantsspec:containers:- name: plantsimage: php:8-fpmvolumeMounts:- name: plants-scriptmountPath: /var/www/htmlvolumes:- name: plants-scriptconfigMap:name: plants-scriptdeployments.yamlyamlapiVersion: apps/v1kind: Deploymentmetadata:name: grocery-deploymentlabels:app: groceryspec:replicas: 1selector:matchLabels:app: grocerytemplate:metadata:labels:app: groceryspec:containers:- name: groceryimage: php:8-fpmvolumeMounts:- name: grocery-scriptmountPath: /var/www/htmlvolumes:- name: grocery-scriptconfigMap:name: grocery-script---apiVersion: apps/v1kind: Deploymentmetadata:name: plants-deploymentlabels:app: plantsspec:replicas: 1selector:matchLabels:app: plantstemplate:metadata:labels:app: plantsspec:containers:- name: plantsimage: php:8-fpmvolumeMounts:- name: plants-scriptmountPath: /var/www/htmlvolumes:- name: plants-scriptconfigMap:name: plants-scriptThis defines:
- A Deployment named
grocery-deployment
and a Deployment namedplants-deployment
will each run in their own containers that use thephp:8-fpm
image. This image, by default, expects.php
files to reside at/var/www/html
. - A
volumeMount
of thegrocery-script
volume, also defined in this file, to mount the contents of thegrocery-script
ConfigMap that you specified earlier into the container at/var/www/html
in thegrocery
container. PHP-FPM will look for php files at this location. The same applies to theplants-script
volume in theplants
container.
- A Deployment named
-
Create the Deployments in the default namespace:
nixkubectl apply -f deployments.yamlnixkubectl apply -f deployments.yamloutputtextdeployment.apps/grocery-deployment createddeployment.apps/plants-deployment createdoutputtextdeployment.apps/grocery-deployment createddeployment.apps/plants-deployment created
Create Services for the PHP microservices Jump to heading
You need two services to communicate with the microservice pods. Though you didn’t define the Services in previous steps, you configured the ingress controller to communicate with the microservices through two Services on port 9000: grocery-service
and plants-service
. These two services correspond to the Deployments of the same names. You will now define and create these Services.
In order for the ingress controller to apply the appropriate configuration to the backends that will service the PHP microservices, you need to add the following annotation to each of the Service definitions:
yaml
haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpm
yaml
haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpm
This informs the ingress controller, which will in turn configure the load balancer, that the backends associated with these Services will use the fcgi-app
you defined earlier in the HAProxy auxiliary configuration named php-fpm
. The directive default-server proto fcgi
will apply those options to all servers defined in the backends, thus enabling FastCGI communication between HAProxy and the PHP-FPM pods.
To create the Services:
-
Create a file named
services.yaml
and add the following to it:services.yamlyamlapiVersion: v1kind: Servicemetadata:name: grocery-serviceannotations:haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpmspec:selector:app: groceryports:- protocol: TCPport: 9000---apiVersion: v1kind: Servicemetadata:name: plants-serviceannotations:haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpmspec:selector:app: plantsports:- protocol: TCPport: 9000services.yamlyamlapiVersion: v1kind: Servicemetadata:name: grocery-serviceannotations:haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpmspec:selector:app: groceryports:- protocol: TCPport: 9000---apiVersion: v1kind: Servicemetadata:name: plants-serviceannotations:haproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpmspec:selector:app: plantsports:- protocol: TCPport: 9000This defines:
- A Service named
grocery-service
will communicate with thegrocery
pods, that is, the pods labeled withapp: grocery
, at port 9000. The ingress controller will use this configuration to configure the backend and its list of servers to communicate with the PHP microservice at port 9000. - A Service named
plants-service
will communicate with theplants
pods, that is, the pods labeled withapp: plants
, at port 9000. The ingress controller will use this configuration to configure the backend and its list of servers to communicate with the PHP microservice at port 9000.
- A Service named
-
Create the Services in the default namespace:
nixk apply -f services.yamlnixk apply -f services.yamloutputtextservice/grocery-service createdservice/plants-service createdoutputtextservice/grocery-service createdservice/plants-service created
Examine the ingress controller logs and configuration Jump to heading
The ingress controller monitors the Services named in the Ingress resource, and when the Services are created, the ingress controller will automatically configure the load balancer.
-
To see in the logs that new backends were added to the configuration, use the
kubectl logs
command and provide the name of yourhaproxy-kubernetes-ingress
pod:nixkubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-s4rkc -n haproxy-controllernixkubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-s4rkc -n haproxy-controlleroutputtext[...]2024/07/29 21:27:32 INFO service/service.go:164 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : Service 'default/grocery-service': new backend 'default_grocery-service_9000'2024/07/29 21:27:32 INFO service/endpoints.go:160 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : [CONFIG] [BACKEND] [SERVER] Server slots in backend 'default_grocery-service_9000' scaled to match available endpoints2024/07/29 21:27:32 INFO service/service.go:164 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : Service 'default/plants-service': new backend 'default_plants-service_9000'[...]outputtext[...]2024/07/29 21:27:32 INFO service/service.go:164 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : Service 'default/grocery-service': new backend 'default_grocery-service_9000'2024/07/29 21:27:32 INFO service/endpoints.go:160 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : [CONFIG] [BACKEND] [SERVER] Server slots in backend 'default_grocery-service_9000' scaled to match available endpoints2024/07/29 21:27:32 INFO service/service.go:164 [transactionID=9e91f547-e0b7-46e7-805b-b0ded84e5abc] reload required : Service 'default/plants-service': new backend 'default_plants-service_9000'[...] -
To view the load balancer configuration, use the following command and provide the name of your
haproxy-kubernetes-ingress
pod:nixkubectl exec -it haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller -- cat /etc/haproxy/haproxy.cfgnixkubectl exec -it haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller -- cat /etc/haproxy/haproxy.cfg/etc/haproxy/haproxy.cfghaproxy[...]backend default_grocery-service_9000mode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check###_config-snippet_### BEGIN### service:default_grocery-service_9000/default/grocery-service ###default-server proto fcgiuse-fcgi-app php-fpm###_config-snippet_### ENDserver SRV_1 100.44.0.2:9000 enabled[...]backend default_plants-service_9000mode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check###_config-snippet_### BEGIN### service:default_plants-service_9000/default/plants-service ###default-server proto fcgiuse-fcgi-app php-fpm###_config-snippet_### ENDserver SRV_1 100.36.0.1:9000 enabled[...]/etc/haproxy/haproxy.cfghaproxy[...]backend default_grocery-service_9000mode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check###_config-snippet_### BEGIN### service:default_grocery-service_9000/default/grocery-service ###default-server proto fcgiuse-fcgi-app php-fpm###_config-snippet_### ENDserver SRV_1 100.44.0.2:9000 enabled[...]backend default_plants-service_9000mode httpbalance roundrobinoption forwardforno option abortonclosedefault-server check###_config-snippet_### BEGIN### service:default_plants-service_9000/default/plants-service ###default-server proto fcgiuse-fcgi-app php-fpm###_config-snippet_### ENDserver SRV_1 100.36.0.1:9000 enabled[...]
Tip
You can find the name of your haproxy-kubernetes-ingress
pods using the command kubectl get pods -n haproxy-controller
.
Test the configuration Jump to heading
Use curl to test the connection between the configured ingress controller, load balancer, and your deployed PHP microservices.
In the previous steps, you mounted a file into each of the PHP-FPM containers: grocery.php
for the grocery
container and plants.php
for the plants
container. The ingress controller will route requests to the appropriate Service based on the URL path. For example:
-
To reach the
grocery
Service, use the following command, replacingyourdomain.com
with your domain and replacing<NODEPORT>
with the NodePort of your ingress controller. The request will go to thegrocery
Service since the URL path contains/grocery
.Tip
Use the
kubectl get service
command to find the NodePort value. It is the NodePort associated with port 80. In this example, it is30901
:nixkubectl get service -n haproxy-controllernixkubectl get service -n haproxy-controlleroutputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/haproxy-kubernetes-ingress NodePort 10.105.8.178 <none> 80:30901/TCP,443:32033/TCP,443:32033/UDP,1024:30609/TCP,6060:31356/TCP 27houtputtextNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEservice/haproxy-kubernetes-ingress NodePort 10.105.8.178 <none> 80:30901/TCP,443:32033/TCP,443:32033/UDP,1024:30609/TCP,6060:31356/TCP 27hnixcurl http://yourdomain.com:<NODEPORT>/grocery/grocery.phpnixcurl http://yourdomain.com:<NODEPORT>/grocery/grocery.phpoutputjson{"bananas":3,"bread":2,"bacon":1}outputjson{"bananas":3,"bread":2,"bacon":1}Note that the response served is the contents of the script you defined earlier after PHP-FPM has executed the PHP code.
-
To reach the
plants
Service, use the following command, replacingyourdomain.com
with your domain and replacing<NODEPORT>
with the NodePort of your ingress controller.nixcurl http://yourdomain.com:<NODEPORT>/plants/plants.phpnixcurl http://yourdomain.com:<NODEPORT>/plants/plants.phpoutputjson{"tree":"oak","flower":"rose","vegetable":"carrot"}outputjson{"tree":"oak","flower":"rose","vegetable":"carrot"} -
Check the logs for the PHP-FPM pods to see that HAProxy routed the requests to PHP-FPM. This example retrieves the plants container’s logs. The same applies to the grocery container.
nixkubectl logs plants-deployment-7ff8984f5f-l8gv8nixkubectl logs plants-deployment-7ff8984f5f-l8gv8outputtext[30-Jul-2024 14:25:27] NOTICE: fpm is running, pid 1[30-Jul-2024 14:25:27] NOTICE: ready to handle connections100.36.0.2 - 30/Jul/2024:14:30:28 +0000 "GET /plants.php" 200outputtext[30-Jul-2024 14:25:27] NOTICE: fpm is running, pid 1[30-Jul-2024 14:25:27] NOTICE: ready to handle connections100.36.0.2 - 30/Jul/2024:14:30:28 +0000 "GET /plants.php" 200Tip
Find the names of your deployments using the command
kubectl get deployments
.
Conclusion Jump to heading
HAProxy provides an extensive set of routing and load balancing capabilities. The HAProxy Kubernetes Ingress Controller extends HAProxy’s well-known flexibility and customizability to Kubernetes’ ingress configuration, simplifying the migration of applications to Kubernetes, even traditional PHP-based applications, as you saw in this tutorial.
The HAProxy Enterprise Kubernetes Ingress Controller also presents a robust option for those requiring built-in WAF security, enterprise administration, and official support from HAProxy Technologies.
See also Jump to heading
Do you have any suggestions on how we can improve the content of this page?