can ingress rewrite 405 to the origin url and change the http-errors 405 to 200? - kubernetes

Can ingress rewrite 405 to the origin url and change the http-errors 405 to 200?
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- http:
paths:
- path: /page/user/(.*)
pathType: Prefix
backend:
serviceName: front-user
servicePort: 80
- path: /page/manager/(.*)
pathType: Prefix
backend:
serviceName: front-admin
servicePort: 80
Ngnix can realize that visit a html page by a post method but I want to know how to realize by ingress.
server {
listen 80;
# ...
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://static_backend;
}
}
This is an e.g. that ngnix realize that visit a html page by a post method to change 405 to 200 and change the method to get

You can use server snippet annotation to achieve it.
Also I rewrote your ingress from extensions/v1beta1 apiVersion to networking.k8s.io/v1, because starting kubernetes v1.22 previous apiVersion is be removed:
$ kubectl apply -f ingress-snippit.yaml
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Ingress-snippet-v1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: frontend-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
nginx.ingress.kubernetes.io/server-snippet: | # adds this block to server
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://static_backend; # tested with IP since I don't have this upstream
}
spec:
rules:
- http:
paths:
- path: /page/user/(.*)
pathType: Prefix
backend:
service:
name: front-user
port:
number: 80
- path: /page/manager/(.*)
pathType: Prefix
backend:
service:
name: front-admin
port:
number: 80
Applying manifest above and verifying /etc/nginx/nginx.conf in ingress-nginx-controller pod:
$ kubectl exec -it ingress-nginx-controller-xxxxxxxxx-yyyy -n ingress-nginx -- cat /etc/nginx/nginx.conf | less
...
## start server _
server {
server_name _ ;
listen 80 default_server reuseport backlog=4096 ;
listen 443 default_server reuseport backlog=4096 ssl http2 ;
set $proxy_upstream_name "-";
ssl_certificate_by_lua_block {
certificate.call()
}
# Custom code snippet configured for host _
error_page 405 =200 #405;
location #405 {
root /srv/http;
proxy_method GET;
proxy_pass http://127.0.0.1; # IP for testing purposes
}
location ~* "^/page/manager/(.*)" {
set $namespace "default";
set $ingress_name "frontend-ingress";
set $service_name "front-admin";
set $service_port "80";
set $location_path "/page/manager/(.*)";
set $global_rate_limit_exceeding n;
...

Related

Redirect from www to non www duplicates query params kubernetes

I am trying to redirect from https://example.nl to https://www.example.nl. This works perfectly. However, when I add query params, the query params get duplicated.
For example, whenever I go to example.nl?test=a, it redirects to wwww.example.nl?test=a?test=a.
How do I prevent this duplication of query params?
I use kubernetes and digital ocean. My kubernetes ingress file looks as follows:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
service.beta.kubernetes.io/do-loadbalancer-name: "example"
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/backend-protocol: HTTP
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'example.nl' ) {
rewrite ^ https://www.example.nl$request_uri permanent;
}
nginx.ingress.kubernetes.io/server-snippet: |
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/x-javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
spec:
tls:
- hosts:
- www.example.nl
- example.nl
secretName: main-example-tls
rules:
- host: www.example.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-end
port:
number: 3000
- path: /api
pathType: Prefix
backend:
service:
name: back-end
port:
number: 8000
- host: example.nl
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: front-end
port:
number: 3000
- path: /api
pathType: Prefix
backend:
service:
name: back-end
port:
number: 8000
If any additional informations is required. Please let me know.
try something like
annotations:
nginx.ingress.kubernetes.io/configuration-snippet: |
rewrite / https://test.app.example.com$uri permanent;
You can also refer my article : https://medium.com/#harsh.manvar111/kubernetes-ingress-domain-redirect-4595e9030a2c

Example Nginx plus ingress for sticky sessions during canary deployment

I’m deploying 2 services to kubernetes pods which simply echo a version number; echo-v1 & echo-v2
Where echo-v2 is considered the canary deployment, I can demonstrate sticky sessions as canary weight is reconfigured from 0 to 100 using canary & canary-weight annotations.
2 ingresses are used:
The first routes to echo-v1 with a session cookie annotation.
The second routes to echo-v2 with canary true,canary weight and session cookie annotations.
The second ingress I can apply without impacting those sessions started on the first ingress and new sessions follow the canary weighting as expected.
However I’ve since learned that those annotations are for nginx community and won’t work with nginx plus.
How can I achieve the same using ingress(es) with nginx plus?
This is the ingress configuration that works for me using Nginx community vs Nginx plus.
Nginx community:
(coffee-v1 service)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/affinity: "cookie"
name: ingress-coffee
spec:
rules:
- http:
paths:
- path: /coffee
pathType: Exact
backend:
service:
name: coffee-v1
port:
number: 80
(coffee-v2 'canary' service)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "100"
name: ingress-coffee-canary
spec:
rules:
- http:
paths:
- path: /coffee
pathType: Exact
backend:
service:
name: coffee-v2
port:
number: 80
Nginx plus:
(coffee-v1 & coffee-v2 as type 'virtualserver' not 'ingress')
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: cafe
spec:
host: cloudbees-training.group.net
tls:
secret: cloudbees-trn.aks.group.net-tls
upstreams:
- name: coffee-v1
service: coffee-v1-svc
port: 80
sessionCookie:
enable: true
name: srv_id_v1
path: /coffee
expires: 2h
- name: coffee-v2
service: coffee-v2-svc
port: 80
sessionCookie:
enable: true
name: srv_id_v2
path: /coffee
expires: 2h
routes:
- path: /coffee
matches:
- conditions:
- cookie: srv_id_v1
value: ~*
action:
pass: coffee-v1
- conditions:
- cookie: srv_id_v2
value: ~*
action:
pass: coffee-v2
# 3 options to handle new session below:
#
# 1) All new sessions to v1:
# action:
# pass: coffee-v1
#
# 2) All new sessions to v2:
# action:
# pass: coffee-v2
#
# 3) Split new sessions by weight
# Note: 0,100 / 100,0 weightings causes sessions
# to drop for the 0 weighted service:
# splits:
# - weight: 50
# action:
# pass: coffee-v1
# - weight: 50
# action:
# pass: coffee-v2

Need to help on routing https URL with redirectpath

I am running Nginx ingress inside one of our EKS cluster and earlier had issue to http-->https redirect as we are terminating SSL at AWS NLB. I was able to get it fixed using the method listed in this ticket https://github.com/kubernetes/ingress-nginx/issues/2724 ( Thanks to #Ariseaz )
However, along with https redirect we want to append path and redirect which is not working. Here are some methods I have tried so far
The container webpage serving paths /coffee and /tea
http://cafe.com ------> https://cafe.com ## This works because of the http --> https redirection
http://cafe.com/tea -----> https://cafe.com/tea ## This works
http://cafe.com/coffee -----> https://cafe.com/coffee ## This works
Now when I want to redirect https://cafe.com to https://cafe/coffee it does not work.
Can anyone please tell me now to append path to https:hostname and redirect.. I was able-to get is working with AWS ALB Ingress with this annotation and I am trying to get the same method with nginx ingress.
alb.ingress.kubernetes.io/actions.svc-cafe: >
{"Type":"redirect","RedirectConfig":{"Path":"/coffee","Protocol":"HTTPS", "Port": "443","StatusCode":"HTTP_301"}} ## This is to append /coffee to hostname and redirect ( https://cafe.com ---> htttps://cafe.com/coffee)
Here is my ingress file using Nginx ingress controller
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-example
annotations:
nginx.ingress.kubernetes.io/server-snippet: |
if ($host = "https://cafe.com") {
return 301 https://$host$request_uri/coffee;
}
#nginx.ingress.kubernetes.io/rewrite-target: /
#nginx.ingress.kubernetes.io/configuration-snippet: |
# rewrite ^(/coffee)$ $1/ permanent;
spec:
ingressClassName: internal-nginx
rules:
- host: cafe.com
http:
paths:
- path: /tea
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- path: /coffee
pathType: Prefix
backend:
service:
name: coffee-svc
port:
number: 80
Please try :
nginx.ingress.kubernetes.io/server-snippet: |
if ($host ~ "https://cafe.com")
{
rewrite ^ https://$host$request_uri/coffee permanent;
}
or else try
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'https://cafe.com' ) {
return 301 https://$host$request_uri/coffee;
}
When I change the host to cafe.com instead of https://cafe.com I can see it the url getting redirected but its going in a loop
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'cafe.com' ) {
return 301 https://$host$request_uri/coffee;
}
https://cafe.com//coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee/coffee
You can try this
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'cafe.com' ) {
return 301 https://cafe.com/coffee;
}
OR
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'cafe.com' ) {
rewrite ^([^.]*[^/])$ https://cafe.com/coffee permanent;
}

Setting up kubernets Ingress proxy-body-size based on request method

I've been trying to set up a max body size in the Ingress controller based on the HTTP method of a given path.
Basically the POST method should allow 3m as max size and all the other methods should allow 1m.
Right now my main idea was to do something like:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-custom-service
namespace: development
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
kubernetes.io/ingress.class: "nginx-dev"
nginx.ingress.kubernetes.io/configuration-snippet: |
internal;
rewrite ^ $original_uri break;
nginx.ingress.kubernetes.io/server-snippet: |
location /api/v1/my-endpoint {
if ( $request_method = POST) {
set $target_destination '/_post';
client_max_body_size 3M;
}
if ( $request_method != POST) {
set $target_destination '/_not_post';
client_max_body_size 1M;
}
set $original_uri $uri;
rewrite ^ $target_destination last;
}
spec:
tls:
rules:
- host: my-host.com
http:
paths:
- path: /_post
backend:
serviceName: my-service
servicePort: 8080
- path: /_not_post
backend:
serviceName: my-service
servicePort: 8080
But then I'm getting the following error in the pod:
Is there any way I can correctly set-up the max body size via the ingress controller?
Try changing your annotations with the configuration-snippet
nginx.ingress.kubernetes.io/configuration-snippet: |
location /upload-path {
client_max_body_size 8M;
}
Read more at : https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md#configuration-snippet

Setting "Cache-Control" header with Kubernetes ingress

I have a kubernetes cluster running in AWS and am trying to modify the Cache Controller headers via the kubernetes ingress as such:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress-lab-static
namespace: lab
annotations:
ingress.kubernetes.io/rewrite-target: /$1
ingress.kubernetes.io/enable-cors: "true"
ingress.kubernetes.io/cors-allow-methods: GET, POST,PUT, OPTIONS, DELETE, HEAD, PATCH
ingress.kubernetes.io/cors-allow-headers: >-
Accept-Charset, Accept-Encoding, Access-Control-Request-Headers, Access-Control-Request-Method, Authorization,
Cache-Control, Connection, Content-Encoding, Content-Type, Content-Length, DNT, Date, Host, If-Modified-Since,
Keep-Alive, Origin, Referer, Server, TokenIssueTime, Transfer-Encoding, User-Agent, Vary, X-CustomHeader, X-Requested-With,
password, username, x-request-id, x-ratelimit-app, x-auth-id, x-auth-key, x-guest-token, X-HTTP-Method-Override,
x-oesp-username, x-oesp-token, x-cus, x-dev, X-Client-Id, X-Device-Code, X-Language-Code, UserRole, x-session-id, x-entitlements-token
ingress.kubernetes.io/configuration-snippet: |
more_set_headers 'Access-Control-Allow-Origin:$origin';
ingress.kubernetes.io/proxy-buffering: "on"
ingress.kubernetes.io/proxy-buffer-size: "2048k"
ingress.kubernetes.io/server-snippet: |
chunked_transfer_encoding off;
location ((https|http):\/\/.*\/test-service\/images\/.*\/imageName.*) {
more_set_headers 'Cache-Control: public, max-age=14400';
}
spec:
rules:
- host: static-url-lab.lab.cdn.example.com
http:
paths:
- path: /test-service/(.*)
backend:
serviceName: test-service
servicePort: 80
However this does not seem to be working. When I curl a resource matching that pattern I get the default values back:
# Example curl - not exact
curl -v "https://static-url-lab.lab.cdn.example.com/test-service/intent/test/image_name" -o /dev/null 2>&1 grep -E "(Cache-Control: max|X-Cache)"
< Cache-Control: max-age=172800, public
As far as I can tell the regex should be matching, but no change is taking place, what am I missing?
Try something like this :
working for me
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($request_uri ~* \.(js|css|gif|jpe?g|png)) {
expires 1M;
add_header Cache-Control "public";
}
nginx.ingress.kubernetes.io/proxy-body-size: 50m
nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"