blob: fecbbcde2d69bdea0e95a39f6e0fd90a3eeb03da [file] [log] [blame] [view]
Giorgi Lekveishvili725bb392023-05-05 18:24:27 +04001# ingress-nginx
2
3[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer
4
5To use, add the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources.
6
7This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
8
9## Prerequisites
10
11- Kubernetes v1.16+
12
13## Get Repo Info
14
15```console
16helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
17helm repo update
18```
19
20## Install Chart
21
22**Important:** only helm3 is supported
23
24```console
25helm install [RELEASE_NAME] ingress-nginx/ingress-nginx
26```
27
28The command deploys ingress-nginx on the Kubernetes cluster in the default configuration.
29
30_See [configuration](#configuration) below._
31
32_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._
33
34## Uninstall Chart
35
36```console
37helm uninstall [RELEASE_NAME]
38```
39
40This removes all the Kubernetes components associated with the chart and deletes the release.
41
42_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._
43
44## Upgrading Chart
45
46```console
47helm upgrade [RELEASE_NAME] [CHART] --install
48```
49
50_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._
51
52### Upgrading With Zero Downtime in Production
53
54By default the ingress-nginx controller has service interruptions whenever it's pods are restarted or redeployed. In order to fix that, see the excellent blog post by Lindsay Landry from Codecademy: [Kubernetes: Nginx and Zero Downtime in Production](https://medium.com/codecademy-engineering/kubernetes-nginx-and-zero-downtime-in-production-2c910c6a5ed8).
55
56### Migrating from stable/nginx-ingress
57
58There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart:
59
601. For Nginx Ingress controllers used for non-critical services, the easiest method is to [uninstall](#uninstall-chart) the old release and [install](#install-chart) the new one
611. For critical services in production that require zero-downtime, you will want to:
62 1. [Install](#install-chart) a second Ingress controller
63 1. Redirect your DNS traffic from the old controller to the new controller
64 1. Log traffic from both controllers during this changeover
65 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it
66 1. For details on all of these steps see [Upgrading With Zero Downtime in Production](#upgrading-with-zero-downtime-in-production)
67
68Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts.
69
70## Configuration
71
72See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands:
73
74```console
75helm show values ingress-nginx/ingress-nginx
76```
77
78### PodDisruptionBudget
79
80Note that the PodDisruptionBudget resource will only be defined if the replicaCount is greater than one,
81else it would make it impossible to evacuate a node. See [gh issue #7127](https://github.com/helm/charts/issues/7127) for more info.
82
83### Prometheus Metrics
84
85The Nginx ingress controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`.
86
87You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`.
88Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`)
89
90### ingress-nginx nginx\_status page/stats server
91
92Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in nginx ingress controller:
93
94- In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed
95- In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost.
96 You can use `curl --unix-socket /tmp/nginx-status-server.sock http://localhost/nginx_status` inside the controller container to access it locally, or use the snippet from [nginx-ingress changelog](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230) to re-enable the http server
97
98### ExternalDNS Service Configuration
99
100Add an [ExternalDNS](https://github.com/kubernetes-incubator/external-dns) annotation to the LoadBalancer service:
101
102```yaml
103controller:
104 service:
105 annotations:
106 external-dns.alpha.kubernetes.io/hostname: kubernetes-example.com.
107```
108
109### AWS L7 ELB with SSL Termination
110
111Annotate the controller as shown in the [nginx-ingress l7 patch](https://github.com/kubernetes/ingress-nginx/blob/main/deploy/aws/l7/service-l7.yaml):
112
113```yaml
114controller:
115 service:
116 targetPorts:
117 http: http
118 https: http
119 annotations:
120 service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:XX-XXXX-X:XXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX
121 service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
122 service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
123 service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600'
124```
125
126### AWS route53-mapper
127
128To configure the LoadBalancer service with the [route53-mapper addon](https://github.com/kubernetes/kops/tree/master/addons/route53-mapper), add the `domainName` annotation and `dns` label:
129
130```yaml
131controller:
132 service:
133 labels:
134 dns: "route53"
135 annotations:
136 domainName: "kubernetes-example.com"
137```
138
139### Additional Internal Load Balancer
140
141This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application.
142
143By default, the ingress object will point to the external load balancer address, but if correctly configured, you can make use of the internal one if the URL you are looking up resolves to the internal load balancer's URL.
144
145You'll need to set both the following values:
146
147`controller.service.internal.enabled`
148`controller.service.internal.annotations`
149
150If one of them is missing the internal load balancer will not be deployed. Example you may have `controller.service.internal.enabled=true` but no annotations set, in this case no action will be taken.
151
152`controller.service.internal.annotations` varies with the cloud service you're using.
153
154Example for AWS:
155
156```yaml
157controller:
158 service:
159 internal:
160 enabled: true
161 annotations:
162 # Create internal ELB
163 service.beta.kubernetes.io/aws-load-balancer-internal: "true"
164 # Any other annotation can be declared here.
165```
166
167Example for GCE:
168
169```yaml
170controller:
171 service:
172 internal:
173 enabled: true
174 annotations:
175 # Create internal LB. More informations: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing
176 # For GKE versions 1.17 and later
177 networking.gke.io/load-balancer-type: "Internal"
178 # For earlier versions
179 # cloud.google.com/load-balancer-type: "Internal"
180
181 # Any other annotation can be declared here.
182```
183
184Example for Azure:
185
186```yaml
187controller:
188 service:
189 annotations:
190 # Create internal LB
191 service.beta.kubernetes.io/azure-load-balancer-internal: "true"
192 # Any other annotation can be declared here.
193```
194
195Example for Oracle Cloud Infrastructure:
196
197```yaml
198controller:
199 service:
200 annotations:
201 # Create internal LB
202 service.beta.kubernetes.io/oci-load-balancer-internal: "true"
203 # Any other annotation can be declared here.
204```
205
206An use case for this scenario is having a split-view DNS setup where the public zone CNAME records point to the external balancer URL while the private zone CNAME records point to the internal balancer URL. This way, you only need one ingress kubernetes object.
207
208Optionally you can set `controller.service.loadBalancerIP` if you need a static IP for the resulting `LoadBalancer`.
209
210### Ingress Admission Webhooks
211
212With nginx-ingress-controller version 0.25+, the nginx ingress controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster.
213**This feature is enabled by default since 0.31.0.**
214
215With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521)
216
217### Helm Error When Upgrading: spec.clusterIP: Invalid value: ""
218
219If you are upgrading this chart from a version between 0.31.0 and 1.2.2 then you may get an error like this:
220
221```console
222Error: UPGRADE FAILED: Service "?????-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable
223```
224
225Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13646) but to resolve this you can set `xxxx.service.omitClusterIP` to `true` where `xxxx` is the service referenced in the error.
226
227As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered.