Ingress configuration for k8s in different namespaces
Outside traffic comes through ingress controller service
that is responsible for routing the traffic based on the defined routing rules or what we call ingress rules
in k8s world.
In other words, ingress
resources are just routing rules (think of it in away that's similar to DNS records) so when you define an ingress
resource you just defined a rule for ingress controller
to work on and route traffic based on such defined rules.
Solution:
Since
Ingress
are nothing but routing rules, you could define such rules anywhere in the cluster (in anynamespace
) andcontroller
should pick them up as it monitors creation of such resources and react accordingly.Here's how to create ingress easily using
kubectl
kubectl create ingress <name> -n namespaceName --rule="host/prefix=serviceName:portNumber"
Note: Add
--dry-run=client -oyaml
to generateyaml
manifest fileOr you may create a service of type
ExternalName
in the samenamespace
where you have defined youringress
. such external service can point to any URL (a service that lives outsidenamespace
or even k8s cluster)Here's an example that shows how to create an
ExternalName
service using kubectl:kubectl create service externalname ingress-ns -n namespaceName --external-name=serviceName.namespace.svc.cluster.local --tcp=80:80 --dry-run=client -oyaml
this should generate something similar to the following:
kind: Service
apiVersion: v1
metadata:
name: nginx
namespace: ingress-ns
spec:
type: ExternalName
externalName: serviceName.namespace.svc.cluster.local #or any external svc
ports:
- port: 80 #specify the port of service you want to expose
targetPort: 80 #port of external service
As described above, create an ingress as below:
kubectl create ingress <name> -n namespaceName --rule="host/prefix=serviceName:portNumber"
Note: Add --dry-run=client -oyaml
to generate yaml
manifest file
I would like to simplify the answer a bit further for those who are reletively new to Kubernetes and its ingress options in particular. There are 2 separate things that need to be present for ingress to work:
- Ingress Controller(essentially a separate Pod/Deployment along with a Service that can be used to utilize routing and proxying. Based on nginx container for example);
- Ingress rules(a separate Kubernetes
resourse with
kind: Ingress
. Will only take effect if Ingress Controller is already deployed)
Now, Ingress Controller can be deployed in any namespace and is, in fact, usually deployed in a namespace separate from your app services. It can out-of-the-box see Ingress rules in all namespaces in the cluster and will pick them up.
The Ingress rules, however, must reside in the namespace where the app that they configure reside.
There are some workarounds for that, but this is the most common approach.
Instead of creating the ingress app-ingress
in ingress-nginx
namespace you should create it in the namespace where you have the service api-sand
and the pod.
Alternatively there is way to achieve ingress in one namespace and service in another namespace via externalName
.Checkout Kubernetes Cross Namespace Ingress Network
Here is an example referred from here.
kind: Service
apiVersion: v1
metadata:
name: my-service
spec:
type: ExternalName
externalName: test-service.namespacename.svc.cluster.local
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.com
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: 80
It's possible actually, you can define ingress and a service with ExternalName type in namespace A, while the ExternalName points to DNS of the service in namespace B. For further details, please refer to this answer: https://stackoverflow.com/a/51899301/2995449