</code></pre></div><h2id=what-has-caused-this-change-in-behavior>What has caused this change in behavior?<aclass=headerlinkhref=#what-has-caused-this-change-in-behaviortitle="Permanent link"> ¶</a></h2><p>There are 2 primary reasons.</p><h3id=reason-1>Reason 1<aclass=headerlinkhref=#reason-1title="Permanent link"> ¶</a></h3><p>Until K8s version 1.21, it was possible to create an Ingress resource using deprecated versions of the Ingress API, such as:</p><ul><li><code>extensions/v1beta1</code></li><li><code>networking.k8s.io/v1beta1</code> You would get a message about deprecation, but the Ingress resource would get created.</li></ul><p>From K8s version 1.22 onwards, you can <strong>only</strong> access the Ingress API via the stable, <code>networking.k8s.io/v1</code> API. The reason is explained in the <ahref=https://kubernetes.io/blog/2021/07/26/update-with-ingress-nginx/>official blog on deprecated ingress API versions</a>.</p><h3id=reason-2>Reason #2<aclass=headerlinkhref=#reason-2title="Permanent link"> ¶</a></h3><p>If you are already using the ingress-nginx controller and then upgrade to Kubernetes 1.22, there are several scenarios where your existing Ingress objects will not work how you expect.</p><p>Read this FAQ to check which scenario matches your use case.</p><h2id=what-is-the-ingressclassname-field>What is the <code>ingressClassName</code> field?<aclass=headerlinkhref=#what-is-the-ingressclassname-fieldtitle="Permanent link"> ¶</a></h2><p><code>ingressClassName</code> is a field in the spec of an Ingress object.</p><divclass=highlight><pre><span></span><code>kubectl explain ingress.spec.ingressClassName
<spanclass=go> IngressClassName is the name of the IngressClass cluster resource. The</span>
<spanclass=go> associated IngressClass defines which controller will implement the</span>
<spanclass=go> resource. This replaces the deprecated `kubernetes.io/ingress.class`</span>
<spanclass=go> annotation. For backwards compatibility, when that annotation is set, it</span>
<spanclass=go> must be given precedence over this field. The controller may emit a warning</span>
<spanclass=go> if the field and annotation have different values. Implementations of this</span>
<spanclass=go> API should ignore Ingresses without a class specified. An IngressClass</span>
<spanclass=go> resource may be marked as default, which can be used to set a default value</span>
<spanclass=go> for this field. For more information, refer to the IngressClass</span>
<spanclass=go> documentation.</span>
</code></pre></div><p>The <code>.spec.ingressClassName</code> behavior has precedence over the deprecated <code>kubernetes.io/ingress.class</code> annotation.</p><h2id=i-have-only-one-ingress-controller-in-my-cluster-what-should-i-do>I have only one ingress controller in my cluster. What should I do?<aclass=headerlinkhref=#i-have-only-one-ingress-controller-in-my-cluster-what-should-i-dotitle="Permanent link"> ¶</a></h2><p>If a single instance of the ingress-nginx controller is the sole Ingress controller running in your cluster, you should add the annotation "ingressclass.kubernetes.io/is-default-class" in your IngressClass, so any new Ingress objects will have this one as default IngressClass.</p><p>When using Helm, you can enable this annotation by setting <code>.controller.ingressClassResource.default: true</code> in your Helm chart installation's values file.</p><p>If you have any old Ingress objects remaining without an IngressClass set, you can do one or more of the following to make the ingress-nginx controller aware of the old objects:</p><ul><li>You can manually set the <ahref=https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec><code>.spec.ingressClassName</code></a> field in the manifest of your own Ingress resources.</li><li>You can re-create them after setting the <code>ingressclass.kubernetes.io/is-default-class</code> annotation to <code>true</code> on the IngressClass</li><li>Alternatively you can make the ingress-nginx controller watch Ingress objects without the ingressClassName field set by starting your ingress-nginx with the flag <ahref=#what-is-the-flag-watch-ingress-without-class>--watch-ingress-without-class=true</a>. When using Helm, you can configure your Helm chart installation's values file with <code>.controller.watchIngressWithoutClass: true</code>.</li></ul><p>We recommend that you create the IngressClass as shown below:</p><divclass=highlight><pre><span></span><code>---
</code></pre></div><p>and add the value <code>spec.ingressClassName=nginx</code> in your Ingress objects.</p><h2id=i-have-many-ingress-objects-in-my-cluster-what-should-i-do>I have many ingress objects in my cluster. What should I do?<aclass=headerlinkhref=#i-have-many-ingress-objects-in-my-cluster-what-should-i-dotitle="Permanent link"> ¶</a></h2><p>If you have a lot of ingress objects without ingressClass configuration, you can run the ingress controller with the flag <code>--watch-ingress-without-class=true</code>.</p><h3id=what-is-the-flag-watch-ingress-without-class>What is the flag <code>--watch-ingress-without-class</code>?<aclass=headerlinkhref=#what-is-the-flag-watch-ingress-without-classtitle="Permanent link"> ¶</a></h3><p>It's a flag that is passed, as an argument, to the <code>nginx-ingress-controller</code> executable. In the configuration, it looks like this:</p><divclass=highlight><pre><span></span><code><spanclass=c1># ...</span>
</code></pre></div><h2id=i-have-more-than-one-controller-in-my-cluster-and-im-already-using-the-annotation>I have more than one controller in my cluster, and I'm already using the annotation<aclass=headerlinkhref=#i-have-more-than-one-controller-in-my-cluster-and-im-already-using-the-annotationtitle="Permanent link"> ¶</a></h2><p>No problem. This should still keep working, but we highly recommend you to test! Even though <code>kubernetes.io/ingress.class</code> 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 <code>.spec.ingressClassName</code>.</p><h2id=i-have-more-than-one-controller-running-in-my-cluster-and-i-want-to-use-the-new-api>I have more than one controller running in my cluster, and I want to use the new API<aclass=headerlinkhref=#i-have-more-than-one-controller-running-in-my-cluster-and-i-want-to-use-the-new-apititle="Permanent link"> ¶</a></h2><p>In this scenario, you need to create multiple IngressClasses (see the example above).</p><p>Be aware that IngressClass works in a very specific way: you will need to change the <code>.spec.controller</code> value in your IngressClass and configure the controller to expect the exact same value.</p><p>Let's see an example, supposing that you have three IngressClasses:</p><ul><li>IngressClass <code>ingress-nginx-one</code>, with <code>.spec.controller</code> equal to <code>example.com/ingress-nginx1</code></li><li>IngressClass <code>ingress-nginx-two</code>, with <code>.spec.controller</code> equal to <code>example.com/ingress-nginx2</code></li><li>IngressClass <code>ingress-nginx-three</code>, with <code>.spec.controller</code> equal to <code>example.com/ingress-nginx1</code></li></ul><p>For private use, you can also use a controller name that doesn't contain a <code>/</code>, e.g. <code>ingress-nginx1</code>.</p><p>When deploying your ingress controllers, you will have to change the <code>--controller-class</code> field as follows:</p><ul><li>Ingress-Nginx A, configured to use controller class name <code>example.com/ingress-nginx1</code></li><li>Ingress-Nginx B, configured to use controller class name <code>example.com/ingress-nginx2</code></li></ul><p>When you create an Ingress object with its <code>ingressClassName</code> set to <code>ingress-nginx-two</code>, only controllers looking for the <code>example.com/ingress-nginx2</code> controller class pay attention to the new object.</p><p>Given that Ingress-Nginx B is set up that way, it will serve that object, whereas Ingress-Nginx A ignores the new Ingress.</p><p>Bear in mind that if you start Ingress-Nginx B with the command line argument <code>--watch-ingress-without-class=true</code>, it will serve:</p><ol><li>Ingresses without any <code>ingressClassName</code> set</li><li>Ingresses where the deprecated annotation (<code>kubernetes.io/ingress.class</code>) matches the value set in the command line argument <code>--ingress-class</code></li><li>Ingresses that refer to any IngressClass that has the same <code>spec.controller</code> as configured in <code>--controller-class</code></li><li>If you start Ingress-Nginx B with the command line argument <code>--watch-ingress-without-class=true</code> and you run Ingress-Nginx A with the command line argument <code>--watch-ingress-without-class=false</code> then this is a supported configuration. If you have two ingress-nginx controllers for the same cluster, both running with <code>--watch-ingress-without-class=true</code> then there is likely to be a conflict.</li></ol><h2id=why-am-i-seeing-ingress-class-annotation-is-not-equal-to-the-expected-by-ingress-controller-in-my-controller-logs>Why am I seeing "ingress class annotation is not equal to the expected by Ingress Controller" in my controller logs?<aclass=headerlinkhref=#why-am-i-seeing-ingress-class-annotation-is-not-equal-to-the-expected-by-ingress-controller-in-my-controller-logstitle="Permanent link"> ¶</a></h2><p>It is highly likely that you will als
</code></pre></div></li><li>Use Helm to install the additional instance of the ingress controller</li><li>Ensure you have Helm working (refer to the <ahref=https://helm.sh/docs/>Helm documentation</a>)</li><li>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; <divclass=highlight><pre><span></span><code>helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
</code></pre></div></li><li>Make sure you have updated the helm repo data; <divclass=highlight><pre><span></span><code>helm repo update
</code></pre></div></li><li>Now, install an additional instance of the ingress-nginx controller like this: <divclass=highlight><pre><span></span><code>helm install ingress-nginx-2 ingress-nginx/ingress-nginx \
</code></pre></div></li></ul><p>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.</p><p>Note that <code>controller.ingressClassResource.name</code> and <code>controller.ingressClass</code> have to be set correctly. The first is to create the IngressClass object and the other is to modify the deployment of the actual ingress controller pod.</p><h3id=i-cant-use-multiple-namespaces-what-should-i-do>I can't use multiple namespaces, what should I do?<aclass=headerlinkhref=#i-cant-use-multiple-namespaces-what-should-i-dotitle="Permanent link"> ¶</a></h3><p>If you need to install all instances in the same namespace, then you need to specify a different <strong>election id</strong>, like this:</p><divclass=highlight><pre><span></span><code>helm install ingress-nginx-2 ingress-nginx/ingress-nginx \
</code></pre></div></article></div></div></main><footerclass=md-footer><divclass="md-footer-meta md-typeset"><divclass="md-footer-meta__inner md-grid"><divclass=md-footer-copyright> Made with <ahref=https://squidfunk.github.io/mkdocs-material/target=_blankrel=noopener> Material for MkDocs </a></div></div></div></footer></div><scriptsrc=../../assets/javascripts/vendor.93c04032.min.js></script><scriptsrc=../../assets/javascripts/bundle.83e5331e.min.js></script><scriptid=__langtype=application/json>{"clipboard.copy":"Copy to clipboard","clipboard.copied":"Copied to clipboard","search.config.lang":"en","search.config.pipeline":"trimmer, stopWordFilter","search.config.separator":"[\\s\\-]+","search.placeholder":"Search","search.result.placeholder":"Type to start searching","search.result.none":"No matching documents","search.result.one":"1 matching document","search.result.other":"# matching documents","search.result.more.one":"1 more on this page","search.result.more.other":"# more on this page","search.result.term.missing":"Missing"}</script><script>