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.yamland 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-appnamedphp-fpm. - Log
STDERRmessages 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-controllernamespace. 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.yamland 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:
nixkubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller
nixkubectl logs haproxy-kubernetes-ingress-7bc4f66d5c-5c8rt -n haproxy-controller
outputtext2024/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
outputtext2024/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.yamland 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.comfor 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-serviceandplants-service. You will define and create these Services in subsequent steps. - A
path-rewriteannotation 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.phpinto 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.yamland 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.yamland 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-deploymentand a Deployment namedplants-deploymentwill each run in their own containers that use thephp:8-fpmimage. This image, by default, expects.phpfiles to reside at/var/www/html. - A
volumeMountof thegrocery-scriptvolume, also defined in this file, to mount the contents of thegrocery-scriptConfigMap that you specified earlier into the container at/var/www/htmlin thegrocerycontainer. PHP-FPM will look for php files at this location. The same applies to theplants-scriptvolume in theplantscontainer.
- 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:
yamlhaproxy.org/backend-config-snippet: |default-server proto fcgiuse-fcgi-app php-fpm
yamlhaproxy.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.yamland 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-servicewill communicate with thegrocerypods, 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-servicewill communicate with theplantspods, 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 logscommand and provide the name of yourhaproxy-kubernetes-ingresspod: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-ingresspod: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
groceryService, use the following command, replacingyourdomain.comwith your domain and replacing<NODEPORT>with the NodePort of your ingress controller. The request will go to thegroceryService since the URL path contains/grocery.Tip
Use the
kubectl get servicecommand 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
plantsService, use the following command, replacingyourdomain.comwith 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
- For complete information on HAProxy FastCGI applications, see HAProxy FastCGI applications reference.
Do you have any suggestions on how we can improve the content of this page?