11

What I want to do is have a service in the default namespace and ingresses in my other namespaces, which point to that service. I tried implementing the service and Ingress shown below, but it didn't work.

kind: Service
apiVersion: v1
metadata:
  name: serviceX
  namespace: default
spec:
  type: ExternalName
  externalName: serviceX.default.svc.cluster.local
ports:
- port: 123


kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: web-ingress-test-vpndev
  namespace: my-namespace
spec:
  tls:
  - hosts:
    - abc.my-namespace.domain.com
    secretName: tls-secret-my-namespace
  rules:
  - http:
      paths:
      - path: "/"
        backend:
          serviceName: serviceX
          servicePort: 123
status:
  loadBalancer:
    ingress: {}

I know that I could implement the service in every namespace, but I was wondering if it's possible to have a single service. If I try to type the externalName of the service in the backend->serviceName handler of the ingress, I get and error saying that the name of the service can only contain numbers, letter and '-'.

Daniel
  • 509
  • 1
  • 4
  • 17
  • while providing `serviceName` in the ingress manifest can you try giving FQDN, that would be `serviceX.default.svc.cluster.local` – viveksinghggits Dec 12 '19 at 13:49
  • @viveksinghggits If i try to configure the serviceName like this `serviceName: serviceX.default.svc.cluster.local` I get an error. – Daniel Dec 12 '19 at 13:59

4 Answers4

5

I don't think this is possible and also don't think it's a good idea. Ingress is not a cluster level resource. Each namespace should have its own instance.

Dávid Molnár
  • 10,673
  • 7
  • 30
  • 55
4

I would have to say that this isnt a good way. as all of ingress in different NS would be convert to Nginx Rule and take effect in ingress-controller pod.

And if you take a look the Nginx Rule(nginx.conf in ingress-controller pod), you will see each block of location in nginx.conf has variable set $namespace "****"; which means the ingress has been isolated by NS

Also, if you still want to implement your idea, might need to modify the ingress-contoller.

Vampire_D
  • 518
  • 1
  • 4
  • 10
3

I achieve this using Istio. It's not the main reason why we are using it, but the traffic management features allows this kind of thing.

+--Namespace A-------------------------------+
|                                            |
|  +-------+   +-------+   +--------------+  |
|  |Ingress+--->Service+--->VirtualService|  |
|  +-------+   +-------+   +------+-------+  |
|                                 |          |
+--------------------------------------------+
                                  |
                  +---------------+
                  |
                  |      +--Namespace B---------+
                  |      |                      |
                  |      |  +-------+    +---+  |
                  +--------->Service+---->Pod|  |
                         |  +-------+    +---+  |
                         |                      |
                         +----------------------+

With Istio you can have your ingress in one namespace, a service without Selector (because there is no pod here) and a virtual service that route the traffic on service.namespaceA to service.namespaceB.

I'am using this to achieve blue-green deployment. Imagine the same principle than above but with 3 namespaces :

  • Namespace-A (with ingress, service and virtualService)
  • Namespace-B-blue (with blue services and pods)
  • Namespace-B-green (with green services and pods)

The switch between blue and green version is managed by the virtualService in the namespace-A. The advantage is that you can test the green version (smoke test) using routing features of istio before release it to everyone.

Fred Mériot
  • 4,157
  • 9
  • 33
  • 50
1

Just going to post this here to help others in future. This works on AWS but it may not on other cloud infra. If you want a single ALB to connect to services in different namespace to itself, you create two k8s ingress, but group them together.

Namespace A

apiVersion: v1
kind: Service
metadata:
  name: service-1
  namespace: A
spec:
  type: NodePort
  ports:
  - name: http
    port: 8080
    protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
      "alb.ingress.kubernetes.io/group.name": "group"
      "alb.ingress.kubernetes.io/group.order": "1"
  namespace: A
spec:
  rules:
  - host: latest.example.com
    http:
      paths:
      - backend:
          serviceName: service-1
          servicePort: 8080
        path: /

Namespace B

apiVersion: v1
kind: Service
metadata:
  name: service-2
  namespace: B
spec:
  type: NodePort
  ports:
  - name: http
    port: 8080
    protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
      "alb.ingress.kubernetes.io/group.name": "group"
      "alb.ingress.kubernetes.io/group.order": "2"
  namespace: B
spec:
  rules:
  - host: other.example.com
    http:
      paths:
      - backend:
          serviceName: service-2
          servicePort: 8080
        path: /

I've removed many annotations for brevity, but this will create a single ALB, with two ingress resources that enable the same domain to point into different services across different namespaces.

Rambatino
  • 4,716
  • 1
  • 33
  • 56