Similar to this question but for generic kubernetes. How can software I'm writing programmatically detect whether there is any ingress controller already existing in the cluster?
4 Answers
You most probably can't, since an ingress controller simply is a deployment that reads and interprets Kubernetes ingress resources by fetching them from the Kubernetes API server using REST or some other Kubernetes API client.
If ingress resources are present, that's a strong hint that an ingress controller is present though.
An ingress resource is a Kubernetes resource to define ingress rules. You can query the Kubernetes API server at https://kubernetes/apis/extensions/v1beta1/ingresses or use kubectl get ingress
as mentioned by others.
It's not mandatory to annotate the ingress.class
unless multiple ingress controllers are present (see https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/#using-multiple-ingress-controllers).
So in the end you may find hints, that an ingerss controller is present, and by reading ingress rules and their annotations you may also get hints which ingress controller is present, but you can't depend on it.

- 5,290
- 3
- 20
- 40
-
What resources? Can I detect the ingress class? or something else? – TREE Oct 09 '19 at 12:53
-
i added some more detail – Markus Dresch Oct 09 '19 at 13:01
-
Unfortunately, I probably can't rely on there being any ingress present. In some situations, my software will be the first thing deployed on the cluster. I need to validate that the cluster is in a good state beforehand. – TREE Oct 09 '19 at 13:03
-
and unfortunately you can also not reliably detect an ingress controller. you may check for common ingress controllers, for example those listed at https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/#additional-controllers which may be good enough, but it's not universal. – Markus Dresch Oct 09 '19 at 13:07
Yes it's a bit tricky because there is no such API object as ingress-controler
but only ingress
. Ingress
in it's turn is only loosely coupled to ingress controller and do not need the latter to be deployed successfully. So the presence of Ingress resource could not be the indication of ingress controller on it's own.
However the trick you might want to exploit is using the Events
section of Ingress as a source of some indicative information.
So when you deploy an Ingress in the fresh k8s cluster with no ingress-controller yet deployed the Events section is empty:
# deploy Ingress (no ingress controller yet)
$ kubectl apply -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
EOF
# check that Ingress deployed successfully
$ k get ing
NAME HOSTS ADDRESS PORTS AGE
test-ingress * 80 36m
# confirm there are no Events so far
$ k describe ing
Name: test-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
*
/testpath test:80 (<none>)
...
nginx.ingress.kubernetes.io/rewrite-target: /
Events: <none>
Then if you deploy the ingress controller the Ingress' Events does get some extra info:
# deploy ingress controller
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-role created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
deployment.apps/nginx-ingress-controller created
# check Ingress details once again
$ k describe ing test-ingress
Name: test-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
*
/testpath test:80 (<none>)
...
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal CREATE 7m11s nginx-ingress-controller Ingress default/test-ingress

- 985
- 2
- 10
- 16
-
that's an interesting approach. just want to add, that this is ingress controller specific as well. i'm using a custom made ingress controller that does not appear in any ingress events. – Markus Dresch Oct 10 '19 at 04:36
There is some function written in Golang which returns data when we hit
kubectl get ingress --all-namespaces
Please refer to this link, maybe after incorporation of the github repository to your code, you can get some help.
This blog also has some info in relation to such implementations, not exactly this although -

- 2,044
- 1
- 7
- 18
-
"Manually" is not an option. I'm not managing a cluster, I'm writing software. – TREE Oct 09 '19 at 12:19
If you provide the software with enough access for example using RBAC, you could implement checks using Kubernetes API or kubectl
commands.
This should be as a security measure be limited to the current namespace.
You mentioned that the software will be the first thing deployed on the cluster, that strongly implies that there won't be anything deployed on the cluster so there will be no Ingress as it's mentioned in the SO question you mentioned here.
You need to provide more details what exactly will be this software doing, who and how will install it.
It's possible that you will just include an option in the installation which will be used by a script that will do checks. Or you will relay on user input to provide correct information.
This is all theory crafting because the lack of the information.
Update
Maybe try using something like Peer finder or implement the idea into your script.

- 10,232
- 2
- 26
- 31
-
I am writing exactly that sort of script, and have full access to kubectl and/or the api server. It could be a brand new cluster or one already in use. – TREE Oct 10 '19 at 10:12