DenCowboy
DenCowboy

Reputation: 15076

Ingress in Kubernetes

I was doing some research about ingress and it seems I have to create a new ingress resource for each namespace. Is that correct?

I just created 2 separate ingress resources in different namespaces in my GKE cluster but it seems to use the same LB in(which is great for cost) but I would think it is possible to have clashes then. (when using same path). I just tried it and the first one I've created is still working on the path, the other newer one on the same path is just not working.

Can someone explain me the correct setup for ingress?

Upvotes: 0

Views: 119

Answers (2)

suren
suren

Reputation: 8786

As Kubernetes works, ingress controller won't pass a packet to a service that is in a different namespace from the ingress resource. So, if you create an ingress resource in the default namespace, all your services must be in the default namespace as well.

This is something that won't change. EVER. There has been a feature request years ago, and kubernetes team announced that it's not going to happen. It introduces a security hole when ingress controller is being able to transpass a namespace.

Now, what we do in these situations is actually pretty neat. You will have to do the following:

  1. Say you have 2 services in the namespaces you need. e.g. service1.foo and service2.bar.
  2. create 2 headless services without selectors and 2 Endpoint objects pointing to the IP addresses of the services service1.foo and service2.bar, in the same namespace as the ingress resource. The headless service without selectors will force kube-dns (or coreDNS) to search for either ExternalName type service or an Endpoint object. Now, the only requirement here is that your headless service and the Endpoint object must have the same name.
  3. Create your ingress resource pointing to the headless services.

It should look like this (for 1 service):

Say the IP address of service1.foo is 10.10.10.10. Your headless service and the Endpoint object would be:

apiVersion: v1
kind: Service
metadata:
  name: bait-svc
spec:
  clusterIP: None
  ports:
  - name: http
    port: 80
    targetPort: 80

---

apiVersion: v1
kind: Endpoints
metadata:
  name: bait-svc
subsets:
- addresses:
  - ip: 10.10.10.10
  ports:
  - port: 80
    protocol: TCP

and Ingress resource:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - secretName: ssl-certs 
  rules:
  - host: site1.training.com
    http:
      paths:
      - path: /
        backend:
          serviceName: bait-svc
          servicePort: 80

So, the Ingress points to the bait-svc, and bait-svc points to service1.foo. And you will do this for each service.

UPDATE

I am thinking now, it might not work with GKE Ingress Controller, as on GKE you need a NodePort type service for the HTTP load balancer to reach the service. As you can see, in my example I've got nginx Ingress Controller.

Independently if it works or not, I would recommend using some other Ingress Controller. It's not that GKE IC is not good. It is quite robust, but almost always you end up hitting some limitation. Other ICs are more flexible.

Upvotes: 2

coderanger
coderanger

Reputation: 54211

The behavior of conflicting Ingress routes is undefined and implementation dependent. In most cases it’s just last writer wins.

Upvotes: 0

Related Questions