Traefik V2: Why requests to subfolders are not routed properly? - kubernetes-ingress

I try to migrate from Traefik V1 to V2 without the IngressRoute or Middleware.
my requests to /backend/something should be routed to the root of my backend service with /something.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/redirect-regex: /backend$
traefik.ingress.kubernetes.io/redirect-replacement: /backend/
traefik.ingress.kubernetes.io/request-modifier: "ReplacePathRegex: ^/backend/(.*) /$1"
spec:
rules:
- host: demo.myapp.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
serviceName: frontend-app
servicePort: 80
- path: /backend # requests to /backend/something should end up in /something
pathType: ImplementationSpecific
backend:
service:
name: backend-api
port: http
How can I strip that?
At the moment requests to
/backend/something ends up in backend/something/ but should be /something
Thank you in advance
PS: is there a "tool" to monitor or test such requests?
This is a demo deployment I work with:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-app
namespace: default
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
name: http
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
selector:
app: nginx
type: ClusterIP
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
namespace: default
labels:
app: hello-world
spec:
selector:
matchLabels:
app: hello-world
replicas: 1
template:
metadata:
labels:
app: hello-world
spec:
containers:
- name: hello-world
image: rancher/hello-world:latest
resources: {}
ports:
- containerPort: 80
name: http
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: hello-world
namespace: default
spec:
selector:
app: hello-world
type: ClusterIP
sessionAffinity: None
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-ingress
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/router.entrypoints: web, websecure
# usage: namespace-middlewareName#kubernetescrdIsMandatory
traefik.ingress.kubernetes.io/router.middlewares: production-middleware-frontend#kubernetescrd,production-middleware-backend#kubernetescrd
traefik.ingress.kubernetes.io/router.tls: "true"
# cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend
port:
number: 5000
- path: /backend
pathType: ImplementationSpecific
backend:
service:
name: backend
port:
number: 3000
tls:
- hosts:
- "yourdomain.com"
secretName: yourdomain-com-production-tls
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: middleware-backend
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
spec:
stripPrefix:
prefixes:
- /backend
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: middleware-frontend
namespace: production
annotations:
kubernetes.io/ingress.class: traefik
spec:
stripPrefix:
prefixes:
- /

Related

GCE LB not picking up readinessProbe URL

I updated readiness probe in my deployment file and also specify port in ingress, service and deployment.
But my GCE Load Balancer health check is not reflecting the correct path (even I delete and recreate ingress).
Am I missing any configuration?
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: custom-app-managed-cert
spec:
domains:
- uat.xyz.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: "gce"
kubernetes.io/ingress.global-static-ip-name: app-gce-uat-ip
networking.gke.io/managed-certificates: custom-app-uat-managed-cert
spec:
rules:
- host: "uat.xyz.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: custom-app
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: custom-app
spec:
type: LoadBalancer
selector:
app: custom-app
ports:
- port: 80
targetPort: 80
type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: custom-app-gke
spec:
replicas: 1
selector:
matchLabels:
app: custom-app
template:
metadata:
labels:
app: custom-app
spec:
serviceAccountName: app-svc
containers:
- name: custom-app-app
image: xxx
imagePullPolicy: Always
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /health
port: 80
env:
- name: PORT
value: "80"
---

K3S: Can't access my web. is there any problem in my yaml files?

I deploy my web service on K3S. I use DuckDNS to access https. i can access my domain with https. But i can't access my web service specific URL.
Here is my yaml files
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: auto-trade-api
spec:
replicas: 1
selector:
matchLabels:
app: auto-trade-api
template:
metadata:
labels:
app: auto-trade-api
spec:
containers:
- name: auto-trade-api
image: image
args: ['yarn', 'start']
resources:
requests:
cpu: '200m'
memory: '200Mi'
limits:
cpu: '200m'
memory: '200Mi'
envFrom:
- secretRef:
name: auto-trade-api
ports:
- containerPort: 3001
restartPolicy: Always
imagePullSecrets:
- name: regcred
Service
kind: Service
metadata:
name: auto-trade-api
spec:
type: "NodePort"
selector:
app: auto-trade-api
ports:
- protocol: TCP
port: 3001
targetPort: 3001
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: auto-trade-api
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "traefik"
cert-manager.io/cluster-issuer: "letsencrypt"
spec:
tls:
- hosts:
- mydomain
secretName: auto-trade-api-tls
rules:
- host: mydomain
http:
paths:
- path: /*
pathType: Prefix
backend:
service:
name: auto-trade-api
port:
number: 3001
i tried access https://mydomain/users that i made. but only display 404 page not found
I think i did connect each component well.

AWS EKS service ingress and ALB --no ADDRESS

I seem to be having an issue with the way my ports are setup on this manifest, which is a simple go app. The app is configured to listen on port 3000.
This container runs fine on my local machine (localhost:3000), but I get no ADDRESS when I look at the Ingress (k get ingress ...).
I am getting an error logged in the AWS aws-load-balancer-controller log when I try to run this image on EKS:
controller-runtime.manager.controller.ingress","msg":"Reconciler error","name":"fiber-demo","namespace":"demo","error":"ingress: demo/fiber-demo: unable to find port 3000 on service demo/fiber-demo"
This is my k8s manifest:
apiVersion: apps/v1
kind: Deployment
metadata:
name: fiber-demo
namespace: demo
labels:
app: fiber-demo
spec:
replicas: 1
selector:
matchLabels:
app: fiber-demo
template:
metadata:
labels:
app: fiber-demo
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
- arm64
containers:
- name: fiber-demo
image: 240195868935.dkr.ecr.us-east-2.amazonaws.com/fiber-demo:0.0.2
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: fiber-demo
namespace: demo
labels:
app: fiber-demo
spec:
selector:
app: fiber-demo
ports:
- protocol: TCP
port: 80
targetPort: 3000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: fiber-demo
namespace: demo
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
labels:
app: fiber-demo
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: fiber-demo
servicePort: 3000
Am I simply not able to specify a targetPort other than port 80 in the Service?
Am I simply not able to specify a targetPort other than port 80 in the Service?
backend.servicePort refers to port exposed by service, not container.
...
backend:
serviceName: fiber-demo # <-- ingress for this service, not container
servicePort: 80 # <-- port which the service exposed, not the port which the container exposed.

Problem with ALB Ingress Controller in redirecting to right path

I have done the setup of ALB (Application Load Balancer) using Ingress Controller (version -> docker.io/amazon/aws-alb-ingress-controller:v1.1.8) for my AWS EKS cluster (v 1.20) running with Fargate profile.
I can access my service using the load balancer link:-
http://5e07dbe1-default-nginxingr-29e9-1260427999.us-east-1.elb.amazonaws.com/
I have 2 different services configured in my Ingress as shown below:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "nginx-ingress"
namespace: "default"
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/security-groups: sg-014b302d73097d083
# alb.ingress.kubernetes.io/actions.ssl-redirect: '{"Type": "redirect", "RedirectConfig": { "Protocol": "HTTPS", "Port": "443", "StatusCode": "HTTP_301"}}'
# alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-east-1:195725532069:certificate/b6a9e691-b807-4f10-a0bf-0449730ecdf4
# alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
# alb.ingress.kubernetes.io/backend-protocol: HTTPS
#alb.ingress.kubernetes.io/load-balancer-attributes: "60"
#alb.ingress.kubernetes.io/rewrite-target: /
labels:
app: nginx-ingress
spec:
rules:
- http:
paths:
# - path: /*
# pathType: Prefix
# backend:
# service:
# name: ssl-redirect
# port:
# number: use-annotation
- path: /foo
pathType: Prefix
backend:
service:
name: "nginx-service"
port:
number: 80
- path: /*
pathType: Prefix
backend:
service:
name: "mydocker-svc"
port:
number: 8080
Now the problem is if I put /foo at the end of LB link then nothing happens and I get 404 not found error:-
Both my services are fine with respective Pods running behind their respective Kubernetes NodePort services but they are not accessible using the Ingress. If I swap the path to /* from /foo for the other service (nginx-service), I can then access that but then it will break my previous service (mydocker-svc).
Please let me know where I'm the mistake so that I can fix this issue. Thank you
ALB Controller:-
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
name: alb-ingress-controller
namespace: kube-system
spec:
selector:
matchLabels:
app.kubernetes.io/name: alb-ingress-controller
template:
metadata:
labels:
app.kubernetes.io/name: alb-ingress-controller
spec:
containers:
- name: alb-ingress-controller
args:
- --ingress-class=alb
- --cluster-name=eks-fargate-alb-demo
- --aws-vpc-id=vpc-0dc46d370e38de475
- --aws-region=us-east-1
image: docker.io/amazon/aws-alb-ingress-controller:v1.1.8
serviceAccountName: alb-ingress-controller
Nginx service:-
apiVersion: v1
kind: Service
metadata:
annotations:
alb.ingress.kubernetes.io/target-type: ip
name: "nginx-service"
namespace: "default"
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
type: NodePort
selector:
app: "nginx"
mydocker-svc:-
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
eks.amazonaws.com/fargate-profile: fp-default
run: mydocker
name: mydocker-svc
annotations:
alb.ingress.kubernetes.io/target-type: ip
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
eks.amazonaws.com/fargate-profile: fp-default
run: mydocker
type: NodePort
status:
loadBalancer: {}
TargetGroups become unhealthy, if the annotation in Kubernetes NodePort service like alb.ingress.kubernetes.io/target-type: IP is missing:-
You can try this out one i am using as reference
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-usermgmt-restapp-service
labels:
app: usermgmt-restapp
annotations:
# Ingress Core Settings
kubernetes.io/ingress.class: "alb"
alb.ingress.kubernetes.io/scheme: internet-facing
# Health Check Settings
alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
alb.ingress.kubernetes.io/healthcheck-port: traffic-port
#Important Note: Need to add health check path annotations in service level if we are planning to use multiple targets in a load balancer
#alb.ingress.kubernetes.io/healthcheck-path: /usermgmt/health-status
alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
alb.ingress.kubernetes.io/success-codes: '200'
alb.ingress.kubernetes.io/healthy-threshold-count: '2'
alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
spec:
rules:
- http:
paths:
- path: /app1/*
backend:
serviceName: app1-nginx-nodeport-service
servicePort: 80
- path: /app2/*
backend:
serviceName: app2-nginx-nodeport-service
servicePort: 80
- path: /*
backend:
serviceName: usermgmt-restapp-nodeport-service
servicePort: 8095
Read more at : https://www.stacksimplify.com/aws-eks/aws-alb-ingress/kubernetes-aws-alb-ingress-context-path-based-routing/

Reference nginx-ingress host name to internal service

After creating all require resource and config the nginx-ingress controller.
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-api
spec:
replicas: 1
selector:
matchLabels:
app: user-api
strategy: {}
template:
metadata:
labels:
app: user-api
spec:
dnsPolicy: ClusterFirstWithHostNet
hostNetwork: true
containers:
- name: user-api
image: doumeyi/user-api-amd64:1.0
ports:
- name: user-api
containerPort: 3000
resources: {}
---
apiVersion: v1
kind: Service
metadata:
name: user-api
spec:
selector:
app: user-api
ports:
- name: user-api
port: 3000
targetPort: 3000
type: LoadBalancer
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /user-api
backend:
serviceName: user-api
servicePort: 3000
I can view example.com show the 404 not found page, but also can not see example.com/user-api to show any message I build in user-api service.
It seems the nginx-ingress cannot resolve the host name to the internal service, how should I fix it?
If NGINX cannot find a route to your Pod, it should not respond with 404. Instead it should give an 502 (Bad Gateway) AFAIK. I assume the 404 is from your application.
NGINX-Ingress changed behavior in 0.22 as mentioned here
The ingress resource should look like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: example.com
http:
paths:
- path: /user-api(/|$)(.*)
backend:
serviceName: user-api