<p>I have to deploy on my kubernetes cluster two deployments that use the same service for communicate but the two deployments are located into two differents namespaces:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: app1
  namespace: namespace1
  labels:
    app: app1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
        - name: app1
          image: eu.gcr.io/direct-variety-20998876/test1:dev
          resources:
            requests:
              cpu: &quot;100m&quot;
              memory: &quot;128Mi&quot;
          ports:
            - containerPort: 8000
          imagePullPolicy: Always
          env:
              ...
</code></pre>
<p>and an identical second but in another amespace:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: app2
  namespace: namespace2
  labels:
    app: app2
spec:
  replicas: 2
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
        - name: app2
          image: eu.gcr.io/direct-variety-20998876/test1:prod
          resources:
            requests:
              cpu: &quot;100m&quot;
              memory: &quot;128Mi&quot;
          ports:
            - containerPort: 8000
          imagePullPolicy: Always
          env:
              ...
</code></pre>
<p>so i have to create a common service for bot deployment that run over the two namespaces:
I try:</p>
<pre><code>kind: Service
apiVersion: v1
metadata:
  name: apps-service
  namespace: ???
spec:
  selector:
    app: ???
  ports:
  - protocol: TCP
    port: 8000
    targetPort: 8000
  type: NodePort
</code></pre>
<p>Until now i create one service for any app in specific namespace but there is a method for create a single service for manage both deployment (and then associate an unique ingress)?</p>
<p>So many thanks in advance</p>

Manuel Santi
<p>First, I would like to provide some general explanations.
As we can see in the <a href="https://v1-18.docs.kubernetes.io/docs/concepts/services-networking/ingress/#prerequisites" rel="nofollow noreferrer">Ingress documentation</a>:</p>
<blockquote>
<p>You must have an Ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect.</p>
</blockquote>
<p><strong><a href="https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/" rel="nofollow noreferrer">Ingress Controller</a></strong> can be deployed in any namespace and is often deployed in a namespace separate from the application namespace.</p>
<p><strong><a href="https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource" rel="nofollow noreferrer">Ingress resource</a></strong> (Ingress rules) should be deployed in the same namespace as the services they point to.</p>
<p>It is possible to have one ingress controller for multiple ingress resources.</p>
<p>Deploying an <code>Ingress</code> resource in the same namespace as the <code>Services</code> it points to is the most common approach (I recommend this approach).
However, there is way to have <code>Ingress</code> in one namespace and <code>Services</code> in another namespaces using <a href="https://kubernetes.io/docs/concepts/services-networking/service/#externalname" rel="nofollow noreferrer">externalName</a> Services.</p>
<hr />
<p>I will create an example to illustrate how it may work.</p>
<p>Suppose, I have two <code>Deployments</code> (<code>app1</code>, <code>app2</code>) deployed in two different <code>Namespaces</code> (<code>namespace1</code>, <code>namespace2</code>):</p>
<pre><code>$ cat app1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: app1
  name: app1
  namespace: namespace1
spec:
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      labels:
        app: app1
    spec:
      containers:
      - image: nginx
        name: nginx
    
$ cat app2.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: app2
  name: app2
  namespace: namespace2
spec:
  selector:
    matchLabels:
      app: app2
  template:
    metadata:
      labels:
        app: app2
    spec:
      containers:
      - image: nginx
        name: nginx
    
</code></pre>
<p>And I exposed these <code>Deployments</code> with <code>ClusterIP</code> <code>Services</code>:</p>
<pre><code>$ cat svc-app1.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: app1
  name: app1
  namespace: namespace1
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: app1
    
$ cat svc-app2.yml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: app2
  name: app2
  namespace: namespace2
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: app2
</code></pre>
<p>We want to have a single <code>Ingress</code> resource in a separate <code>Namespace</code> (<code>default</code>).
First, we need to deploy Services of type ExternalName that map a Service to a DNS name.</p>
<pre><code>$ cat external-app1.yml
kind: Service
apiVersion: v1
metadata:
  name: external-app1
spec:
  type: ExternalName
  externalName: app1.namespace1.svc
  
$ cat external-app2.yml
kind: Service
apiVersion: v1
metadata:
  name: external-app2
spec:
  type: ExternalName
  externalName: app2.namespace2.svc
</code></pre>
<p>Then we can deploy Ingress resource:</p>
<pre><code>$ cat ingress.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: app-ingress
spec:
  rules:
    - http:
        paths:
          - path: /app1
            backend:
              serviceName: external-app1
              servicePort: 80
          - path: /app2
            backend:
              serviceName: external-app2
              servicePort: 80
              
$ kubectl apply -f ingress.yml
ingress.networking.k8s.io/app-ingress created
          
</code></pre>
<p>Finally, we can check if it works as expected:</p>
<pre><code>$ curl 34.118.X.207/app1
app1
$ curl 34.118.X.207/app2
app2
</code></pre>
<p><strong>NOTE:</strong> This is a workaround and may work differently with different ingress controllers. It is ususally better to have two or more Ingress resources in different namespaces.</p>
