traefik ingress wildcard support - kubernetes

I am following traefik documentation (https://docs.traefik.io/routing/routers/), want to use PathPrefix matcher to match different paths with wildcard support, for example, to match path starting with api/v1, it should match
api/v1/customers,
api/v1alpha/customers,
api/v1beta/customers.
How to achieve it using wildcards in path syntax? Please find below my ingress yaml. I tried /api/{v1*}/customers but not working as expected.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
traefik.frontend.rule.type: PathPrefix
labels:
app: <app_name>
chart: <chart_name>
heritage: Tiller
release: <release_name>
name: <name>
namespace: default
spec:
rules:
- http:
paths:
- backend:
serviceName: <service_name>
servicePort: 443
path: /api/v1*/customers

I figured out how it works, posting here if someone wants to know. We can add regular expression in path
path: /api/{version:v1([a-z]*)}/customers

Related

Defining Ingress for k3s traefik

I am running k3s version 1.25.5 and I would like to define traefik as an ingress for one of the services defined through an external helm chart. I am struggling to find the right ingress definition. I tried with the below yaml file but that gives an error stating
error: resource mapping not found for name: "c8-ingress" namespace: "" from "zeebe-traefik.yaml": no matches for kind "Ingress" in version "extensions/v1beta1"
ensure CRDs are installed first
This seems to be because of the an old apiVersion used in the yaml file. How to do it the right way?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: c8-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
spec:
rules:
- http:
paths:
- path: "/"
backend:
serviceName: dev-zeebe-gateway
servicePort: 26500
Thanks.
Your example is using an outdated Ingress definition. In v1.25.x you need to use the stable networking.k8s.io/v1 API, as described here.
It is also recommended to provide the fitting namespace. This is useful for documentation, but also required for resource backends. It will also avoid adding -n YOURNAMESPACE to every kubectl apply.
In your case, this may look something like:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: c8-ingress
namespace: YOURNAMESPACE
spec:
rules:
- http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: dev-zeebe-gateway
port:
number: 26500
I hope this helps to solve your issue.
In many cases, you can run kubectl explain RESOURCE to get useful links and resources for a given api-resource.

How to make harbor reachable behind istio ingress?

I have installed Harbor as follows:
helm install hub harbor/harbor \
--version 1.3.2 \
--namespace tool \
--set expose.ingress.hosts.core=hub.service.example.io \
--set expose.ingress.annotations.'kubernetes\.io/ingress\.class'=istio \
--set expose.ingress.annotations.'cert-manager\.io/cluster-issuer'=letsencrypt-prod \
--set externalURL=https://hub.service.example.io \
--set notary.enabled=false \
--set secretkey=secret \
--set harborAdminPassword=pw
Everything is up and running but the page is not reachable via https://hub.service.example.io. The same problem occurs here Why css and png are not accessible? but how to set wildcard * in Helm?
Update
Istio supports ingress gateway. This for example works without Gateway and VirtualService definition:
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes-first
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 8080
selector:
app: hello-kubernetes-first
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes-first
spec:
replicas: 3
selector:
matchLabels:
app: hello-kubernetes-first
template:
metadata:
labels:
app: hello-kubernetes-first
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
env:
- name: MESSAGE
value: Hello from the first deployment!
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: istio
name: helloworld-ingress
spec:
rules:
- host: "hw.service.example.io"
http:
paths:
- path: "/*"
backend:
serviceName: hello-kubernetes-first
servicePort: 80
---
I would say it won't work with ingress and istio.
As mentioned here
Simple ingress specifications, with host, TLS, and exact path based matches will work out of the box without the need for route rules. However, note that the path used in the ingress resource should not have any . characters.
For example, the following ingress resource matches requests for the example.com host, with /helloworld as the URL.
$ kubectl create -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: simple-ingress
annotations:
kubernetes.io/ingress.class: istio
spec:
rules:
- host: example.com
http:
paths:
- path: /helloworld
backend:
serviceName: myservice
servicePort: grpc
EOF
However, the following rules will not work because they use regular expressions in the path and ingress.kubernetes.io annotations:
$ kubectl create -f - <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: this-will-not-work
annotations:
kubernetes.io/ingress.class: istio
# Ingress annotations other than ingress class will not be honored
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /hello(.*?)world/
backend:
serviceName: myservice
servicePort: grpc
EOF
I assume your hello-world is working because of just 1 annotation which is ingress class.
If you take a look at annotations of harbor here, it might be the problem when you want to use ingress with istio.
but how to set wildcard * in Helm?
Wildcard have nothing to do here. As I mentioned in this answer you can use either wildcard or additional paths, which is done well. Take a look at the ingress paths here.
https://github.com/goharbor/harbor-helm/blob/master/templates/ingress/ingress.yaml#L5
If you look here, they have the path hardcoded to a couple ingress options. Envoy/istio isn't one of them. However, you may be in luck- expose.ingress.controller set to "gce" seems to set the paths the way you need them to be. (I've never used gce, maybe they even use istio?)
Edit- original answer is below. Apparently there is an ingress controller you can enable in istio. There are absolutely no docs on it, but what should I expect?
In your case though, helm is not your problem. istio doesn't use ingress objects, it uses 'Gateways' and 'VirtualServices'. You can't configure an app to use the istio ingress system using kubernetes.io/ingress.class annotations.
(at least, that has been my experience, and I can't find anything to contradict that in their docs, but it is completely possible there is an istio ingress controller tha

When using a nginx kubernetes routing LoadBalancer with path redirects, why can I not access my service correctly?

I am using AKS with Helm v2.2 to try deploying a chart that utilizes an nginx LoadBalancer Pod to control all ingress into my services via a single ip address. This is very much in the experimental phase but I have proven that when I use the following Helm ingress configuration for my .net core webapi service:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
hosts:
- host:
paths:
- /
That I can indeed then visit my exposed api and see the swagger ui at
http://[My External IP]/index.html
what I then want to do is place several services behind the same LoadBalancer (as you are intended to) so my expectations were that I could then change the above service configuration to something like this:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
hosts:
- host:
paths:
- /serviceA
Which should then mean I can access the same service via the now updated url:
http://[My External IP]/serviceA/index.html
Is this what I should be expecting to work? Do I need to use any sort of re-write system as so far I get errors back from this url saying that it cannot find certain missing resources. Any attempts at using the re-write annotation have not resulted in helping me here either. Could someone help me out and point out what I may be doing wrong? With the new url path I end up with the following types of errors on what appears to be the files that the index.html page is trying to load suggesting it is half working but needs some re-writing or something?
Failed to load resource: the server responded with a status of 404 ()
As a result of the Helm chart template engine the following ingress yaml file is created:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: myrelease-release-manager
labels:
app.kubernetes.io/name: release-manager
helm.sh/chart: release-manager-0.1.0
app.kubernetes.io/instance: release-name
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /serviceA
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- host:
http:
paths:
- path: /serviceA
backend:
serviceName: myrelease-release-manager
servicePort: 80
As a result of this ingress file I want to visit this service when I go to my external ip address with the path /serviceA/index.html.
Close, you need to update the rewrite target to /$2
nginx.ingress.kubernetes.io/rewrite-target: /$2
Rewrites
/serviceB/foo -> /foo
/serviceA/foo -> /foo
But each one will be directed to the services for that path
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: myrelease-release-manager
labels:
app.kubernetes.io/name: release-manager
helm.sh/chart: release-manager-0.1.0
app.kubernetes.io/instance: release-name
app.kubernetes.io/version: "1.0"
app.kubernetes.io/managed-by: Tiller
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- backend:
serviceName: serviceB
servicePort: 80
path: /serviceB(/|$)(.*)
- backend:
serviceName: serviceA
servicePort: 80
path: /serviceA(/|$)(.*)

AKS: IP whitelisting (ingress)

I am trying to whitelist IP(s) on the ingress in the AKS. I am currently using the ingress-nginx not installed with Helm.
The mandatory kubernetes resources can be found here
The service is started as:
spec:
externalTrafficPolicy: Local
Full yaml here
My ingress definition is:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
# namespace: ingress-nginx
annotations:
ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/whitelist-source-range: "xxx.xxx.xxx.xxx"
spec:
rules:
- http:
paths:
- path: /xx-xx
backend:
serviceName: xx-xx
servicePort: 8080
- path: /xx
backend:
serviceName: /xx
servicePort: 5432
The IP whitelisting is not enforced. Am I doing something wrong ?
After a lot of digging around I found that the problem is because of this bug in NATing, defined here and there is quick medium read here.
Hope this solves problems for future readers or help track the bug

traefik ingress custom error in kubernetes

I need to set a custom error in traefik ingress on kubernetes so that when there is no endpoint or when the status is "404", or "[500-600]" it redirects to another error service or another custom error message I used the annotation as it's in the documentation in the ingress file as this (Note: this a helm template output of passing the annotation as a yaml in the values.yaml file)
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend
namespace: "default"
annotations:
external-dns.alpha.kubernetes.io/target: "domain.com"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/error-pages: "map[/:map[backend:hello-world status:[502 503]]]"
spec:
rules:
- host: frontend.domain.com
http:
paths:
- backend:
serviceName: frontend
servicePort: 3000
path: /
The answer by ldez is correct, but there are a few caveats:
First off, these annotations only work for traefik >= 1.6.x (earlier versions may support error pages, but not for the kubernetes backend)
Second, the traefik backend must be configured through kubernetes. You cannot create a backend in a config file and use it with kubernetes, at least not in traefik 1.6.x
Here's how the complete thing looks like. foo is just a name, as explained in the other answer, and can be anything:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend
namespace: "default"
annotations:
external-dns.alpha.kubernetes.io/target: "domain.com"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/error-pages: |-
foo:
status:
- "404"
- "500"
# See below on where "error-pages" comes from
backend: error-pages
query: "/{{status}}.html"
spec:
rules:
# This creates an ingress on an non-existing host name,
# which binds to a service. As part of this a traefik
# backend "error-pages" will be created, which is the one
# we use above
- host: error-pages
http:
paths:
- backend:
serviceName: error-pages-service
servicePort: https
- host: frontend.domain.com
http:
# The configuration for your "real" Ingress goes here
# This is the service to back the ingress defined above
# Note that you can use anything for this, including an internal app
# Also: If you use https, the cert on the other side has to be valid
---
kind: Service
apiVersion: v1
metadata:
name: error-pages-service
namespace: default
spec:
ports:
- name: https
port: 443
type: ExternalName
externalName: my-awesome-errors.mydomain.test
If you use this configuration, and your app sends a 404, then https://my-awesome-errors.mydomain.test/404.html would be shown as the error page.
The correct syntax is:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend
namespace: "default"
annotations:
external-dns.alpha.kubernetes.io/target: "domain.com"
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/error-pages: |-
foo:
status:
- "404"
backend: bar
query: /bar
fii:
status:
- "500-600"
backend: bar
query: /bir
spec:
rules:
- host: frontend.domain.com
http:
paths:
- backend:
serviceName: frontend
servicePort: 3000
path: /
https://docs.traefik.io/v1.6/configuration/backends/kubernetes/#general-annotations
Note that, currently, the Helm Charts doesn't support this feature.
Ingress does not support that annotations that you guys are using there!
That annotations are supported with Service only, Ingress is using host section.