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

Revise main documentation page #8019

Merged
merged 1 commit into from
Dec 12, 2021
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
118 changes: 69 additions & 49 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
# Welcome
# Overview

This is the documentation for the NGINX Ingress Controller.

It is built around the [Kubernetes Ingress resource](http://kubernetes.io/docs/user-guide/ingress/), using a [ConfigMap](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#understanding-configmaps-and-pods) to store the NGINX configuration.
It is built around the [Kubernetes Ingress resource](https://kubernetes.io/docs/concepts/services-networking/ingress/), using a [ConfigMap](https://kubernetes.io/docs/concepts/configuration/configmap/) to store the controller configuration.

Learn more about using Ingress on [k8s.io](http://kubernetes.io/docs/user-guide/ingress/).
You can learn more about using [Ingress](http://kubernetes.io/docs/user-guide/ingress/) in the official [Kubernetes documentation](https://docs.k8s.io).

## Getting Started

See [Deployment](./deploy/) for a whirlwind tour that will get you started.


# FAQ - Migration to apiVersion networking.k8s.io/v1
# FAQ - Migration to apiVersion `networking.k8s.io/v1`

- Please read this [official blog on deprecated ingress api versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/) If you are using ingress objects in your pre K8s v1.22 cluster, and you upgrade to K8s v1.22, then this document may be relevant to you.
If you are using Ingress objects in your cluster (running Kubernetes older than v1.22), and you plan to upgrade to Kubernetess v1.22, this section is relevant to you.

- Please read this [official blog on deprecated Ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/)

- Please read this [official documentation on the IngressClass object](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class)

## What is an ingressClass and why is it important for users of Ingress-NGINX controller now ?
## What is an IngressClass and why is it important for users of Ingress-NGINX controller now ?

IngressClass is a Kubernetes resource. See the description below.
Its important because until now, a default install of the Ingress-NGINX controller did not require a ingressClass object. But from version 1.0.0 of the Ingress-NGINX Controller, a ingressclass object is required.
Its important because until now, a default install of the Ingress-NGINX controller did not require any IngressClass object. From version 1.0.0 of the Ingress-NGINX Controller, an IngressClass object is required.

On clusters with more than one instance of the Ingress-NGINX controller, all instances of the controllers must be aware of which Ingress object they must serve. The ingressClass field of a ingress object is the way to let the controller know about that.
On clusters with more than one instance of the Ingress-NGINX controller, all instances of the controllers must be aware of which Ingress objects they serve. The `ingressClassName` field of an Ingress is the way to let the controller know about that.

```
_$ k explain ingressClass
kubectl explain ingressclass
```
```
KIND: IngressClass
VERSION: networking.k8s.io/v1

Expand Down Expand Up @@ -63,23 +67,25 @@ FIELDS:

There are 2 reasons primarily.

(Reason #1) Until K8s version 1.21, it was possible to create a ingress resource, with the "apiVersion:" field set to a value like:
_(Reason #1)_ Until K8s version 1.21, it was possible to create an Ingress resource using deprecated versions of the Ingress API, such as:

- extensions/v1beta1
- networking.k8s.io/v1beta1
- `extensions/v1beta1`
- `networking.k8s.io/v1beta1`

You would get a message about deprecation but the ingress resource would get created.
You would get a message about deprecation, but the Ingress resource would get created.

From K8s version 1.22 onwards, you can ONLY set the "apiVersion:" field of a ingress resource, to the value "networking.k8s.io/v1". The reason is [official blog on deprecated ingress api versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/).
From K8s version 1.22 onwards, you can **only** access the Ingress API via the stable, `networking.k8s.io/v1` API. The reason is explained in the [official blog on deprecated ingress API versions](https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/).

(Reason #2) When you upgrade to K8s version v1.22, while you are already using the Ingress-NGINX controller, there are several scenarios where the old existing ingress objects will not work. Read this FAQ to check which scenario matches your use case.
_(Reason #2)_ if you are already using the Ingress-NGINX controller and then upgrade to K8s version v1.22 , there are several scenarios where your existing Ingress objects will not work how you expect. Read this FAQ to check which scenario matches your use case.

## What is ingressClassName field ?

ingressClassName is a field in the specs of a ingress object.
`ingressClassName` is a field in the specs of an Ingress object.

```shell
kubectl explain ingress.spec.ingressClassName
```
```
% k explain ingress.spec.ingressClassName
KIND: Ingress
VERSION: networking.k8s.io/v1

Expand All @@ -97,25 +103,27 @@ DESCRIPTION:
for this field. For more information, refer to the IngressClass
documentation.
```
the spec.ingressClassName behavior has precedence over the annotation.

The `.spec.ingressClassName` behavior has precedence over the deprecated `kubernetes.io/ingress.class` annotation.


## I have only one instance of the Ingresss-NGINX controller in my cluster. What should I do ?

- If you have only one instance of the Ingress-NGINX controller running in your cluster, and you still want to use ingressclass, you should add the annotation "ingressclass.kubernetes.io/is-default-class" in your ingress class, so any new Ingress objects will have this one as default ingressClass.
## I have only one instance of the Ingress-NGINX controller in my cluster. What should I do ?

In this case, you need to make your Controller aware of the objects. If you have several Ingress objects and they don't yet have the [ingressClassName](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#ingress-v1-networking-k8s-io) field, or the ingress annotation (`kubernetes.io/ingress.class`), then you should start your ingress-controller with the flag [--watch-ingress-without-class=true](## What is the flag '--watch-ingress-without-class' ?) .
- If you have only one instance of the Ingress-NGINX controller running in your cluster, and you still want to use IngressClass, you should add the annotation `ingressclass.kubernetes.io/is-default-class` in your IngressClass, so that any new Ingress objects will have this one as default IngressClass.

You can configure your helm chart installation's values file with `.controller.watchIngressWithoutClass: true`.
In this case, you need to make your controller aware of the objects. If you have any Ingress objects that don't yet have either the [`.spec.ingressClassName`](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec) field set in their manifest, or the ingress annotation (`kubernetes.io/ingress.class`), then you should start your Ingress-NGINX controller with the flag `--watch-ingress-without-class=true`.

We highly recommend that you create the ingressClass as shown below:
You can configure your Helm chart installation's values file with `.controller.watchIngressWithoutClass: true`.

We recommend that you create the IngressClass as shown below:
```
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/component: controller
name: nginx
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
Expand All @@ -124,76 +132,88 @@ spec:
```
And add the value "spec.ingressClassName=nginx" in your Ingress objects

## I have multiple ingress objects in my cluster. What should I do ?
- If you don't care about ingressClass, or you have a lot of ingress objects without ingressClass configuration, you can run the ingress-controller with the flag `--watch-ingress-without-class=true`.
## I have multiple Ingress objects in my cluster. What should I do ?
- If you don't care about ingress classes, or you have a lot of Ingress objects without any IngressClass configuration, you can run the ingress-controller with the flag `--watch-ingress-without-class=true`.

## What is the flag '--watch-ingress-without-class' ?
- Its a flag that is passed,as an argument, to the ingress-controller executable, in the pod spec. It looks like this ;
### What is the flag '--watch-ingress-without-class' ?
- Its a flag that is passed,as an argument, to the `nginx-ingress-controller` executable. In the configuration, it looks like this ;
```
...
...
args:
- /nginx-ingress-controller
- --watch-ingress-without-class=true
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
- --election-id=ingress-controller-leader
- --controller-class=k8s.io/ingress-nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
- --watch-ingress-without-class=true
...
...
```

## I have more than one controller in my cluster and already use the annotation ?

No problem. This should still keep working, but we highly recommend you to test!

## I have more than one controller running in my cluster, and I want to use the new spec ?
In this scenario, you need to create multiple ingressClasses (see example one). But be aware that ingressClass works in a very specific way: you will need to change the .spec.controller value in your IngressClass and point the controller to the relevant ingressClass. Let's see some example, supposing that you have two Ingress Classes:
Even though `kubernetes.io/ingress.class` is deprecated, the Ingress-NGINX controller still understands that annotation.
If you want to follow good practice, you should consider migrating to use IngressClass and `.spec.ingressClassName`.

## I have more than one controller running in my cluster, and I want to use the new API ?

In this scenario, you need to create multiple IngressClasses (see example one). But be aware that IngressClass works in a very specific way: you will need to change the `.spec.controller` value in your IngressClass and configure the controller to expect the exact same value.

- Ingress-Nginx-IngressClass-1 with .spec.controller equals to "k8s.io/ingress-nginx1"
- Ingress-Nginx-IngressClass-2 with .spec.controller equals to "k8s.io/ingress-nginx2"
Let's see some example, supposing that you have three IngressClasses:

- IngressClass `ingress-nginx-one`, with `.spec.controller` equal to `example.com/ingress-nginx1`
- IngressClass `ingress-nginx-two`, with `.spec.controller` equal to `example.com/ingress-nginx2`
- IngressClass `ingress-nginx-three`, with `.spec.controller` equal to `example.com/ingress-nginx1`

(for private use, you can also use a controller name that doesn't contain a `/`; for example: `ingress-nginx1`)

When deploying your ingress controllers, you will have to change the `--controller-class` field as follows:

- Ingress-Nginx-Controller-nginx1 with `k8s.io/ingress-nginx1`
- Ingress-Nginx-Controller-nginx2 with `k8s.io/ingress-nginx2`
- Ingress-Nginx A, configured to use controller class name `example.com/ingress-nginx1`
- Ingress-Nginx B, configured to use controller class name `example.com/ingress-nginx2`

Then, when you create an Ingress object with its `ingressClassName` set to `ingress-nginx-two`, only controllers looking for the `example.com/ingress-nginx2` controller class pay attention to the new object. Given that Ingress-Nginx B is set up that way, it will serve that object, whereas Ingress-Nginx A ignores the new Ingress.

Then, when you create an Ingress Object with IngressClassName = `ingress-nginx2`, it will look for controllers with `controller-class=k8s.io/ingress-nginx2` and as `Ingress-Nginx-Controller-nginx2` is watching objects that points to `ingressClass="k8s.io/ingress-nginx2`, it will serve that object, while `Ingress-Nginx-Controller-nginx1` will ignore the ingress object.
Bear in mind that, if you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true`, then it will serve:

Bear in mind that, if your `Ingress-Nginx-Controller-nginx2` is started with the flag `--watch-ingress-without-class=true`, then it will serve:
1. Ingresses without any `ingressClassName` set
2. Ingresses where the the deprecated annotation (`kubernetes.io/ingress.class`) matches the value set in the command line argument `--ingress-class`
3. Ingresses that refer to any IngressClass that has the same `spec.controller` as configured in `--controller-class`

- objects without ingress-class
- objects with the annotation configured in flag `--ingress-class` and same class value
- and also objects pointing to the ingressClass that have the same .spec.controller as configured in `--controller-class`
If you start Ingress-Nginx B with the command line argument `--watch-ingress-without-class=true` and you run Ingress-Nginx A with the command line argument `--watch-ingress-without-class=false` then this is a supported configuration. If you have two Ingress-NGINX controllers for the same cluster, both running with `--watch-ingress-without-class=true` then there is likely to be a conflict.

## I am seeing this error message in the logs of the Ingress-NGINX controller: "ingress class annotation is not equal to the expected by Ingress Controller". Why ?

## I am seeing this error message in the logs of the Ingress-NGINX controller "ingress class annotation is not equal to the expected by Ingress Controller". Why ?
- It is highly likely that you will also see the name of the ingress resource in the same error message. This error messsage has been observed on use the deprecated annotation, to spec the ingressClass, in a ingress resource manifest. It is recommended to use the ingress.spec.ingressClassName field, of the ingress resource, to spec the name of the ingressClass of the ingress resource being configured.
- It is highly likely that you will also see the name of the ingress resource in the same error message. This error messsage has been observed on use the deprecated annotation (`kubernetes.io/ingress.class`) in a Ingress resource manifest. It is recommended to use the `.spec.ingressClassName` field of the Ingress resource, to specify the name of the IngressClass of the Ingress you are defining.

## How to easily install multiple instances of the ingress-NGINX controller in the same cluster ?
- Create a new namespace
```
kubectl create namespace ingress-nginx-2
```
- Use helm to install the additional instance of the ingress controller
- Ensure you have helm working (refer to helm documentation)
- We have to assume that you have the helm repo for the ingress-NGINX controller already added to your helm config. But, if you have not added the helm repo then you can do this to add the repo to your helm config;
- Use Helm to install the additional instance of the ingress controller
- Ensure you have Helm working (refer to the [Helm documentation](https://helm.sh/docs/))
- We have to assume that you have the helm repo for the ingress-NGINX controller already added to your Helm config. But, if you have not added the helm repo then you can do this to add the repo to your helm config;
```
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
```
- Make sure you have updated the helm repo data;
```
helm repo update
```
- Now you install the additional instance of the ingress-NGINX controller like this ;
- Now, install an additional instance of the ingress-NGINX controller like this ;
```
helm install ingress-nginx-2 ingress-nginx/ingress-nginx \
--namespace ingress-nginx-2 \
--set controller.ingressClassResource.name=nginx-2 \
--set controller.ingressClassResource.controllerValue="k8s.io/ingress-nginx-2" \
--set controller.ingressClassResource.name=nginx-two \
--set controller.ingressClassResource.controllerValue="example.com/ingress-nginx-2" \
strongjz marked this conversation as resolved.
Show resolved Hide resolved
--set controller.ingressClassResource.enabled=true \
--set controller.ingressClassByName=true
```
- If you need to install yet another instance, then repeat the procedure to create a new namespace, change the values like names & namespaces (for example from "-2" to "-3"), or anything else that meets your needs.
- If you need to install yet another instance, then repeat the procedure to create a new namespace, change the values such as names & namespaces (for example from "-2" to "-3"), or anything else that meets your needs.