Kubernetes how to run multiple services at the same address - kubernetes

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: {}

Related

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

Convert apiVersion: networking.k8s.io/v1beta1 ingress manifest to apiVersion: networking.k8s.io/v1

I had installed an ran a kubernetes cluster with an nginx ingress earlier this year. Though it had little issues, it worked fine. For the ingress, I used the tag
apiVersion: networking.k8s.io/v1beta1
However, I have recently installed the latest version of (kubernetes 1.22) which only allows for
apiVersion: networking.k8s.io/v1
The problem i'm having is using my old yaml configuration with the new format.
My yaml file looks like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: dev-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/websocket-services : "chatserver"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- http:
paths:
- path: /api/auth/
pathType: Prefix
backend:
serviceName: um-service
servicePort: 5001
- path: /api/system/*
pathType: Prefix
backend:
serviceName: system-service
servicePort: 5002
- path: /api/news/*
backend:
serviceName: news-service
servicePort: 5003
- path: /api/tasks/*
# pathType: Prefix
backend:
serviceName: tasks-service
servicePort: 5004
- path: /api/chats/
pathType: Prefix
backend:
serviceName: chatserver
servicePort: 5500
- path: /
backend:
serviceName: web-service
servicePort: 5000
my new manifest looks like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dev-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /api/auth/
pathType: Prefix
backend:
service:
name: um-service
port:
number: 5001
- path: /api/system/*
pathType: Prefix
backend:
service:
name: system-service
port:
number: 5002
- path: /api/chats/
pathType: Prefix
backend:
service:
name: chatserver
port:
number: 5050
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 5000
ingressClassName: nginx
How do I convert this to use the new apiVersion: networking.k8s.io/v1 tag?
Fortunately there isn't too much difference between the API versions in terms of the YAML. Here's an example of networking.k8s.io/v1 from the Kubernetes Docs.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
The main change for you would have to do with the how the backend blocks are done. For example:
backend:
serviceName: tasks-service
servicePort: 5004
would need to become:
backend:
service:
name: "tasks-service"
port:
number: 5004

How to rewrite URLs for some specific paths?

I have read in ingress-nginx documentation that the rewrite is being performed thanks to an annotation like 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(/|$)(.*)
I have a case where I have multiple hosts and I want URL rewriting for some particular paths only:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
name: ingress
spec:
rules:
- host: somehost.westeurope.cloudapp.azure.com
http:
paths:
- path: /rest-smtp-sink # I want to rewrite this path
pathType: Prefix
backend:
service:
name: rest-smtp-sink-svc
port:
number: 80
- path: /backend # This one too
pathType: Prefix
backend:
service:
name: server-svc
port:
number: 80
- path: / # But not this one
pathType: Prefix
backend:
service:
name: client-svc
port:
number: 80
However, the annotation seems to be global. How do I enable URL rewriting for some paths only?
I managed to get the desired result with this configuration:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: ingress
spec:
rules:
- host: somehost.westeurope.cloudapp.azure.com
http:
paths:
- path: /rest-smtp-sink(/|$)(.*)
pathType: Prefix
backend:
service:
name: rest-smtp-sink-svc
port:
number: 80
- path: /backend(/|$)(.*)
pathType: Prefix
backend:
service:
name: server-svc
port:
number: 80
- path: /()(.*)
pathType: Prefix
backend:
service:
name: client-svc
port:
number: 80
As the nginx.ingress.kubernetes.io/rewrite-target annotation is global, I've used /$2 as the rewrite target and /()(.*) as a noop for the root path.

Can the same hostname be used in different namespaces in 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

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.