<p>I am setting up my ingress controller, ingress class and ingress to expose a service outside the cluster. This is fresh cluster setup.</p>
<p>I have setup the nginx-ingress controller using</p>
<p><code>kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.41.0/deploy/static/provider/baremetal/deploy.yaml</code></p>
<p>The next step based on my understanding is to create the ingress class <a href="https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class" rel="noreferrer">https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class</a></p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
  name: external-lb
spec:
  controller: example.com/ingress-controller
  parameters:
    apiGroup: k8s.example.com/v1alpha
    kind: IngressParameters
    name: external-lb
</code></pre>
<p><strong>How did they get the name of the controller <code>example.com/ingress-controller</code>?</strong></p>

<p>I have run multiple scenarios with <code>IngressClass</code>, <code>Ingress</code> and <code>Nginx Ingress Controller</code>.</p>
<p><strong>Scenario 1</strong></p>
<ul>
<li>IngressClass with custom name</li>
<li>Nginx Ingress Controller with default <code>--ingress-class</code> value which is <code>nginx</code></li>
<li>Ingress using ingressClassName same as IngressClass name</li>
</ul>
<p><em>Output: Response 404</em></p>
<p><strong>Scenario 2</strong></p>
<ul>
<li>IngressClass with custom name</li>
<li>Nginx Ingress Controller with own<code>ingress-class</code> ingress-test</li>
<li>Ingress using ingressClassName same as IngressClass name</li>
</ul>
<p><em>Output: Response 404</em></p>
<p><strong>Scenario 3</strong></p>
<ul>
<li>IngressClass with <code>test</code> name</li>
<li>Nginx Ingress Controller <code>--ingress-class</code> with value <code>test</code></li>
<li>Ingress using <code>test</code> in ingressClassName</li>
</ul>
<p><em>Output: Proper response</em></p>
<p><strong>Senario 4</strong></p>
<ul>
<li>IngressClass with <code>nginx</code> name</li>
<li>Nginx Ingress Controller <code>--ingress-class</code> with value <code>nginx</code></li>
<li>Ingress using <code>nginx</code> in ingressClassName</li>
</ul>
<p><em>Output: Proper response</em></p>
<p><strong>Conclusion</strong></p>
<p>First of all, please keep in mind that there are 3 types of <code>Nginx</code>. <code>Open Source Nginx Ingress Controller</code>, you are probably using it. <code>Nginx Incorporaton</code> (nginx inc) and <code>Nginx Incorporaton Plus</code>.</p>
<p>In one of the scenarios, when I have used <code>spec.controller: nginx.org/ingress-controller</code> with <code>Nginx Ingress Controller</code> with argument <code>--ingress-class=nginx</code>, in <code>Nginx Ingress Controller</code> pod you will see entry which is pointing to <code>k8s.io/ingress-nginx</code>.</p>
<p>To reproduce this behavior, you will need to deploy <code>IngressClass</code> with specific controller and then deploy nginx.</p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: nginx.org/ingress-controller
</code></pre>
<p>After deploying <code>Nginx Ingress Controller</code>, controller pod will be in <code>CrashLoopBackOff</code> state. In logs you will find entry:</p>
<pre><code>E1118 15:42:19.008911       8 main.go:134] Invalid IngressClass (Spec.Controller) value &quot;nginx.org/ingress-controller&quot;. Should be &quot;k8s.io/ingress-nginx&quot;
</code></pre>
<p><strong>It works only when <code>IngressClass</code> name is set to <code>nginx</code>.</strong></p>
<p>I would say that <code>nginx.org/ingress-controller</code> is for <code>Nginx Incorporated</code> and <code>k8s.io/ingress-nginx</code> for <code>Open Source Nginx Ingress</code>.</p>
<p>If custom value is used for <code>--ingress-class</code> argument in the <code>controller Deployment manifest</code>, presence or absence of <code>IngressClass</code> object with the same name doesn't made any difference in, how the cluster works, if only you keep Ingress <code>spec.ingressClass</code> value  the same with controller argument. Moreover, if it's present, IngressClass <code>spec.controller</code> can have any value that match the required pattern &quot;domain like&quot; and that didn't affect <code>Ingress</code> workflow behavior on my cluster at all.</p>
<p>In addition, <code>Ingress</code> works fine if I put the correct value of the <code>ingress-class</code> either to <code>spec.ingressClass</code> property or to <code>metadata.annotation.kubernetes.io/ingress.class</code> accordingly. It gives an error like the following if you try to put both values to the same Ingres object:</p>
<pre><code>apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  ingressClassName: nginx
</code></pre>
<p><code>The Ingress &quot;test-ingress&quot; is invalid: annotations.kubernetes.io/ingress.class: Invalid value: &quot;nginx&quot;: can not be set when the class field is also set</code></p>
<p>Please keep in mind it was tested only for <a href="https://kubernetes.github.io/ingress-nginx/" rel="noreferrer">Nginx Ingress Controlle</a>. If you would like to use <code>IngressClass</code> with other <code>Ingress Controllers</code> like <a href="https://traefik.io/" rel="noreferrer">Traefik</a> or <a href="https://www.getambassador.io/" rel="noreferrer">Ambasador</a>, you would check their release notes.</p>
