Traefik ingressroute returns 404 not found - kubernetes

I'm using Traefik ingress controller. When I request to my domain https://harbor.domain.com/ it returns 404 not found. what's wrong with my ingressroute?
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: harbor
namespace: harbor
spec:
entryPoints:
- web
- websecure
routes:
- kind: Rule
match: Host(`harbor.domain.com`) && (PathPrefix(`/api`) || PathPrefix(`/service`) || PathPrefix(`/v2`) || PathPrefix(`/chartrepo`) || PathPrefix(`/c`))
services:
- kind: Service
name: harbor-portal
namespace: harbor
port: 80
scheme: https
- kind: Rule
match: Host(`notary.domain.com`)
services:
- kind: Service
name: harbor-notary-server
namespace: harbor
port: 4443
scheme: https
tls:
secretName: harbor.domain.com
Secret file exists and created by cluster issuer.
these are my services in harbor namespace:

Related

Path or PathPrefix routing with Traefik on Kubernetes not working

I'm using Traefik 2.7.0 on an AKS Kubernetes Cluster 1.22.6.
Currently, everything routes to the same service:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`)
kind: Rule
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-my-domain-com-cert
I'm currently in the process of externalizing an API resource from this service to a dedicated new service ("/users") because there will be other services in the future that will need the same functionality.
What I'm trying (and failing) to do, is to route calls to "/users" to the new service:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`) && Path(`/users`)
kind: Rule
services:
- name: users-api
namespace: namespace2
port: 80
- match: Host(`api.my-domain.com`)
kind: Rule
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-baywa-lusy-com-cert
I tried Path(..) and PathPrefix(..). No success. Everything is still routed to the old service. The new service has slightly different output. So I can tell with certainty that it's still routed to the old service.
Adding the priority manually didn't help either:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`) && Path(`/users`)
kind: Rule
priority: 2000
services:
- name: users-api
namespace: namespace2
port: 80
- match: Host(`api.my-domain.com`)
kind: Rule
priority: 1000
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-baywa-lusy-com-cert
Am I Missing something here? Any help is appreciated!
Thanks,
best regards,
Pascal
You can only expose services in the same namespace as your IngressRoute resource. If you watch the logs of your Traefik pod when you deploy your IngressRoute, you should see something like:
time="2023-01-26T13:57:17Z" level=error msg="service namespace2/users-api not in the parent resource namespace namespace1" providerName=kubernetescrd ingress=namespace1 namespace=namespace1
To do what you want, you need to create two separate IngressRoute resources, one in namespace1 and one in namespace2.
In namespace1:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: old-api
name: old-api
namespace: namespace1
spec:
entryPoints:
- web
routes:
- kind: Rule
priority: 1000
match: Host(`api.my-domain.com`)
services:
- name: old-api
port: 80
In namespace2:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: new-api
name: new-api
namespace: namespace2
spec:
entryPoints:
- web
routes:
- kind: Rule
priority: 2000
match: Host(`api.my-domain.com`) && PathPrefix(`/users`)
services:
- name: new-api
port: 80
You can find all the files I used to test this configuration here.
I don't know if the explicit priorities are necessary or not; it worked for me without them but maybe I was just lucky so I left them there. I would generally assume that a "more specific route" takes precedence over a "less specific route", but I don't know if that's actually true.

How to configure tls with traefik in kubernetes using yaml?

I am having trouble exposing a service over http and https using traefik 2.9 in Kubernetes.
The http endpoint kinda works, I introduced CORS errors somehow once I tried to add https but that is not my main concern. The https ingress is broken and I cant find any indication of why its not working. The traefik pod doesn't log any errors and the dotnet service isn't receiving the requests. Also both routes show up in the dashboard and websecure is displayed as having TLS enabled.
Excluding ClusterRole, ServiceAccount, and ClusterRoleBinding because I believe that's configured correctly as the http route wouldn't work if it wasnt.
Traefik config:
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-deployment
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
containers:
- name: traefik
image: traefik:v2.9
args:
- --api.insecure
- --providers.kubernetesingress
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls
ports:
- name: web
containerPort: 80
- name: dashboard
containerPort: 8080
- name: websecure
containerPort: 443
Traefik services:
apiVersion: v1
kind: Service
metadata:
name: traefik-dashboard-service
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: dashboard
selector:
app: traefik
---
apiVersion: v1
kind: Service
metadata:
name: traefik-web-service
spec:
type: LoadBalancer
loadBalancerIP: 10.10.1.38
ports:
- targetPort: web
port: 80
name: http
- targetPort: websecure
port: 443
name: https
selector:
app: traefik
Secret for tls:
apiVersion: v1
data:
comptech.pem: <contents of pem file base64 encoded>
comptech.crt: <contents of crt file base64 encoded>
comptech.key: <contents of key file base64 encoded>
kind: Secret
metadata:
name: comptech-cert
namespace: default
type: Opaque
Service for dotnet application:
apiVersion: v1
kind: Service
metadata:
name: control-api-service
spec:
ports:
- name: http
port: 80
targetPort: 5000
protocol: TCP
- name: https
port: 443
targetPort: 5000
protocol: TCP
selector:
app: control-api
Ingresses:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: control-api-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: web
spec:
rules:
- host: sub.domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: control-api-service
port:
name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: control-api-secure-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
rules:
- host: sub.domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: control-api-service
port:
name: https
tls:
- secretName: comptech-cert
My hope here is that someone with much more experience with traefik/tls will be able to quickly realize what I'm doing incorrectly. Any input is greatly appreciated!
UPDATE:
The firewall was only allowing http traffic, we reconfigured it to support https and it is responding with Traefiks default certs. So i can hit the container but tls is still not configured using my supplied cert.
The pem file is not needed and the crt file was generated incorrectly using openssl the command that worked for me was: openssl crl2pkcs7 -nocrl -certfile comptech.pem | openssl pkcs7 -print_certs -out cert.crt
Pointing to the https port of the control-api-service was not working and needed to be changed to http
A config map needed to be created for the traefik deployment to work correctly:
apiVersion: v1 kind: ConfigMap metadata: name: traefik-config labels:
name: traefik-config namespace: default data: dyn.yaml: |
# https://doc.traefik.io/traefik/https/tls/
tls:
stores:
default:
defaultCertificate:
certFile: '/certs/tls.crt'
keyFile: '/certs/tls.key'
Finally the configmap and secret must be used in the traefik deployment like below:
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik-deployment
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-account
containers:
- name: traefik
image: traefik:v2.9
args:
- --api.insecure
- --providers.kubernetesingress
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls
- --providers.file.filename=/config/dyn.yaml
ports:
- name: web
containerPort: 80
- name: dashboard
containerPort: 8080
- name: websecure
containerPort: 443
volumeMounts:
- name: comptech-cert-volume
mountPath: /certs
- name: traefik-config-volume
mountPath: /config
volumes:
- name: comptech-cert-volume
secret:
secretName: comptech-cert
- name: traefik-config-volume
configMap:
name: traefik-config
In my setup, I use the IngressRoute CRD implementation from Traefik.
The CRDs were automatically installed when I setup the Traefik controller using Helm.
Is it a possibility for you to use this in your setup? You can check if the CRDs already exist using below command on your k8s cluster.
kubectl get crd
Below is a snippet from one of my projects where I also use a custom wildcard certificate from a secret using the IngressRoute manifest.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: blue-api-ingressroute
spec:
entryPoints:
- websecure
routes:
- match: "Host(`blue.domain.com`)" && PathPrefix(`/swagger`)"
kind: Rule
services:
- name: blue-api-svc
port: 80
tls:
secretName: bluecert
You can also include other custom resources that are available from Traefik. The complete set of configuration that is available can be seen here. For example, below is the same snippet with middleware and tlsoptions resources included for improving the security of the endpoint.
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: tlsoptions
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_AES_256_GCM_SHA384
- TLS_AES_128_GCM_SHA256
- TLS_CHACHA20_POLY1305_SHA256
- TLS_FALLBACK_SCSV
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: security
spec:
headers:
frameDeny: true
sslRedirect: true
browserXssFilter: true
contentTypeNosniff: true
stsIncludeSubdomains: true
stsPreload: true
stsSeconds: 31536000
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: blue-api-ingressroute
spec:
entryPoints:
- websecure
routes:
- match: "Host(`blue.domain.com`)" && PathPrefix(`/swagger`)"
kind: Rule
services:
- name: blue-api-svc
port: 80
middlewares:
- name: security
tls:
secretName: bluecert
options:
name: tlsoptions

traefik ingressroute - URL should redirect to a default path

kubernetes ingress rules, AWS ALB rule has default path rule if no path is provided in the URL.
I couldn't figure out similar config in Traefik ingressroute.
Right now - https://example.com goes to the default wildfly page.
https://example.com/foo goes to the app login page.
How do I configure so that https://example.com would directly go to https://example.com/foo
Ingressroute:
spec:
entryPoints:
- web
- websecure
routes:
- kind: Rule
match: Host(`example.com`) && PathPrefix(`/`)
middlewares:
- name: https-redirect
namespace: ns
services:
- name: service-1
port: 80
Another ingressroute:
spec:
entryPoints:
- web
routes:
- match: Host(`example.com`)
kind: Rule
middlewares:
- name: https-redirect
services:
- name: service-1
port: 80
Middleware:
kind: Middleware
metadata:
name: https-redirect
spec:
redirectScheme:
scheme: https
permanent: true
According to Traefik docs, you can create a typical defaultBackend Kubernetes Ingress like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cheese
spec:
defaultBackend:
service:
name: stilton
port:
number: 80
You can then set priority for this Ingress to ensure it matches the right type of requests, as traefik.ingress.kubernetes.io/router.priority annotation. You can read more about this here.

Why does Traefik v2 response 404 only over http

My problem is that my traefik ingress controller in my kubernetes cluster does response 404 page not found over http, BUT over https I get the real response from the service.
This happened after I added the TLS section to IngressRoute.
This is my IngressRoute:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: example-backend
namespace: example
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`api.example.com`)
kind: Rule
priority: 10
services:
- name: example-backend-service
port: 80
tls:
secretName: tls-secret # I'm using my own certificate, not Let's Encrypt
Why I don't get the real/same response like https does?
As the TLS applies on a router, you cannot have only one IngressRoute to handle the 2 cases.
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: example-backend
namespace: example
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.example.com`)
kind: Rule
priority: 10
services:
- name: example-backend-service
port: 80
tls:
secretName: tls-secret
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: example-backend-redirect
namespace: example
spec:
entryPoints:
- web
routes:
- match: Host(`api.example.com`)
kind: Rule
priority: 10
services:
# in this IngressRoute the service will be never called
# because of the redirect middleware.
- name: example-backend-service
port: 80
middlewares:
- name: https_redirect
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https_redirect
spec:
redirectScheme:
scheme: https
permanent: true

Traefik 2 http to https redirect with tls not working

I want to set up http to https redirect in one IngressRoute, but with configuration below when I trying to access http endpoint traefik returns 404 not found error. If I remove tls section redirect works but tls not.
Can I have both working?
traefik version 2.1.0-rc2
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: console-web
namespace: dev
labels:
app: console-web
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`console.example.com`)
kind: Rule
services:
- name: console-web
port: 8080
middlewares:
- name: https-redirect
tls:
secretName: example-com-tls
This is an old issue however this might help someone. This might not directly work as i have not tested it. For kubernetes it should work in following way first you define how the middleware works
Untested Code
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: test-redirectscheme
spec:
redirectScheme:
scheme: https
Then define the IngressRoute
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingress1
namespace: default
spec:
entryPoints:
- websecure
routes:
- match: Host(`somehost`)
kind: Rule
services:
- name: console-web
port: 8080
tls:
secretName: example-com-tls
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingress2
namespace: default
spec:
entryPoints:
- web
routes:
- match: Host(`somehost`)
middlewares:
- name: test-redirectscheme
kind: Rule
services:
- name: console-web
port: 80
two ingress needed as one is redirecting the trafic to other. I also suppose if you dont have two ports you can reuse the previous one as it is going to be redirected to https anyway. Let me know if it does not does not work.
after spending hours on this for docker on this 404 issue for the http endpoint i found this https://stackoverflow.com/a/62093408/2442649