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:
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: "100m"
memory: "128Mi"
ports:
- containerPort: 8000
imagePullPolicy: Always
env:
...
and an identical second but in another amespace:
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: "100m"
memory: "128Mi"
ports:
- containerPort: 8000
imagePullPolicy: Always
env:
...
so i have to create a common service for bot deployment that run over the two namespaces: I try:
kind: Service
apiVersion: v1
metadata:
name: apps-service
namespace: ???
spec:
selector:
app: ???
ports:
- protocol: TCP
port: 8000
targetPort: 8000
type: NodePort
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)?
So many thanks in advance
First, I would like to provide some general explanations. As we can see in the Ingress documentation:
You must have an Ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect.
Ingress Controller can be deployed in any namespace and is often deployed in a namespace separate from the application namespace.
Ingress resource (Ingress rules) should be deployed in the same namespace as the services they point to.
It is possible to have one ingress controller for multiple ingress resources.
Deploying an Ingress
resource in the same namespace as the Services
it points to is the most common approach (I recommend this approach).
However, there is way to have Ingress
in one namespace and Services
in another namespaces using externalName Services.
I will create an example to illustrate how it may work.
Suppose, I have two Deployments
(app1
, app2
) deployed in two different Namespaces
(namespace1
, namespace2
):
$ 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
And I exposed these Deployments
with ClusterIP
Services
:
$ 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
We want to have a single Ingress
resource in a separate Namespace
(default
).
First, we need to deploy Services of type ExternalName that map a Service to a DNS name.
$ 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
Then we can deploy Ingress resource:
$ 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
Finally, we can check if it works as expected:
$ curl 34.118.X.207/app1
app1
$ curl 34.118.X.207/app2
app2
NOTE: 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.