nginx-ingress add custom header for a specific path - nginx

I have the following nginx-ingress in a kubernetes environment
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "cache-control: no-store";
more_set_headers "MyCustomHeader: Value";
spec:
rules:
- http:
paths:
- backend:
serviceName: svc1
servicePort: 80
# Want to add the custom headers in this path only
path: /
- backend:
serviceName: svc2
servicePort: 80
path: /cacheable-path
I have a couple of headers that I want to set Cache-Control and MyCustomHeader. But I want these headers to be set only for the root path / and not for other routes (like /cacheable-path).
How to achieve this ? Adding the annotation causes the header to be appended to all the responses. I want the headers to be added to a specific path only.

It is not possible to add headers for a specific path in a single Ingress resource. You will have to create two Ingress resources.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
more_set_headers "cache-control: no-store";
more_set_headers "MyCustomHeader: Value";
spec:
rules:
- http:
paths:
- backend:
serviceName: svc1
servicePort: 80
path: /
Without header
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- backend:
serviceName: svc2
servicePort: 80
path: /cacheable-path

Related

set rate-limits for specific apis in kubernetes nginx

I am currently using nginx-ingress-controller in my eks-cluster.
I want to set rate-limits for only specific apis like /healthz like mentioned here and not only all my APIs.
Is there a way i can do it?
Thanks in advance
For separate specific you can make another ingress resource
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/limit-rps: "15"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress
name: ingress
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /healthz
While you can make one ingress resource for other API, without rate limit setup
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
labels:
name: ingress-2
name: ingress-2
spec:
rules:
- host: healthz.example.io
http:
paths:
- backend:
serviceName: hello
servicePort: 80
path: /data
- backend:
serviceName: hello
servicePort: 80
path: /api

How to add blocking IP rules on each nginx-ingress host

I have searched a lot and I didn't find the solution. I want to block/allow ip's into each host definition in the nginx-ingress, not per locations.
This is the ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: test1.test.com
#Blocking rules here, only affecting test1.test.com domain
http:
paths:
- path: /
backend:
serviceName: wordpressA
servicePort: 80
- host: test2.test.com
#Blocking rules here, only affecting test2.test.com domain
http:
paths:
- path: /
backend:
serviceName: wordpressB
servicePort: 80
Many thanks for your time
You need to split those host definitions into separate ingress rules.
Then you can use annotation to whitelist source range using following annotation :
nginx.ingress.kubernetes.io/whitelist-source-range
Something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app1-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/24"
spec:
rules:
- host: app1.com
http:
paths:
- path: /
backend:
serviceName: app1-service
servicePort: http
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: app2-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/24"
spec:
rules:
- host: app2.com
http:
paths:
- path: /
backend:
serviceName: app2-service
servicePort: http
You can also use server snipper and add nginx config to the yaml.
Something like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
location / {
# block one workstation
deny 192.168.1.1;
# allow anyone in 192.168.1.0/24
allow 192.168.1.0/24;
# drop rest of the world
deny all;
}

We hosted a website in AWS Kubernetes Service. niginx-ingress-path issue

We hosted a website in AWS Kubernetes Service. We are having following issue.
issue1.css not working
issue2:Redirection also not working
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: myapp1-alerts-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
tls:
- hosts:
- dev-api.myapp1.solutions
secretName: myapp1-alerts-tls
rules:
- host: dev-api.myapp1.solutions
http:
paths:
- path: /alerts
backend:
serviceName: myapp1-alerts
servicePort: 80
enter image description here
Take a look at the official documentation. There you will find an example below:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: rewrite.bar.com
http:
paths:
- backend:
serviceName: http-svc
servicePort: 80
path: /something(/|$)(.*)
| kubectl create -f -
In this ingress definition, any characters captured by (.*) will be
assigned to the placeholder $2, which is then used as a parameter in
the rewrite-target annotation.
For example, the ingress definition above will result in the following
rewrites:
rewrite.bar.com/something rewrites to rewrite.bar.com/
rewrite.bar.com/something/ rewrites to rewrite.bar.com/
rewrite.bar.com/something/new rewrites to rewrite.bar.com/new
Adjust your config accordingly and please let me know if that helped.

nginx ingress sub path redirection

I have an ingress controller and ingress resource running with all /devops mapped to devopsservice in the backend. When I try to hit "http://hostname/devops" things work and I get a page (although without CSS and styles) with a set of hyperlinks for e.g one of them is "logs".
When I click on the "logs" hyperlink, it is redirecting me to http://hostname/logs whereas I need it to be http://hostname/devops/logs.
Any idea what I can do?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
Looks like your ingress is not serving anything /devops/*. Try adding another path /devops/* with the same backend. Basically this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops/*
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
Update: the above has been deprecated in favor of something like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
If you access http://hostname/devops/logs directly from your browser, certainly you will get what you want. But since you click the hyperlink in the homepage, then you can only get http://hostname/logs, which will be certainly failed.
So, you need /logs backend configured in your ingress yaml to get it processed, and configure nginx.ingress.kubernetes.io/configuration-snippet to ensure /logs not get rewrote, like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/add-base-url : "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite ^/logs /logs break;
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /logs
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
I met the similar issue recently.
Assuming the "logs" hyperlink in your html uses a relative path, which means the hyperlink doesn't start with '/', then I think you can try to hit the page at http://hostname/devops/ instead of http://hostname/devops. (Note a / suffix in the first url.).
Then the "logs" hyperlink will be formed as http://hostname/devops/logs.
I think it's about how the browser identifies the 'base' url. With accessing 'http://hostname/devops/, if there is no 'base' tag in the html header, the 'base' url will be figured out to be http://hostname/devops; while with 'http://hostname/devops', the base url will be http://hostname.
If it's not the case, there is discussion at https://github.com/kubernetes/ingress-nginx/issues/4149. It's suggested a workaround to use the nginx directive subs_filter with a configuration-snippet to make the href attributes relative and also add the base tag in the html header.
The ingress used is as below,
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: rewrite
namespace: default
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops(/|$)(.*)
The nginx.ingress.kubernetes.io/x-forwarded-prefix annotation can be used for this purpose.
It adds x-forwarded-prefix header to http request with a value from this annotation. You can use it, if your backend support such header.
For example, Spring Boot application can handle it by using property:
server.forward-headers-strategy=framework
In your case ingress would look like the following:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: ingress-nginx
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/x-forwarded-prefix: /devops
spec:
rules:
- host: master1.dev.local
http:
paths:
- backend:
serviceName: devops1
servicePort: 10311
path: /devops
This solution has its downsides. It forces you to declare each service in separate ingress.

Rewrite path for nginx Ingress

I need to point Ingress to images so that my Pods gets the URL, in full. I have the below config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: solar-demo
annotations:
nginx.org/server-snippet: "proxy_ssl_verify off;"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: shmukler.example.com
http:
paths:
- path: /city/*
backend:
serviceName: solar-demo
servicePort: 3000
- path: /solar/*
backend:
serviceName: solar-demo
servicePort: 3001
If I keep the line: nginx.ingress.kubernetes.io/rewrite-target: /, my services inside the Pods get the rewritten paths, so /city/dublin becomes /dublin.
If I comment out the line nginx.ingress.kubernetes.io/rewrite-target: /, I just get 503 errors on the client side, and nothing in the logs. With rewrite, my services give me 404 because there is no route /dublin.
What am I doing wrong? How could I just pass the path on and have the Pods respond?
$ kubectl describe svc solar-demo
Name: solar-demo
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration=
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"solar-demo","namespace":"default"},"spec":{"ports":[{"name":"city","port":3000...
Selector: app=testapp
Type: ClusterIP
IP: 10.107.221.76
Port: city 3000/TCP
TargetPort: 3000/TCP
Endpoints: 172.17.0.3:3000,172.17.0.8:3000
Port: solar 3001/TCP
TargetPort: 3001/TCP
Endpoints: 172.17.0.3:3001,172.17.0.8:3001
Session Affinity: None
Events: <none>
Suggestions?
Here should be a working config:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: solar-demo
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: shmukler.example.com
http:
paths:
- path: /city
backend:
serviceName: solar-demo
servicePort: 3000
- path: /solar
backend:
serviceName: solar-demo
servicePort: 3001
What changed:
Removed * from paths
Specified ingress in the annotation
Removed re-write annotation
The path on an ingress (when using an nginx ingress) is like specifying the nginx location block. nginx does not use the * character in location blocks.

Resources