Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed fastcgi userguide #11454

Merged
merged 1 commit into from
Jun 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 101 additions & 11 deletions docs/user-guide/fcgi-services.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


# Exposing FastCGI Servers

> **FastCGI** is a [binary protocol](https://en.wikipedia.org/wiki/Binary_protocol "Binary protocol") for interfacing interactive programs with a [web server](https://en.wikipedia.org/wiki/Web_server "Web server"). [...] (It's) aim is to reduce the overhead related to interfacing between web server and CGI programs, allowing a server to handle more web page requests per unit of time.
Expand All @@ -8,10 +6,15 @@

The _ingress-nginx_ ingress controller can be used to directly expose [FastCGI](https://en.wikipedia.org/wiki/FastCGI) servers. Enabling FastCGI in your Ingress only requires setting the _backend-protocol_ annotation to `FCGI`, and with a couple more annotations you can customize the way _ingress-nginx_ handles the communication with your FastCGI _server_.

For most practical use-cases, php applications are a good example. PHP is not HTML so a FastCGI server like php-fpm processes a index.php script for the response to a request. See a working example below.

This [post in a FactCGI feature issue](https://github.com/kubernetes/ingress-nginx/issues/8207#issuecomment-2161405468) describes a test for the FastCGI feature. The same test is described below here.

## Example Objects to expose a FastCGI server pod

## Example Objects to Expose a FastCGI Pod
### The FasctCGI server pod

The _Pod_ example object below exposes port `9000`, which is the conventional FastCGI port.
The _Pod_ object example below exposes port `9000`, which is the conventional FastCGI port.

```yaml
apiVersion: v1
Expand All @@ -23,12 +26,40 @@ labels:
spec:
containers:
- name: example-app
image: example-app:1.0
image: php:fpm-alpine
ports:
- containerPort: 9000
name: fastcgi
```

- For this example to work, a HTML response should be received from the FastCGI server being exposed
- A HTTP request to the FastCGI server pod should be sent
- The response should be generated by a php script as that is what we are demonstrating here

The image we are using here `php:fpm-alpine` does not ship with a ready to use php script inside it. So we need to provide the image with a simple php-script for this example to work.

- Use `kubectl exec` to get into the example-app pod
- You will land at the path `/var/www/html`
- Create a simple php script there at the path /var/www/html called index.php
- Make the index.php file look like this

```
<!DOCTYPE html>
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>FastCGI Test Worked!</p>'; ?>
</body>
</html>
```

- Save and exit from the shell in the pod
- If you delete the pod, then you will have to recreate the file as this method is not persistent

### The FastCGI service

The _Service_ object example below matches port `9000` from the _Pod_ object above.

```yaml
Expand All @@ -45,21 +76,41 @@ spec:
name: fastcgi
```

And the _Ingress_ and _ConfigMap_ objects below demonstrates the supported _FastCGI_ specific annotations (NGINX actually has 50 FastCGI directives, all of which have not been exposed in the ingress yet), and matches the service `example-service`, and the port named `fastcgi` from above. The _ConfigMap_ **must** be created first for the _Ingress Controller_ to be able to find it when the _Ingress_ object is created, otherwise you will need to restart the _Ingress Controller_ pods.
### The configMap object and the ingress object

```yaml
# The ConfigMap MUST be created first for the ingress controller to be able to
# find it when the Ingress object is created.
The _Ingress_ and _ConfigMap_ objects below demonstrate the supported _FastCGI_ specific annotations.

!!! Important
NGINX actually has 50 [FastCGI directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#directives)
All of the nginx directives have not been exposed in the ingress yet

### The ConfigMap object

This configMap object is required to set the parameters of [FastCGI directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#directives)

!!! Attention
- The _ConfigMap_ **must** be created before creating the ingress object

- The _Ingress Controller_ needs to find the configMap when the _Ingress_ object with the FastCGI annotations is created
- So create the configMap before the ingress
- If the configMap is created after the ingress is created, then you will need to restart the _Ingress Controller_ pods.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: example-cm
data:
SCRIPT_FILENAME: "/example/index.php"
SCRIPT_FILENAME: "/var/www/html/index.php"

---
```

### The ingress object

- Do not create the ingress shown below until you have created the configMap seen above.
- You can see that this ingress matches the service `example-service`, and the port named `fastcgi` from above.

```
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
Expand All @@ -83,6 +134,44 @@ spec:
name: fastcgi
```

## Send a request to the exposed FastCGI server

You will have to look at the external-ip of the ingress or you have to send the HTTP request to the ClusterIP address of the ingress-nginx controller pod.

```
% curl 172.19.0.2 -H "Host: app.example.com" -vik
* Trying 172.19.0.2:80...
* Connected to 172.19.0.2 (172.19.0.2) port 80
> GET / HTTP/1.1
> Host: app.example.com
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Wed, 12 Jun 2024 07:11:59 GMT
Date: Wed, 12 Jun 2024 07:11:59 GMT
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive
< X-Powered-By: PHP/8.3.8
X-Powered-By: PHP/8.3.8

<
<!DOCTYPE html>
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<p>FastCGI Test Worked</p> </body>
</html>

```

## FastCGI Ingress Annotations

To enable FastCGI, the `nginx.ingress.kubernetes.io/backend-protocol` annotation needs to be set to `FCGI`, which overrides the default `HTTP` value.
Expand Down Expand Up @@ -114,6 +203,7 @@ data:
SCRIPT_FILENAME: "/example/index.php"
HTTP_PROXY: ""
```

Using the _namespace/_ prefix is also supported, for example:

> `nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-namespace/example-configmap"`