Ingress to redirect to service from LB ip - kubernetes

I'm trying to create an Ingress rule to redirect requests from LoadBalancer to Service.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless
backend:
serviceName: node-red
servicePort: 1880
The above yaml script is supposed to redirect all requests from https://LOAD_BALANCER_IP/hostless to node-red on port 1880
If I try to request the above URL, I got an error Cannot GET /hostless. Requesting the root gives 404 page not found.
I can access my services with the direct URL (eg. http://LOAD_BALANCER_IP:1880 will redirect to Node-red service).
Service yaml looks like that:
apiVersion: v1
kind: Service
metadata:
labels:
app: node-red
name: node-red
spec:
ports:
- name: "1880"
port: 1880
protocol: TCP
targetPort: 1880
selector:
app: node-red
sessionAffinity: None
type: LoadBalancer
How to use ingress to reach a service whereas a custom port ?

I've found a way to make it works !
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/redirect-entry-point: https
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.middlewares: "kube-system-traefik-stripprefix#kubernetescrd"
name: traefik-all
namespace: partner
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: nginx-demo
servicePort: 2222
- path: /node
backend:
serviceName: node-red
servicePort: 1880
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-stripprefix
namespace: kube-system
spec:
stripPrefixRegex:
regex:
- "/[^/]+"
I use a middleware to remove the prefix as K3S Traefik does not support the traefik.ingress.kubernetes.io/rewrite-target annotation.
With the above code, all trafic from LOAD_BALANCER_IP/* will be redirected to nginx-demo:2222 service. All trafic from LOAD_BALANCER_IP/node/* will be redicted to node-red:1880 service.
I hope this could help someone !

Try setting a rewrite-target annotation, which will effectively rewrite /hostless requests to /, i.e. http://LOAD_BALANCER_IP:1880/hostless externally to http://node-red:1880 internally.
For example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless(/|$)(.*)
backend:
serviceName: node-red
servicePort: 1880
See this link, assuming you are using Nginx ingress controller.

Related

using NGINX ingress with https not on 443

How do you use an NGINX ingress controller to route to an app using SSL that is not running on 443? I found this post which seems to say it's not possible.
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
selector:
matchLabels:
app: foo
replicas: 2
template:
metadata:
labels:
app: foo
spec:
containers:
- name: foo
image: bar
ports:
- containerPort: 3000
Trying:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: foo.com
- http:
paths:
- path: /
backend:
serviceName: foo
servicePort: 3000
NginX Ingress Controller is a Layer 7 technology, it does host based (Layer 7) routing and not on ports (Layer 4). So, your clients are expected to connect using standard port 80/443.
So, your clients will simply connect to the https://example.com (port 443) and kubernetes ingress controller will redirect it to your https service on port 3000.
However, since your service is ssl enabled, you will have to use the proper annotations
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: foo
servicePort: 3000

Blazor server through k8s ingress controller

I've written a small Blazor application which looks to work all well when containerized and when accessed through k3s port forwarding, but struggling to find a guideline on how that application needs to be correctly exposed via a ingress controller. To show this:
If I run the Blazor application and access via port-forwarding (blazor routing works perfectly well etc.):
kubectl port-forward deployment/ 8000:80
and page routing working as expected
However, when I add a clusterIP service to the deployment and connect to it through Traefik ingress controller, I get:
and changing the route will give a 404 page not found error
My Ingress serviceIp and ingress controller setup:
ClusterIP:
apiVersion: v1
kind: Service
metadata:
name: driverpassthrough
spec:
selector:
app: driverpassthrough
ports:
- name: ui
protocol: TCP
port: 8010
targetPort: 80
ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-test
annotations:
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /passthrough
backend:
serviceName: driverpassthrough
servicePort: 8010
so in my case, I use k3s and traefik. I also have 3 replicas of my blazor server app. To make it work, I had to enable sticky session (in annotations) on the cluster ip like so:
Service
apiVersion: v1
kind: Service
metadata:
name: qscale-healthcheck-service
annotations:
traefik.ingress.kubernetes.io/affinity: "true"
labels:
name: qscale-healthcheck-service
spec:
type: ClusterIP
selector:
app: healthcheck
ports:
- name: http
port: 80
targetPort: 80
Ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: qscale-healthcheck-service
servicePort: 80
This is the link where I found the annotation: Traefik Doc

Azure Kubernetes Nginx Ingress: How do I properly route to an API service and an Nginx web server with HTTPS and avoid 502?

I have 2 services, one serves up a rest API and the other serves up static content via nginx web server.
I can retrieve the static content from the pod running an nginx web server via the ingress controller using https provided that I don't use the following annotation within the ingress yaml
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
However, the backend API service no longer works. If I add that annotation back, the backend service URL https://fqdn/restservices/engine-rest/v1/api works but the front end https://fqdn/ web server throws a 502.
Ingress
Ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
- path: /
backend:
serviceName: b
servicePort: 8011
Service API
kind: Service
apiVersion: v1
metadata:
name: a
namespace: namespace-abc
labels:
app: a
version: 1
spec:
ports:
- name: https
protocol: TCP
port: 80
targetPort: 8080
nodePort: 31019
selector:
app: a
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: ClientIP
externalTrafficPolicy: Cluster
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Service UI
kind: Service
apiVersion: v1
metadata:
name: b
namespace: namespace-abc
labels:
app: b
version: 1
annotations:
spec:
ports:
- name: http
protocol: TCP
port: 8011
targetPort: 8011
nodePort: 32620
selector:
app: b
version: 1
clusterIP: <cluster ip>
type: LoadBalancer
sessionAffinity: None
externalTrafficPolicy: Cluster
If your problem is that adding nginx.ingress.kubernetes.io/backend-protocol: HTTPS makes service-A work but fails service-B, and removing it makes service-A fail but works for service-B, then the solution is to create two different Ingress objects so they can be annotated independently
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-a
namespace: namespace-abc
annotations:
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
rules:
- http:
paths:
- path: /restservices/engine-rest/v1
backend:
serviceName: a
servicePort: 8080
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: ingress-b
namespace: namespace-abc
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: b
servicePort: 8011

How do I get traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip to work?

I have the following kubernetes manifest
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik-external
traefik.ingress.kubernetes.io/router.entrypoints: websecure, web
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
name: ingressname
namespace: thenamespace
spec:
rules:
- host: my.host
http:
paths:
- backend:
serviceName: theservice
servicePort: 8080
path: /api
Havin an service, theservice, that listens to / I would expect the url my.host/api/something/anotherthing match to /something/anotherthing in theservice. That doesn't happen for me though, I get a 404 back.
Any ideas what might be wrong?
During the transition from v1 to v2, a number of internal pieces and components of Traefik were rewritten and reorganized. As such, the combination of core notions such as frontends and backends has been replaced with the combination of routers, services, and middlewares.
With v2 transforming the URL path prefix of incoming requests is configured with middlewares object, after the routing step with router rule PathPrefix.
With v1 it is defined at ingress level:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: traefik
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
rules:
- host: company.org
http:
paths:
- path: /admin
backend:
serviceName: admin-svc
servicePort: admin
With v2 you have define also middleware object alongside ingress-route:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: http-redirect-ingressroute
namespace: admin-web
spec:
entryPoints:
- web
routes:
- match: Host(`company.org`) && PathPrefix(`/admin`)
kind: Rule
services:
- name: admin-svc
port: admin
middlewares:
- name: admin-stripprefix
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: admin-stripprefix
spec:
stripPrefix:
prefixes:
- /admin
More information can be found here:
Frontends and Backends Are Dead...
... Long Live Routers, Middlewares, and Services

Not able to access multiple services from ingress controller hosted on different ports

I have two services hosted on different ports and I have created a ingress resource which looks like this
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /svc1/
backend:
serviceName: app1-svc
servicePort: 3000
- path: /svc2/
backend:
serviceName: app2-svc
servicePort: 8080
on top of this I have created a NodePort type ingress controller.
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-ingress
name: controller-nginx-ingress-controller
spec:
clusterIP: 10.88.18.191
externalTrafficPolicy: Cluster
ports:
- name: http
nodePort: 30080
port: 80
protocol: TCP
targetPort: http
- name: https
nodePort: 31442
port: 443
protocol: TCP
targetPort: https
selector:
app: nginx-ingress
component: controller
release: controller
And finally, setup a cloud load balancer to access application running on my K8S cluster.
Problem:
I couldn't able to access any of my application using URL routing
http://load-balancer-ip/svc1/
http://load-balancer-ip/svc2/
Can anyone please let me know what incorrect I'm doing? And how to resolve this issue?
From what you mentioned in comments I am pretty sure the problem can be solved with path rewrites.
Now, when you are sending a request to /svc1/ with path: /svc1/ then the request is forwarded to app1-svc with path set to /svc1/ and you are receiving 404 errors as there is no such path in app1. From what you mentioned, you can most probably solve the issue using rewrite. You can achieve it using nginx.ingress.kubernetes.io/rewrite-target annotation, so your ingress would look like following:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress
namespace: mynamespace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- http:
paths:
- path: /svc1(/|$)(.*)
backend:
serviceName: app1-svc
servicePort: 3000
- path: /svc2(/|$)(.*)
backend:
serviceName: app2-svc
servicePort: 8080
In this case when sending request with path set to /svc1/something the request will be forwarded to app1 with path rewritten to /something.
Also take a look in ingress docs for more explanation.
Let me know if it solved you issue.