How to get the k8s ingress wildcard in the host and put it on the url path - kubernetes

I use k8s to deploy my services.
I hope when I access the ingress host foo.example.com and the ingress forward it to server:8000/proxy/foo. The subdomain foo is dynamic and can be changed to any word. The expected result is as below:
foo.example.com -> server:8000/proxy/foo
bar.example.com -> server:8000/proxy/bar
......
I knew the ingress host could use wildcards and use ingress-nginx rewrite can rewrite the url path. I use the ingress-nginx controller. The ingress yaml file like as below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /proxy/${wildcard}/$1 # Could I use the host wildcard here?
name: nginx-forward
spec:
rules:
- host: *.example.com # I want to get the subdomain wildcard
http:
paths:
- backend:
service:
name: service
port:
number: 8080
path: /(.*)
pathType: Prefix
tls: # update this attribute
- hosts:
- *.example.com
secretName: my-secret
How could I use k8s ingress or other things to get what I want? Thanks.

You can use server snippet to get the subdomain:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/server-snippet: |
server_name ~^(?<subdomain>\w+)\.example\.com$;
nginx.ingress.kubernetes.io/rewrite-target: /proxy/$subdomain/$1
name: nginx-forward
spec:
rules:
- http:
paths:
- backend:
service:
name: service
port:
number: 8080
path: /(.*)
pathType: Prefix

Related

Only allow requests to certain paths using k8s ingress

I've set up an ingress to route traffic to my http server, however I would like to leave some routes inaccessible from outside of the cluster.
Example routes:
/status -> end point to determine service status
/users/names -> returns users
/users/ages -> returns ages
current ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: my-namespace
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: my-service
port:
number: 8080
this works currently but leaves all routes accessible. What I want to do is only have routes that fall under the /users path open, so that would be both /users/names and /users/ages. That would leave /status inaccessible from outside of the cluster. Is this achievable from changing the ingress configuration? Any help would be appreciated.
Just specify the path that you want to expose via the ingress like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: my-namespace
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: localhost
http:
paths:
- pathType: Prefix
path: /users # <- add the path here
backend:
service:
name: my-service
port:
number: 8080

How to disable tls for specific traefik ingress in kubernetes?

I am using traefik ingress controller in Kubernetes. It is configured to redirect all request to https and terminate tls connection before passing the request to backend service.
Is it possible to only enable http for one particular ingress config but https for other ingresses ? Any example would be helpful.
I only want to enable http(no https) for this ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- host: testdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 8080
You can create the one ingress with the config like
apiVersion: networking.k8s.io/v1
kind: Ingress
annotation:
kubernetes.io/ingress.class: "traefik"
ingress.kubernetes.io/force-ssl-redirect: "false"
ingress.kubernetes.io/ssl-redirect: "false"
traefik.ingress.kubernetes.io/frontend-entry-points: http
metadata:
name: test-ingress
spec:
rules:
- host: testdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 8080
you can get more idea about the annotation from here : https://doc.traefik.io/traefik/v1.6/configuration/backends/kubernetes/

Creating ingress resource

How do I create an ingress(ping) to expose a single service(hello) given a path (/hello )and a port (6789) in a given namespace (dev)?
the following is right? Also how to verify the same?
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ping
namespace: dev
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello
port:
number: 6789
You might need to add the host into the ingress YAML if you are looking forward to use the domain for resolution like
hello-world.info forward the traffic to hello service.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: hello-world.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
to verify the changes you can use the Curl to check and test the endpoint also.
Once your YAML file is applied and ingress is created on cluster you can hit the endpoint and verify.
i would recommend checking out the part test your ingress :
https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/#test-your-ingress

Is it possible to use same hostname with multiple Ingress resources running in different namespaces?

I want to use the same hostname let's say example.com with multiple Ingress resources running in different namespaces i.e monitoring and myapp. I'm using Kubernetes nginx-ingress controller.
haproxy-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: haproxy-ingress
namespace: myapp
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
tls:
- hosts:
# fill in host here
- example.com
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: haproxy
port:
number: 80
grafana-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
tls:
- hosts:
- example.com
rules:
- host: example.com
http:
paths:
# only match /grafana and paths under /grafana/
- path: /grafana(/|$)(.*)
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
When I'm doing curl example.com then it is redirecting me to the deployment running in namespace one(as expected) but when I'm doing curl example.com/grafana then still it is redirecting me to namespace one deployment.
Please help.
Yes it is possible.
There can be two issues in your case.
One is you don't need the regex path for grafana ingress. Simple /grafana path will be fine with path type Prefix as with path type Prefix any /grafana/... will be redirected associated service. So the manifest file will be:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana-ingress
namespace: monitoring
spec:
tls:
- hosts:
- example.com
rules:
- host: example.com
http:
paths:
- path: /grafana
pathType: Prefix
backend:
service:
name: grafana
port:
number: 3000
And the second issue can be the related service or deployment might not be the under same namespace monitoring. Please make sure the deployment/service/secret or other resources needed for grafana remains under the same namespace monitoring.

Kubernetes Ingress backend path with postfix

I can not understand how to achieve such a result as in nginx configuration:
location /api/ {
proxy_pass http://xyz:9000/api_server/;
}
but with ingress. If I understand correctly nginx.ingress.kubernetes.io/app-root is a redirection, but not proxying
Each ingress rule works already as a proxy_pass directive. So you can use the nginx.ingress.kubernetes.io/rewrite-target annotation in your case:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /api_server/$2
spec:
rules:
- http:
paths:
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: my-service-xyz
port:
number: 9000