traefik ingress StripPrefix - kubernetes

Using traefik as the ingress controller and looking for a way to stripping path prefixing. as these prefixed path section is "forwarded" to the service unless the service is also listening on a same path, the service will hit a 404. it was not very clear on the docs how to remove the forwarded paths, any pointers?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: azure-vote-route
namespace: azure-vote
spec:
rules:
- host: <>.<>.cloudapp.azure.com
http:
paths:
# - path: /
# pathType: Prefix
# backend:
# service:
# name: azure-vote-front
# port:
# number: 80
- path: /foo
pathType: Prefix
backend:
service:
name: azure-vote-front
port:
number: 80

found the answers
option 1
kind: Ingress
and using a Middleware from traefik to strip the prefix. and this middleware is refereed using an annotation on the Ingress definition
<namespace-of-middlewear>-<name-of-middlewear>
eg
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: ingress-stripprefix
namespace: azure-vote
spec:
stripPrefix:
prefixes:
- /foo
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-a
namespace: azure-vote
annotations:
traefik.ingress.kubernetes.io/router.middlewares: azure-vote-ingress-stripprefix#kubernetescrd
spec:
rules:
- host: <>.<>.cloudapp.azure.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: azure-vote-front
port:
number: 80
option 2
kind: IngressRoute (which is a traefik specific ingress implementation.)
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroute-middle
namespace: azure-vote
spec:
entryPoints:
- web
routes:
- match: Host(`<>.cloudapp.azure.com`) && PathPrefix(`/test`)
kind: Rule
services:
- name: azure-vote-front
port: 80
middlewares:
- name: testmiddle
- match: Host(`<>.cloudapp.azure.com`)
kind: Rule
services:
- name: azure-vote-front
port: 80
middlewares:
- name: testmiddle
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: testmiddle
namespace: azure-vote
spec:
stripPrefix:
prefixes:
- /test

Related

How to strip the path prefix in Kubernetes Traefik ingress?

I'm using k3s v1.22.7 on Ubuntu 20.04. I want /bar/xyz to be /xyz to the pods. Without the middleware I'm properly routed to the pods, with it I get 404 from Traefik as though the stripping from replacePathRegex/stripPrefix happens before the Ingress path evaluation. Examples online all have it like that though...
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-prefix
spec:
#replacePathRegex:
# regex: ^/(?:[^/]+)/(.*)
# replacement: /$1
stripPrefix:
prefixes:
- /bar
- /baz
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: foo-ingress
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.middlewares: strip-prefix#kubernetescrd
spec:
rules:
- host: example.org
http:
paths:
- path: /bar
pathType: Prefix
backend:
service:
name: foo-service
port:
number: 5001
- path: /baz
pathType: Prefix
backend:
service:
name: foo-service
port:
number: 5002
Looks like the middleware needs the namespace prefixed, so either
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-prefix
# No namespace defined
spec:
stripPrefixRegex:
regex:
- ^/[^/]+
---
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: default-strip-prefix#kubernetescrd
or
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: strip-prefix
namespace: example # Namespace defined
spec:
stripPrefixRegex:
regex:
- ^/[^/]+
---
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: example-strip-prefix#kubernetescrd
should work.
(Source)

not able to create the rule for the ingress controller

What am I going wrong in the below query?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
serviceName: nginx
servicePort: 80
The error I am getting:
error validating "ingress.yaml": error validating data: [ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "serviceName" in io.k8s.api.networking.v1.IngressBackend, ValidationError(Ingress.spec.rules[0].http.paths[0].backend): unknown field "servicePort" in io.k8s.api.networking.v1.IngressBackend]; if you choose to ignore these errors, turn validation off with
--validate=false
Ingress spec has changed since updated to v1. Try:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
pathType: ImplementationSpecific
backend:
service:
name: nginx
port:
number: 80
According to this documentation you need to change ServiceName and ServicePort.
Each HTTP rule contains (...) a list of paths (for example, /testpath), each of which has an associated backend defined with a service.name and a service.port.name or service.port.number. Both the host and path must match the content of an incoming request before the load balancer directs traffic to the referenced Service.
Here is your yaml file with corrections:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
service:
name: nginx
port:
number: 8080
ServiceName and ServicePort no keywords are available like that in v1 .
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /nginx
backend:
service:
name: nginx
port:
number: 8080
service name and service port syntax is incorrect. Follow the below sample
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80

PathPrefixStrip is ignored on ingress

Traefik version 2.5.6
I have the following ingress settings:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/app-root: /users
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
name: users
spec:
rules:
- host: dev.[REDUCTED]
http:
paths:
- backend:
service:
name: users-service
port:
number: 80
path: /users
pathType: Prefix
But when I call:
curl -i http://dev.[REDUCTED]/users/THIS-SHOUD-BE-ROOT
I get in the pod, serving the service:
error: GET /users/THIS-SHOUD-BE-ROOT 404
What can be the reason for that?
Try to use Traefik Routers as in the example below:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: users
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`dev.[REDUCTED]`) && PathPrefix(`/users`)
kind: Rule
services:
- name: users-service
port: 80

How to fix the 404 not found error when to expose service through ingress

I want to expose the web service through ingress with hostNetwork setting to true, but when I try to reach the www.example.com/example-apiapi, the response always return 404 not found error code for me.
--- Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
tls:
- hosts:
- www.example.com
secretName: example-tls
rules:
- host: www.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
number: 3000
--- service
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example
ports:
- name: example-api
port: 3000
targetPort: example-api # 3000
This is because I have not defined the nginx class for ingress.
--- Ingress
...
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
name: example-ingress
...

Kubernetes routing to specific pod in function of a param in url

The need I have just looks like this stuff :
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
name: http
spec:
serviceName: "nginx-set"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: http
----
apiVersion: v1
kind: Service
metadata:
name: nginx-set
labels:
app: nginx
spec:
ports:
- port: 80
name: http
clusterIP: None
selector:
app: nginx
Here is the interesting part :
apiVersion: voyager.appscode.com/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: default
spec:
rules:
- host: appscode.example.com
http:
paths:
- path: '/testPath'
backend:
hostNames:
- web-0
serviceName: nginx-set #! There is no extra service. This
servicePort: '80' # is the Statefulset's Headless Service
I'm able to target a specific pod because of setting the hostName in function of the url.
Now I'd like to know if it's possible in kubernetes to create a rule like that
apiVersion: voyager.appscode.com/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: default
spec:
rules:
- host: appscode.example.com
http:
paths:
- path: '/connect/(\d+)'
backend:
hostNames:
- web-(result of regex match with \d+)
serviceName: nginx-set #! There is no extra service. This
servicePort: '80' # is the Statefulset's Headless Service
or if I have to wrote a rule for each pod ?
Sorry that isn't possible, the best solution is to create multiple paths, each one referencing one pod:
apiVersion: voyager.appscode.com/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: default
spec:
rules:
- host: appscode.example.com
http:
paths:
- path: '/connect/0'
backend:
hostNames:
- web-0
serviceName: nginx-set
servicePort: '80'
- path: '/connect/1'
backend:
hostNames:
- web-1
serviceName: nginx-set
servicePort: '80'