Can the same hostname be used in different namespaces in kubernetes? - kubernetes

I want to use my hostname as test.com in first namespace and example.com/demo in another namespace. However i am unable to do that since (in my opinion) the nginx-ingress controller always points to the first website (example.com). My nginx-ingress controller is running in the default namespace
#namespace prod
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
rules:
- host: example.com
http:
paths:
- path: /static
backend:
serviceName: app-svc
servicePort: 80
- path: /
backend:
serviceName: app-svc
servicePort: 8000
tls:
- hosts:
- example.com
secretName: cert
status:
loadBalancer:
ingress:
- ip: xx.xxx.xx.xxx
#namespace dev
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: test-ingress
namespace: dev-env
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
rules:
- host: example.com
http:
paths:
- path: /static
backend:
serviceName: app-svc
servicePort: 80
- path: /demo
backend:
serviceName: app-svc
servicePort: 8000
tls:
- hosts:
- example.com
secretName: cert
status:
loadBalancer:
ingress:
- ip: xx.xxx.xx.xxx

You can use the same hostname/domain, but in order to access distinct backend services, you have to define distinct paths, in your case you can do something like this:
#namespace prod
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: test-ingress
namespace: prod-env
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
rules:
- host: example.com
http:
paths:
- path: /prod/static
backend:
serviceName: app-svc
servicePort: 80
- path: /prod/
backend:
serviceName: app-svc
servicePort: 8000
tls:
- hosts:
- example.com
secretName: selfsigned-cert
status:
loadBalancer:
ingress:
- ip: 80.180.31.153
#namespace dev
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: test-ingress
namespace: dev-env
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
spec:
rules:
- host: example.com
http:
paths:
- path: /dev/static
backend:
serviceName: app-svc
servicePort: 80
- path: /demo
backend:
serviceName: app-svc
servicePort: 8000
tls:
- hosts:
- example.com
secretName: selfsigned-cert
status:
loadBalancer:
ingress:
- ip: 80.180.31.153
Like this you have:
example.com/prod/static -> points to app-svc:80 on prod-env namespace
example.com/prod/ -> points to app-svc:8000 on prod-env namespace
example.com/dev/static -> points to app-svc:8000 on dev-env namespace
example.com/demo -> points to app-svc:8000 on dev-env namespace
If you need to preserve the url after host, you should add a subdomain for each namespace:
dev.example.com/static -> points to app-svc:80 on prod-env namespace
prod.example.com/static -> points to app-svc:8000 on dev-env namespace
In order for this one to work you have to have defined this as an A record in your domain DNS administration, pointing at the same IP as your loadBalancer (80.180.31.153 in this case):
example.com A -> 80.180.31.153 (optional)
dev.exmaple.com A -> 80.180.31.153
prod.example.com A -> 80.180.31.153
or the easiest one:
*.example.com A -> 80.180.31.153

Related

Kubernetes Ingress path route to different services in different namespaces

currently I'm trying the following setup:
I have:
one cluster
one Ingress Controller
one url (myapp.onazure.com)
two namespaces for two applications default and default-test
two deployments, ingress objects, services for the namespaces
I can easily reach my app from the default namespace with path based routing '/' as a prefix rule
Now i have tried to configure the second namespace and following rule: /testing to hit another service
Unfortunately i get an HTTP404 when i try to hit the following URL myapp.onazure.com/testing/openapi.json
What did I miss?
Working Ingress 1
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object
namespace: default
annotations:
kubernetes.io/ingress.class: public-nginx
spec:
tls:
- hosts:
- myapp-region1.onazure.com
- myapp-region2.onazure.com
secretName: ingress-tls-csi
rules:
- host: - myapp-region1.onazure.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: liveapi-svc
port:
number: 8080
- host: myapp-region2.onazure.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: liveapi-svc
port:
number: 8080
Not working Ingress 2
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object-testing
namespace: default-testing
annotations:
kubernetes.io/ingress.class: public-nginx
#nginx.ingress.kubernetes.io/rewrite-target: /testing
spec:
tls:
- hosts:
- myapp-region1.onazure.com
- myapp-region2.onazure.com
secretName: ingress-tls-csi-testing
rules:
- host: myapp-region1.onazure.com
http:
paths:
- path: /testing
#pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8080
- host: myapp-region2.onazure.com
http:
paths:
- path: /testing
#pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8080
Maybe I am missing a rewrite target to simply '/' in the testing namespace ingress?
Finally I figured out the missing part. I had to add the following statement to the not working ingress object:
annotations:
kubernetes.io/ingress.class: public-nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
Please see the complete ingress object:
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: liveapi-ingress-object
namespace: default-testing
annotations:
kubernetes.io/ingress.class: public-nginx
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- myapp.onazure.com
secretName: ingress-tls-csi-testing
rules:
- host: myapp.onazure.com
http:
paths:
- path: /testing/(.*)
pathType: Prefix
backend:
service:
name: liveapi-svc-testing
port:
number: 8000
Use full DNS name of a service,
$SERVICE.$NAMESPACE.svc.cluster.local
But you need to make sure your ignress controller has acccess to the desired namespace.

Ingress don't load the website assets (Css files and Javascript files)

I have a kubeadm cluster and i am trying to deploy to static websites using ingress (after installing the metalLB and nginx-ingress controller )
After deploying the ingress, i find that the ingress don't load the website assets (the html file only)
Please any help !
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
name: ingress-test
spec:
ingressClassName: nginx
rules:
- host: k8s.example.k8s
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-svc
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-svc
port:
number: 80
Make sure your routing working properly with ingress
Example and it's not 404 for css:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /?(.*)
backend:
serviceName: service
servicePort: 3000
- path: /api/?(.*)
backend:
serviceName: service
servicePort: 5000
Read more at : https://github.com/kubernetes/ingress-nginx/issues/2557

Kubernetes how to run multiple services at the same address

I have several sites available at http://service1/api and http://service2/api
I want them to work on the same external address and routing occurs inside the kube
http:/exturi/service1/api
http:/exturi/service2/api
Ingress configuration
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: ingress-api
spec:
rules:
- host: api.sample.com
http:
paths:
- backend:
serviceName: edpcore-db-api
servicePort: 13001
path: /db-api/
pathType: Prefix
tls:
- hosts:
- api.sample.com
secretName: tls-api-secret
how to configure ingress
If you are using the Nginx ingress you can do routing using
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: service-1
servicePort: 80
path: /service-1(/|$)(.*)
- backend:
serviceName: service-2
servicePort: 80
path: /service-2(/|$)(.*)
For example, the ingress definition above will result in the following rewrites:
rewrite.bar.com/service1 rewrites to rewrite.bar.com/
rewrite.bar.com/service1/ rewrites to rewrite.bar.com/
rewrite.bar.com/service1/new rewrites to rewrite.bar.com/new
Refer : https://kubernetes.github.io/ingress-nginx/examples/rewrite/
Extra
If you don't want to remove service name or rewrite simple use this config
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: haproxy
name: simple
namespace: default
spec:
rules:
- host: simple.bar.com
http:
paths:
- backend:
serviceName: service-1
servicePort: 80
path: /service-1
- backend:
serviceName: service-2
servicePort: 80
path: /service-2
Thats how you should do it (nginx ingress):
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: my-ingress-namespace
spec:
rules:
- host: exturi
http:
paths:
- backend:
service:
name: service1
port:
number: 80
path: /service1/(.*)
pathType: ImplementationSpecific
- backend:
service:
name: service2
port:
number: 80
path: /service2/(.*)
pathType: ImplementationSpecific
status:
loadBalancer:
ingress:
- ip: {}

rewrites path on ingress kubernetes

i have tomcat backend service running on kubernetes cluster try to rewrite using ingress with path /blob/api/v1/test-backend > /api/v1/test-backend so
the configuration now is running so can hit to xx.somedomain.com/blob/api/v1/test-backend and i want change to xx.somedomain.com/api/v1/test-backend with rewrites
my basic ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-blob
namespace: blob-test
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: 50m
spec:
tls:
- hosts:
- xx.somedomain.com
secretName: cert-key
rules:
- host: xx.somedomain.com
http:
paths:
- path: /blob/
backend:
serviceName: blob-service
servicePort: 8080
- path: /
backend:
serviceName: web-service
servicePort: 80
and this is yaml for rewrite /blob/
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-blob
namespace: blob-test
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-body-size: 50m
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- xx.somedomain.com
secretName: cert-key
rules:
- host: xx.somedomain.com
http:
paths:
- path: /blob/api/v1/some-backend
backend:
serviceName: blob-service
servicePort: 8080
when i test with api tester like talend is got 405 error
Try this
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
For example, the ingress definition above will result in the following rewrites:
rewrite.bar.com/something rewrites to rewrite.bar.com/
rewrite.bar.com/something/ rewrites to rewrite.bar.com/
rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
Refer : https://kubernetes.github.io/ingress-nginx/examples/rewrite/
Try adding annotation like this
nginx.ingress.kubernetes.io/rewrite-target: "/$1"

Kubernetes Nginx Ingress not redirect properly to path routing services

I'm using ingress for kubernetes. My ingress is kubernetes nginx ingress. And routing configs don't work and redirect me root path in every request in https section All configs is given below
cat frontapi-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: swagger-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: preprod-ops.kblab.local
http:
paths:
- backend:
serviceName: kb-workplace
servicePort: 8080
path: /
- backend:
serviceName: gw-branch
servicePort: 8443
path: /api
$ cat swagger-portal.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: swagger-portal
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: preprod-ops.kblab.local
http:
paths:
- backend:
serviceName: swagger-portal
servicePort: 9001
path: /swagger-portal
Above config works properly with http config but, below config doesn't work with https config. It only works swagger-portal section
$cat frontapi-ingress-https.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/secure-verify-ca-secret: preprod.kblab.local
kubernetes.io/ingress.class: nginx
generation: 1
name: app-ingress
spec:
rules:
- host: preprod.kblab.local
http:
paths:
- backend:
serviceName: gw-branch
servicePort: 8443
path: /api
- backend:
serviceName: kb-workplace
servicePort: 8080
path: /
- backend:
serviceName: acs-alfresco
servicePort: 8080
path: /acs
tls:
- hosts:
- preprod.kblab.local
- secretName: preprod.kblab.local
$ cat swagger-portal-https.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
name: swagger-portal
spec:
rules:
- host: preprod.kblab.local
http:
paths:
- backend:
serviceName: swagger-portal
servicePort: 9001
path: /swagger-portal/a
tls:
- hosts:
- preprod.kblab.local
- secretName: preprod.kblab.local
Thanks in advance.
You are setting the nginx.ingress.kubernetes.io/rewrite-target: / annotation on your swagger-portal-https.yaml Ingress, which explicitly implies the redirection to the root path.
If you want to preserve the request path, you need to remove this annotation.