1

Summary

I am specifying an IngressClassName without a corresponding IngressClass resource and it is unexpectedly working fine; my understanding was you need to define the IngressClass resource as well. Previously we were using the annotation based approach, kubernetes.io/ingress.class, so I am migrating to the new way.

Details

My reading of the above doc makes me think if you set IngressClassName as follows

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  labels:
    app: example-service.example.com
    manager: nginx-ingress-controller
  name: example
spec:
  ingressClassName: example-com-public
  rules:
  - host: example-service.example.com
    http:
      paths:
      - backend:
          serviceName: example-service
          servicePort: 8080
        path: /

Then there needs to be a IngressClass with name example-com-public. However, in our cluster, this is not the case since we are migrating from the old annotation-only approach. Yet everything works. It seems we may not need to have to create IngressClass resources?

1 Answers1

1

I have analyzed this scenario and came to the following conclusions:

  • IngressClass defines the Ingress Controller and each Ingress rule may be marked with corresponding ingress.class annotation.

  • If a custom value is used for --ingress-class argument in the controller Deployment manifest it doesn't matter if there is a corresponding IngressClass object with the same name. However, you need to keep the Ingress' spec.ingressClass value the same as controller's argument. Moreover, if it's present, IngressClass spec.controller can have any value that match the required pattern "domain like" and that would not affect Ingress workflow behavior.

  • The Ingress is working fine if you put the correct value of the ingress-class to spec.ingressClassName property or to metadata.annotation.kubernetes.io/ingress.class. But if you try to put both values to the same Ingress object you're gonna see the error like this:


The Ingress "test-ingress" is invalid: annotations.kubernetes.io/ingress.class: Invalid value: "nginx": can not be set when the class field is also set

  • An example of working IngressClass requires: IngressClass with name example-com-public + Nginx Ingress Controller with --ingress-class argument set to example-com-public + Ingress with example-com-public value in ingressClassName

  • See this diagram: this diagram for a better visual understanding.

  • Thanks for the thorough analysis - I am reading through it and seeing how it related to our set up – Friedrich 'Fred' Clausen Apr 27 '21 at 03:11
  • So, to summarise: If no `IngressClass` then the `Ingress`'s `spec.ingressClassName` _needs to_ match the controller exactly. However by using an `IngressClass` resource we can have a more flexible matching process. I have tried to sketch my understanding here: https://i.imgur.com/n9cQCrQ.png – Friedrich 'Fred' Clausen Apr 27 '21 at 04:27
  • That would be correct. Bear in mind tho that I was analyzing with the Nginx Ingress Controller (the one that you are using). There are also other controllers like Nginx Incorporaton (nginx inc) and Nginx Incorporaton Plus which could also be used but would require different tests. – Wytrzymały Wiktor Apr 27 '21 at 11:32
  • 1
    Yup, fair enough. If you see value in my diagram feel free to add to answer. Finally - you wrote "The Ingress is working fine if you put the correct value of the ingress-class to spec.ingressClass property " - I think you mean `spec.ingressClassName` property as applied to the Ingress itself? I will accept your answer in the meantime. – Friedrich 'Fred' Clausen Apr 28 '21 at 03:35
  • Done, thanks for your input :) – Wytrzymały Wiktor Apr 28 '21 at 06:45