write ingress rule for application running with context-root - kubernetes

I have a web app and its corresponding backend service deployed in k8s. They are exposed as follows through services:
Web App -> http://1.2.3.4:8080/webapp/login
Backend -> http://5.6.7.8:8081/backend-service/login
I have configured ingress resource for these service but it turns out NGINX ingress controller is skipping the context root part while rewriting the url which is making my service unavailable when I am deploying it through ingress. Below is my ingress resource:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: default
name: gateway-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/use-regex: true
spec:
rules:
- http:
paths:
- path: /webapp/*
backend:
serviceName: webapp-service
servicePort: 8080
- path: /backend-service/*
backend:
serviceName: backend-service
servicePort: 8081
**Output of : kubectl describe ingress gateway-ingress**
Name: gateway-ingress
Namespace: default
Address: test.elb.us-east-2.amazonaws.com
Default backend: default-http-backend:80 (<none>)
Rules:
Host Path Backends
---- ---- --------
*
/webapp/* webapp-service:8080 (1.2.3.4:8080)
/backend-service/* backend-service:8081 (5.6.7.8:8081)
So when I am accessing my application using http://test.elb.us-east-2.amazonaws.com/webapp/login I am getting 404 not found. How can i configure ingress resource correctly?

Application context removal is caused by the rewrite-target annotation. Just remove it if it's not needed.

Related

Warning: Rejected - All hosts are taken by other resources

I'm trying to setup Nginx-ingress controller to manage two paths on the same hostname in bare metal based cluster.
In the app1 namespace i have below nginx resource:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app1-ingress
namespace: app1
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
And in the app2 namespace i have below nginx resource:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app2-ingress
namespace: app2
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
My app1-service applied first and it is running fine, now when i applied the second app2-service it shows below warning and not able to access it on browser.
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
How do i configure my nginx ingress resource to connect multiple service paths on the same hostname?
Default Nginx Ingress controller doesn't support having different Ingress resources with the same hostname. You can have one Ingress resource that contains multiple paths, but in this case all apps should live in one namespace. Like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app1-ingress
namespace: app1
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
Splitting ingresses between namespaces is currently not supported by standard Nginx Ingress controller.
You may however take a look at an alternative implementation of Nginx Ingress by Nginx Inc. They have support for Mergeable Ingresses.

Multi-path application with path based routing in Kubernetes ingress

I want to run a spring boot application over ingress having multiple path Like
http://localhost:8888/login
http://localhost:8888/client/dev
On localhost when i run this application it automatically redirect to /login
I am using traefik ingress controller. The pod and service is running. Ingress configured as below.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/redirect-entry-point: https
traefik.ingress.kubernetes.io/rewrite-target: /
name: config
namespace: default
spec:
rules:
- host: config.example.com
http:
paths:
- backend:
service:
name: config
port:
number: 8888
path: /config
pathType: ImplementationSpecific
status:
loadBalancer: {}
when i open https://config.example.com/config it redirects to https://config.example.com/login and i get 404 error.
What annotations can be used so that it allow me to do further sub path routing.

OpenShift Ingress external service

tell me how to map an external resource as a service in openshift for use in ingress?
OKD 3.11.
I am creating a service type ExternalName
apiVersion: v1
kind: Service
metadata:
name: "sso"
namespace: "test"
spec:
type: ExternalName
externalName: sso.test.org
Then I create a ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example
namespace: test
spec:
rules:
- host: app.test.org
http:
paths:
- path: /
backend:
serviceName: ui
servicePort: 8080
- path: /auth
backend:
serviceName: sso
servicePort: 443
- path: /api
backend:
serviceName: api
servicePort: 8080
But I get the error "Application is not available" for /auth.
/api and / works fine.
What could be the mistake?
I have a problem when accessing external ports with ssl. When accessing ports without ssl, no problems. It seems that haroute does not add https at the beginning of the address, and the request goes through http:// sso:443

ingress can not get the default http backend

The ingress I config to run with the controller ingress-nginx.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
tls:
- hosts:
- XXX.XX.com
secretName: app-tls
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-api
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
I can run the api locally curl localIP:3000/testapi, but it can not run remotely.
# kubectl describe ingress app-ingress
Name: app-ingress
Namespace: default
Address: XX.XX.XX.XX
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
app-tls terminates www.daichenchen.cn
Rules:
Host Path Backends
---- ---- --------
XXX.XX.com
/my-api(/|$)(.*) app:80 (<error: endpoints "app" not found>)
I already succeed install the ingress-nginx and all the pod work without error.
Your defined serviceName in Ingress rules and Service should be same.
Like this :
...
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
If Ingress and the Service is in different namespace, you can also add the service name to the ingress rule. In this case you need to use dns name for service <service-name>.<namespace>.
For example:
rules:
- host: example.com
http:
paths:
- path: /my-api
backend:
serviceName: test-service.test-namespace
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: test-namespace
The way ingress controller finds out Endpoints of a service is it searches for a kubernetes service with the serviceName provided in the ingress resource in the namespace where you have created the ingress resource. If there is no kubernetes service with serviceName found you get endpoints not found.
The Endpoints of the service contains the IPs of pods behind the kubernetes service.
So in your case either the kubernetes service does not exist or it's in a different namespace than where ingress resource is created.
Some variant of nginx ingress controller does not support default backend and for this it's expected to have the error: endpoints "default-http-backend" not found
Another variant of nginx ingress controller supports default backend.
Double check which variant of nginx ingress controller you installed

ERR_TOO_MANY_REDIRECTS for Minio via NGINX Ingress Controller

I have a Minio ClusterIP service running in a Kubernetes cluster. And on top of it, I have a NGINX Ingress Controller. NGINX Ingress needs to forward Minio traffic to the Minio service, and other traffic to their corresponding services.
My Ingress configuration looks like this:
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: /app/?(.*)
backend:
serviceName: app-service
servicePort: 3000
- path: /minio/?(.*)
backend:
serviceName: minio-service
servicePort: 9000
Once deployed, the app works fine. However, the Minio page has problem, complaining:
This page isn’t working
example.mysite.com redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS
And indeed, the requests are kept redirecting. Here is the screenshot from Chrome DevTools' Network console.
Any ideas?
As Minio always redirects to /minio/, you need to keep /minio in the path and pass it on to the Minio service.
When I change its path rule to - path: /(minio/.*), it works. Now the Ingress configuration looks like below:
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: /app/?(.*)
backend:
serviceName: app-service
servicePort: 3000
- path: /(minio/.*)
backend:
serviceName: minio-service
servicePort: 9000
And I've got the Minio service working in the browser:
Hope it is helpful.