Skip to content

Commit

Permalink
Merge pull request #154 from nginxinc/merge-controllers
Browse files Browse the repository at this point in the history
Merge NGINX and NGINX Plus controllers
  • Loading branch information
pleshakov authored Jul 11, 2017
2 parents 24e4376 + 1b0547d commit 168c0b0
Show file tree
Hide file tree
Showing 32 changed files with 238 additions and 2,375 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# NGINX Ingress Controllers
# NGINX Ingress Controller

This repo provides implementations of an Ingress controller for NGINX and NGINX Plus. These implementations are different from the NGINX Ingress controller in [kubernetes/ingress repo](https://github.com/kubernetes/ingress).
This repo provides an implementation of an Ingress controller for NGINX and NGINX Plus. This implementation is different from the NGINX Ingress controller in [kubernetes/ingress repo](https://github.com/kubernetes/ingress).

## What is Ingress?

Expand All @@ -18,36 +18,36 @@ An Ingress controller is an application that monitors Ingress resources via the

See https://github.com/kubernetes/contrib/tree/master/ingress/controllers/ to learn more about Ingress controllers and find out about different implementations.

## NGINX and NGINX Plus Ingress Controllers
## NGINX Ingress Controller

We provide Ingress controllers for NGINX and NGINX Plus that support the following Ingress features:
We provide an Ingress controller for NGINX and NGINX Plus that supports the following Ingress features:
* SSL termination
* Path-based rules
* Multiple host names

We provide the following extensions to our Ingress controllers:
We provide the following extensions to our Ingress controller:
* [Websocket](examples/websocket), which allows you to load balance Websocket applications.
* [SSL Services](examples/ssl-services), which allows you to load balance HTTPS applications.
* [Rewrites](examples/rewrites), which allows you to rewrite the URI of a request before sending it to the application.
* [Session Persistence](examples/session-persistence) (NGINX Plus only), which guarantees that all the requests from the same client are always passed to the same backend container.

Additionally, we provide a mechanism to customize the NGINX configuration. Refer to the [examples folder](examples) to find out how to [deploy](examples/complete-example) NGINX Ingress controllers and [customize](examples/customization) the NGINX configuration.
Additionally, we provide a mechanism to customize the NGINX configuration. Refer to the [examples folder](examples) to find out how to [deploy](examples/complete-example) the Ingress controller and [customize](examples/customization) the NGINX configuration.

## Difference between NGINX and NGINX Plus Controllers
## Benefits of Using the Ingress Controller with NGINX Plus

[NGINX Plus](https://www.nginx.com/products/) is a commercial version of NGINX that comes with advanced features and support.

Deployment of the NGINX Plus Ingress controller requires you to do one extra step: build your own [Docker image](nginx-plus-controller) using the certificate and key for your subscription.
The Docker image of the NGINX Ingress controller is [available on Docker Hub](https://hub.docker.com/r/nginxdemos/nginx-ingress/).

The NGINX Plus Ingress controller leverages the advanced features of NGINX Plus, which gives you the following additional benefits:
The Ingress controller leverages the advanced features of NGINX Plus, which gives you the following additional benefits:

* **Reduced number of configuration reloads**
Every time the number of pods of services you expose via Ingress changes, the Ingress controller updates the configuration of NGINX to reflect those changes. For the open source NGINX software, the configuration file must be changed and the configuration reloaded. For NGINX Plus, the [on-the-fly reconfiguration](https://www.nginx.com/products/on-the-fly-reconfiguration/) feature is utilized, which allows NGINX Plus to be updated on-the-fly without reloading the configuration. This prevents a potential increase of memory usage and overall system overloading, which could occur with too frequent configuration reloads.
* **Real-time statistics**
NGINX Plus provides you with [advanced statistics](https://www.nginx.com/products/live-activity-monitoring/), which you can access either through the API or via the built-in dashboard. This can give you insights into how NGINX Plus and your applications are performing.
* **Session persistence** When enabled, NGINX Plus makes sure that all the requests from the same client are always passed to the same backend container using the *sticky cookie* method. Refer to the [session persistence examples](examples/session-persistence) to find out how to configure it.

**Note**: Deployment of the Ingress controller for NGINX Plus requires you to do one extra step: build your own [Docker image](nginx-controller) using the certificate and key for your subscription.
The Docker image of the Ingress controller for NGINX is [available on Docker Hub](https://hub.docker.com/r/nginxdemos/nginx-ingress/).

## Using Multiple Ingress Controllers

You can run multiple Ingress controllers at the same time. For example, if your Kubernetes cluster is deployed in cloud, you can run the NGINX controller and the corresponding cloud HTTP load balancing controller. Refer to the [example](examples/multiple-ingress-controllers) to learn more.
Expand All @@ -61,13 +61,13 @@ NGINX Plus comes with a [DNS-based dynamic reconfiguration feature](https://www.

## Production Status

This is the preview version of the Ingress controllers.
This is the preview version of the Ingress controller.

## Support

Support from the [NGINX Professional Services Team](https://www.nginx.com/services/) is available when using the NGINX Plus Ingress controller.

## Contacts

We’d like to hear your feedback! If you have any suggestions or experience issues with our Ingress controllers, please create an issue or send a pull request on Github.
We’d like to hear your feedback! If you have any suggestions or experience issues with our Ingress controller, please create an issue or send a pull request on Github.
You can contact us directly via [kubernetes@nginx.com](mailto:kubernetes@nginx.com).
6 changes: 3 additions & 3 deletions examples/complete-example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

* Kubernetes 1.2 and later (TLS support for Ingress has been added in 1.2)
* For NGINX Plus:
* Build and make available in your cluster the [NGINX Plus](../../nginx-plus-controller) controller image
* Build and make available in your cluster the [Ingress controller](../../nginx-controller) image.
* Update the container image field in the ```nginx-plus-ingress-rc.yaml``` file accordingly.

## Running the Example

## 1. Deploy the Ingress Controller

1. Create either an NGINX or an NGINX Plus Ingress controller:
1. Create an Ingress controller either for NGINX or NGINX Plus:
```
$ kubectl create -f nginx-ingress-rc.yaml
```
Expand Down Expand Up @@ -116,5 +116,5 @@ certificate and the --resolve option to set the Host header of a request with ``
</html>
```

1. If you're using the Plus controller, you can open the live activity monitoring dashboard, which is available at http://XXX.YYY.ZZZ.III:8080/status.html
1. If you're using NGINX Plus, you can open the live activity monitoring dashboard, which is available at http://XXX.YYY.ZZZ.III:8080/status.html
If you go to the Upstream tab, you'll see: ![dashboard](dashboard.png)
3 changes: 2 additions & 1 deletion examples/complete-example/nginx-plus-ingress-rc.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ spec:
hostPort: 8080
# Uncomment the lines below to enable extensive logging and/or customization of
# NGINX configuration with configmaps
#args:
args:
- -nginx-plus
#- -v=3
#- -nginx-configmaps=default/nginx-config
2 changes: 1 addition & 1 deletion examples/customization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The table below summarizes some of the options. More options (extensions) are av
| N/A | `set-real-ip-from` | Sets the value of the [set_real_ip_from](http://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from) directive. | N/A |
| N/A | `real-ip-header` | Sets the value of the [real_ip_header](http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header) directive. | `X-Real-IP`|
| N/A | `real-ip-recursive` | Enables or disables the [real_ip_recursive](http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive) directive. | `False`|
| `nginx.org/server-tokens` | `server-tokens` | Enables or disables the [server_tokens](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) directive. Additionally, with the NGINX Plus controller, you can specify a custom string value. The empty string value disables the emission of the “Server” field. | `True`|
| `nginx.org/server-tokens` | `server-tokens` | Enables or disables the [server_tokens](http://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens) directive. Additionally, with the NGINX Plus, you can specify a custom string value, including the empty string value, which disables the emission of the “Server” field. | `True`|
| N/A | `http-snippets` | Sets a custom snippet in http context. | N/A |
| `nginx.org/location-snippets` | `location-snippets` | Sets a custom snippet in location context. | N/A |
| `nginx.org/server-snippets` | `server-snippets` | Sets a custom snippet in server context. | N/A |
Expand Down
3 changes: 2 additions & 1 deletion examples/daemon-set/nginx-plus-ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ spec:
hostPort: 443
# Uncomment the lines below to enable extensive logging and/or customization of
# NGINX configuration with configmaps
#args:
args:
- -nginx-plus
#- -v=3
#- -nginx-configmaps=default/nginx-config
2 changes: 1 addition & 1 deletion nginx-controller/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ FROM nginx:1.13.0
RUN ln -sf /proc/1/fd/1 /var/log/nginx/access.log \
&& ln -sf /proc/1/fd/2 /var/log/nginx/error.log

COPY nginx-ingress nginx/ingress.tmpl nginx/nginx.conf.tmpl /
COPY nginx-ingress nginx/templates/nginx.ingress.tmpl nginx/templates/nginx.tmpl /

RUN rm /etc/nginx/conf.d/*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ RUN ln -sf /proc/1/fd/1 /var/log/nginx/access.log \
# nginx will store lists of upstream servers in this directory
RUN mkdir -p /var/lib/nginx/state && chown -R nginx:nginx /var/lib/nginx

COPY nginx-plus-ingress nginx/ingress.tmpl nginx/nginx.conf.tmpl /

COPY nginx-ingress nginx/templates/nginx-plus.ingress.tmpl nginx/templates/nginx-plus.tmpl /
RUN rm /etc/nginx/conf.d/*

ENTRYPOINT ["/nginx-plus-ingress"]
ENTRYPOINT ["/nginx-ingress"]
23 changes: 17 additions & 6 deletions nginx-controller/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# NGINX Ingress Controller

This is an implementation of a Kubernetes Ingress controller for NGINX, which provides HTTP load balancing for applications your deploy in your Kubernetes cluster. You can find more details on what an Ingress controller is on the [main page](https://github.com/nginxinc/kubernetes-ingress).
This is an implementation of a Kubernetes Ingress controller for NGINX and NGINX Plus, which provides HTTP load balancing for applications your deploy in your Kubernetes cluster. You can find more details on what an Ingress controller is on the [main page](https://github.com/nginxinc/kubernetes-ingress).

## How to Use the Controller

To find examples on how to deploy, configure and use the NGINX Ingress controller, please see [the examples folder](../examples). The examples require the Docker image of the controller to be available to your Kubernetes cluster. We provide such an image though [DockerHub](https://hub.docker.com/r/nginxdemos/nginx-ingress/).
To find examples on how to deploy, configure and use the Ingress controller, please see [the examples folder](../examples). The examples require the Docker image of the controller to be available to your Kubernetes cluster. We provide such an image though [DockerHub](https://hub.docker.com/r/nginxdemos/nginx-ingress/) for NGINX. If you are using NGINX Plus, you need to build the image.

There are cases when you need to build your own image. For example if you want to customize the controller, either by changing the NGINX configuration templates and/or modifying the controller logic. Please read the next section for instructions on how to build an image.
There are other cases when you need to build your own image. For example if you want to customize the controller, either by changing the NGINX configuration templates and/or modifying the controller logic. Please read the next section for instructions on how to build an image.

## How to Build the Controller Image

Expand All @@ -16,6 +16,8 @@ Before you can build the image, make sure that the following software is install
* [Docker](https://www.docker.com/products/docker)
* [GNU Make](https://www.gnu.org/software/make/)

Additionally, for NGINX Plus, you must have the NGINX Plus license. If you don't have one, you can sign up for a [free 30-day trial](https://www.nginx.com/free-trial-request/). Put the certificate (`nginx-repo.crt`) and the key (`nginx-repo.key`) of your license inside this folder.

### Building the image

We build the image using the make utility. The **Makefile** we provide has the following targets:
Expand All @@ -30,18 +32,27 @@ The **Makefile** contains the following main variables, which you should customi
* **VERSION** -- the current version of the controller.
* **TAG** -- the tag added to the image. It's set to the value of the `VERSION` variable by default.
* **PUSH_TO_GCR**. If you’re running your Kubernetes in GCE and using Google Container Registry, make sure that `PUSH_TO_GCR = 1`. This means using the `gcloud docker push` command to push the image, which is convenient when pushing images to GCR. By default, the variable is unset and the regular `docker push` command is used to push the image to the registry.
* **DOCKERFILE** -- the path to a Dockerfile. We provide two Dockerfiles:
1. `Dockerfile`, for building a debian-based image. It's used by default.
1. `DockerfileForAlpine`, for building an alpine-based image.
* **DOCKERFILE** -- the path to a Dockerfile. We provide three Dockerfiles:
1. `Dockerfile`, for building a debian-based image with NGINX. It's used by default.
1. `DockerfileForAlpine`, for building an alpine-based image with NGINX.
1. `DockerfileForPlus`, for building an ubuntu-based image with NGINX Plus.

Let’s create the controller binary, build an image and push the image to the private registry. Make sure to run the `docker login` command first to login to the registry. If you’re using Google Container Registry, as we are in our example here, you don’t need to use the docker command to login. However, make sure you’re logged into the gcloud tool (using the `gcloud auth login` command).

In this folder we run the following commands in the shell:

For NGINX:
```
$ make clean
$ make PREFIX=gcr.io/my-k8s-project/nginx-ingress TAG=latest PUSH_TO_GCR=1
```

Where **my-k8s-project** is the name of the GCE project where we run our Kubernetes cluster. As the result, the image -- **gcr.io/my-k8s-project/nginx-ingress:latest** -- is built and pushed to the registry.

For NGINX Plus:
```
$ make clean
$ make DOCKERFILE=DockerfileForPlus PREFIX=gcr.io/my-k8s-project/nginx-plus-ingress TAG=latest PUSH_TO_GCR=1
```

By default, to compile the controller we use the [golang](https://hub.docker.com/_/golang/) container that we run as part of the building process. If you want to compile the controller using your local golang environment, specify `BUILD_IN_CONTAINER=0` when you run the make command.
21 changes: 15 additions & 6 deletions nginx-controller/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,18 @@ type LoadBalancerController struct {
stopCh chan struct{}
cnf *nginx.Configurator
watchNginxConfigMaps bool
nginxPlus bool
}

var keyFunc = cache.DeletionHandlingMetaNamespaceKeyFunc

// NewLoadBalancerController creates a controller
func NewLoadBalancerController(kubeClient kubernetes.Interface, resyncPeriod time.Duration, namespace string, cnf *nginx.Configurator, nginxConfigMaps string) (*LoadBalancerController, error) {
func NewLoadBalancerController(kubeClient kubernetes.Interface, resyncPeriod time.Duration, namespace string, cnf *nginx.Configurator, nginxConfigMaps string, nginxPlus bool) (*LoadBalancerController, error) {
lbc := LoadBalancerController{
client: kubeClient,
stopCh: make(chan struct{}),
cnf: cnf,
client: kubeClient,
stopCh: make(chan struct{}),
cnf: cnf,
nginxPlus: nginxPlus,
}

lbc.ingQueue = NewTaskQueue(lbc.syncIng)
Expand Down Expand Up @@ -302,9 +304,16 @@ func (lbc *LoadBalancerController) syncCfgm(key string) {

if serverTokens, exists, err := nginx.GetMapKeyAsBool(cfgm.Data, "server-tokens", cfgm); exists {
if err != nil {
glog.Error(err)
if lbc.nginxPlus {
cfg.ServerTokens = cfgm.Data["server-tokens"]
} else {
glog.Error(err)
}
} else {
cfg.ServerTokens = serverTokens
cfg.ServerTokens = "off"
if serverTokens {
cfg.ServerTokens = "on"
}
}
}

Expand Down
27 changes: 24 additions & 3 deletions nginx-controller/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/nginxinc/kubernetes-ingress/nginx-controller/controller"
"github.com/nginxinc/kubernetes-ingress/nginx-controller/nginx"
"github.com/nginxinc/kubernetes-ingress/nginx-controller/nginx/plus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/pkg/api"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -36,6 +37,9 @@ var (
nginxConfigMaps = flag.String("nginx-configmaps", "",
`Specifies a configmaps resource that can be used to customize NGINX
configuration. The value must follow the following format: <namespace>/<name>`)

nginxPlus = flag.Bool("nginx-plus", false,
`Enables support for NGINX Plus.`)
)

func main() {
Expand Down Expand Up @@ -68,10 +72,27 @@ func main() {
glog.Fatalf("Failed to create client: %v.", err)
}

ngxc, _ := nginx.NewNginxController("/etc/nginx/", *proxyURL != "", *healthStatus)
local := *proxyURL != ""

nginxConfTemplatePath := "nginx.tmpl"
nginxIngressTemplatePath := "nginx.ingress.tmpl"
if *nginxPlus {
nginxConfTemplatePath = "nginx-plus.tmpl"
nginxIngressTemplatePath = "nginx-plus.ingress.tmpl"
}
ngxc, _ := nginx.NewNginxController("/etc/nginx/", local, *healthStatus, nginxConfTemplatePath, nginxIngressTemplatePath)
ngxc.Start()

nginxConfig := nginx.NewDefaultConfig()
cnf := nginx.NewConfigurator(ngxc, nginxConfig)
lbc, _ := controller.NewLoadBalancerController(kubeClient, 30*time.Second, *watchNamespace, cnf, *nginxConfigMaps)
var nginxAPI *plus.NginxAPIController
if *nginxPlus {
nginxAPI, err = plus.NewNginxAPIController("http://127.0.0.1:8080/upstream_conf", "http://127.0.0.1:8080/status", local)
if err != nil {
glog.Fatalf("Failed to create NginxAPIController: %v", err)
}
}
cnf := nginx.NewConfigurator(ngxc, nginxConfig, nginxAPI)

lbc, _ := controller.NewLoadBalancerController(kubeClient, 30*time.Second, *watchNamespace, cnf, *nginxConfigMaps, *nginxPlus)
lbc.Run()
}
4 changes: 2 additions & 2 deletions nginx-controller/nginx/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package nginx
type Config struct {
LocationSnippets []string
ServerSnippets []string
ServerTokens bool
ServerTokens string
ProxyConnectTimeout string
ProxyReadTimeout string
ClientMaxBodySize string
Expand Down Expand Up @@ -40,7 +40,7 @@ type Config struct {
// NewDefaultConfig creates a Config with default values
func NewDefaultConfig() *Config {
return &Config{
ServerTokens: true,
ServerTokens: "on",
ProxyConnectTimeout: "60s",
ProxyReadTimeout: "60s",
ClientMaxBodySize: "1m",
Expand Down
Loading

0 comments on commit 168c0b0

Please sign in to comment.