PathPrefixStrip is ignored on ingress - kubernetes

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

Related

traefik ingress StripPrefix

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

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

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
...

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