forked from kubernetes/ingress-nginx
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FastCGI backend support (kubernetes#2982)
Co-authored-by: Pierrick Charron <pierrick@adoy.net>
- Loading branch information
Showing
22 changed files
with
938 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
|
||
|
||
# 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. | ||
> | ||
> — Wikipedia | ||
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_. | ||
|
||
|
||
## Example Objects to Expose a FastCGI Pod | ||
|
||
The _Pod_ example object below exposes port `9000`, which is the conventional FastCGI port. | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: example-app | ||
labels: | ||
app: example-app | ||
spec: | ||
containers: | ||
- name: example-app | ||
image: example-app:1.0 | ||
ports: | ||
- containerPort: 9000 | ||
name: fastcgi | ||
``` | ||
The _Service_ object example below matches port `9000` from the _Pod_ object above. | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: example-service | ||
spec: | ||
selector: | ||
app: example-app | ||
ports: | ||
- port: 9000 | ||
targetPort: 9000 | ||
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. | ||
|
||
```yaml | ||
# The ConfigMap MUST be created first for the ingress controller to be able to | ||
# find it when the Ingress object is created. | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: example-cm | ||
data: | ||
SCRIPT_FILENAME: "/example/index.php" | ||
--- | ||
apiVersion: extensions/v1beta1 | ||
kind: Ingress | ||
metadata: | ||
annotations: | ||
kubernetes.io/ingress.class: "nginx" | ||
nginx.ingress.kubernetes.io/backend-protocol: "FCGI" | ||
nginx.ingress.kubernetes.io/fastcgi-index: "index.php" | ||
nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-cm" | ||
name: example-app | ||
spec: | ||
rules: | ||
- host: app.example.com | ||
http: | ||
paths: | ||
- backend: | ||
serviceName: example-service | ||
servicePort: fastcgi | ||
``` | ||
|
||
## The FastCGI Ingress Annotations | ||
|
||
### The `nginx.ingress.kubernetes.io/backend-protocol` Annotation | ||
|
||
To enable FastCGI, the `backend-protocol` annotation needs to be set to `FCGI`, which overrides the default `HTTP` value. | ||
|
||
> `nginx.ingress.kubernetes.io/backend-protocol: "FCGI"` | ||
|
||
This enables the _FastCGI_ mode for the whole _Ingress_ object. | ||
|
||
### The `nginx.ingress.kubernetes.io/fastcgi-index` Annotation | ||
|
||
To specify an index file, the `fastcgi-index` annotation value can optionally be set. In the example below, the value is set to `index.php`. This annotation corresponds to [the _NGINX_ `fastcgi_index` directive](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_index). | ||
|
||
> `nginx.ingress.kubernetes.io/fastcgi-index: "index.php"` | ||
|
||
### The `nginx.ingress.kubernetes.io/fastcgi-params-configmap` Annotation | ||
|
||
To specify [_NGINX_ `fastcgi_param` directives](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param), the `fastcgi-params-configmap` annotation is used, which in turn must lead to a _ConfigMap_ object containing the _NGINX_ `fastcgi_param` directives as key/values. | ||
|
||
> `nginx.ingress.kubernetes.io/fastcgi-params: "example-configmap"` | ||
|
||
And the _ConfigMap_ object to specify the `SCRIPT_FILENAME` and `HTTP_PROXY` _NGINX's_ `fastcgi_param` directives will look like the following: | ||
|
||
```yaml | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: example-configmap | ||
data: | ||
SCRIPT_FILENAME: "/example/index.php" | ||
HTTP_PROXY: "" | ||
``` | ||
Using the _namespace/_ prefix is also supported, for example: | ||
|
||
> `nginx.ingress.kubernetes.io/fastcgi-params: "example-namespace/example-configmap"` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
all: all-container | ||
|
||
BUILDTAGS= | ||
|
||
# Use the 0.0 tag for testing, it shouldn't clobber any release builds | ||
TAG?=0.1 | ||
REGISTRY?=kubernetes-ingress-controller | ||
GOOS?=linux | ||
DOCKER?=docker | ||
SED_I?=sed -i | ||
GOHOSTOS ?= $(shell go env GOHOSTOS) | ||
|
||
PKG=k8s.io/ingress-nginx/images/fastcgi-helloserver | ||
|
||
ifeq ($(GOHOSTOS),darwin) | ||
SED_I=sed -i '' | ||
endif | ||
|
||
REPO_INFO=$(shell git config --get remote.origin.url) | ||
|
||
ARCH ?= $(shell go env GOARCH) | ||
GOARCH = ${ARCH} | ||
|
||
BASEIMAGE?=alpine:3.9 | ||
|
||
ALL_ARCH = amd64 arm arm64 ppc64le | ||
|
||
QEMUVERSION=v3.0.0 | ||
|
||
IMGNAME = fastcgi-helloserver | ||
IMAGE = $(REGISTRY)/$(IMGNAME) | ||
MULTI_ARCH_IMG = $(IMAGE)-$(ARCH) | ||
|
||
ifeq ($(ARCH),arm) | ||
QEMUARCH=arm | ||
GOARCH=arm | ||
endif | ||
ifeq ($(ARCH),arm64) | ||
QEMUARCH=aarch64 | ||
endif | ||
ifeq ($(ARCH),ppc64le) | ||
QEMUARCH=ppc64le | ||
GOARCH=ppc64le | ||
endif | ||
|
||
TEMP_DIR := $(shell mktemp -d) | ||
|
||
DOCKERFILE := $(TEMP_DIR)/rootfs/Dockerfile | ||
|
||
sub-container-%: | ||
$(MAKE) ARCH=$* build container | ||
|
||
sub-push-%: | ||
$(MAKE) ARCH=$* push | ||
|
||
all-container: $(addprefix sub-container-,$(ALL_ARCH)) | ||
|
||
all-push: $(addprefix sub-push-,$(ALL_ARCH)) | ||
|
||
container: .container-$(ARCH) | ||
.container-$(ARCH): | ||
cp -r ./* $(TEMP_DIR) | ||
$(SED_I) 's|BASEIMAGE|$(BASEIMAGE)|g' $(DOCKERFILE) | ||
$(SED_I) "s|QEMUARCH|$(QEMUARCH)|g" $(DOCKERFILE) | ||
|
||
ifeq ($(ARCH),amd64) | ||
# When building "normally" for amd64, remove the whole line, it has no part in the amd64 image | ||
$(SED_I) "/CROSS_BUILD_/d" $(DOCKERFILE) | ||
else | ||
# When cross-building, only the placeholder "CROSS_BUILD_" should be removed | ||
# Register /usr/bin/qemu-ARCH-static as the handler for ARM binaries in the kernel | ||
# $(DOCKER) run --rm --privileged multiarch/qemu-user-static:register --reset | ||
curl -sSL https://github.com/multiarch/qemu-user-static/releases/download/$(QEMUVERSION)/x86_64_qemu-$(QEMUARCH)-static.tar.gz | tar -xz -C $(TEMP_DIR)/rootfs | ||
$(SED_I) "s/CROSS_BUILD_//g" $(DOCKERFILE) | ||
endif | ||
|
||
$(DOCKER) build -t $(MULTI_ARCH_IMG):$(TAG) $(TEMP_DIR)/rootfs | ||
|
||
ifeq ($(ARCH), amd64) | ||
# This is for to maintain the backward compatibility | ||
$(DOCKER) tag $(MULTI_ARCH_IMG):$(TAG) $(IMAGE):$(TAG) | ||
endif | ||
|
||
push: .push-$(ARCH) | ||
.push-$(ARCH): | ||
$(DOCKER) push $(MULTI_ARCH_IMG):$(TAG) | ||
ifeq ($(ARCH), amd64) | ||
$(DOCKER) push $(IMAGE):$(TAG) | ||
endif | ||
|
||
clean: | ||
$(DOCKER) rmi -f $(MULTI_ARCH_IMG):$(TAG) || true | ||
|
||
build: clean | ||
CGO_ENABLED=0 GOOS=${GOOS} GOARCH=${GOARCH} go build -a -installsuffix cgo \ | ||
-ldflags "-s -w" \ | ||
-o ${TEMP_DIR}/rootfs/fastcgi-helloserver ${PKG}/... | ||
|
||
release: all-container all-push | ||
echo "done" | ||
|
||
.PHONY: register-qemu | ||
register-qemu: | ||
# Register /usr/bin/qemu-ARCH-static as the handler for binaries in multiple platforms | ||
$(DOCKER) run --rm --privileged multiarch/qemu-user-static:register --reset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"net/http" | ||
"net/http/fcgi" | ||
) | ||
|
||
func hello(w http.ResponseWriter, r *http.Request) { | ||
keys, ok := r.URL.Query()["name"] | ||
|
||
if !ok || len(keys[0]) < 1 { | ||
fmt.Fprintf(w, "Hello world!") | ||
return | ||
} | ||
|
||
key := keys[0] | ||
fmt.Fprintf(w, "Hello "+string(key)+"!") | ||
} | ||
|
||
func main() { | ||
http.HandleFunc("/hello", hello) | ||
|
||
l, err := net.Listen("tcp", "0.0.0.0:9000") | ||
if err != nil { | ||
panic(err) | ||
} | ||
fcgi.Serve(l, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Copyright 2017 The Kubernetes Authors. All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
FROM BASEIMAGE | ||
|
||
CROSS_BUILD_COPY qemu-QEMUARCH-static /usr/bin/ | ||
|
||
COPY . / | ||
|
||
CMD ["/fastcgi-helloserver"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.