I have GKE Ingress with a backend referring to a kubernetes service of type ExternalName. The "external" service refers to another kubernetes service within the same cluster (in a different namespace, that's why the "external" service is used as a bridge). However, the healthcheck defined on the "external" service via BackendConfig is failing. When I test the "external" service on the healthcheck path and port via curl manually, it's working, giving 200 OK. Does anybody know if it's even possible to have an ExternalName service as a backend service for GKE Ingress? Or is there any other way how to reference a service from an Ingress across different namespaces? I know that I can create one Ingress per namespace to reference services in different namespace but each Ingress means a new IP address, new forwarding rules, more $$$. The namespaces are used to separate environments. Any hint is welcome...
2 Answers
I don't think you can use an ExternalName
service as the backend for an Ingress. ExternalName
is meant to be used for internal clients to alias an external service. You might be able to do what you want, but I've never tried that approach.
EDIT
As an alternative to using an ingress resource, you can try using the new Gateway API which does support a single shared entry point for multiple services (even across namespaces). It is currently in alpha, but mainly because the actual API will likely change in the future. Moving forward, it would be the path you'd want to take.
EDIT
If you want to use ingress, I'd suggest deploying an nginx ingress controller as it does support sharing a single external IP for multiple ingresses. You should be able to create an Ingress in each namespace pointing to the appropriate service and they will "share" the same external IP. You can specify a different path for the backend in each Ingress resource:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-hello-world-1
namespace: hello1
spec:
rules:
- http:
paths:
- backend:
serviceName: service-hello1
servicePort: 80
path: /hello-world-1
and
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-hello-world-2
namespace: hello2
spec:
rules:
- http:
paths:
- backend:
serviceName: service-hello2
servicePort: 80
path: /hello-world-2
A service of type ‘ExternalName’ is used for mapping from an internal DNS name to an external DNS name, it provides an internal alias for an external DNS name. So it cannot be used as the backend for an Ingress, refer to the doc [1]. To use Ingress Controller for multiple namespaces, go through this sample code.
To share the same external IP, you can run your own nginx-ingress controller in your cluster and expose it via the LoadBalancer service type. Then you would have one IP for your ingress and be able to serve all ingresses via nginx controller by adding annotation kubernetes.io/ingress.class: "nginx". For further information, go through the link.
Additionally, you can run multiple services on a single load balancer and public IP by configuring routing rules on the Ingress. By hosting multiple services on the same Ingress, you can avoid creating additional load balancers (which are billable resources) for every service that you expose to the internet. Refer to the [2].
[1] https://cloud.google.com/kubernetes-engine/docs/concepts/service#service_of_type_externalname