nginx-ingress rewrite-target to /api not working - nginx

i am trying to get api as location (/api) to work with intress settings
this is my ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-dev
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
#nginx.ingress.kubernetes.io/rewrite-target: /
#nginx.ingress.kubernetes.io/app-root: /
spec:
rules:
- host: 'dev.example.com'
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: my-ruby
port: 3000
when i curl dev.example.com/api/check_version
i get error
I, [2021-12-01T16:43:35.776502 #13] INFO -- : [7253cca0b88503d625af527db32eb92e] Started GET "/api/check_serverr" for 10.42.1.228 at 2021-12-01 16:43:35 +0300
F, [2021-12-01T16:43:35.779603 #13] FATAL -- : [7253cca0b88503d625af527db32eb92e]
[7253cca0b88503d625af527db32eb92e] ActionController::RoutingError (No route matches [GET] "/api/check_version"):
if i add annotation nginx.ingress.kubernetes.io/rewrite-target: /
get error
I, [2021-12-01T16:49:11.153280 #13] INFO -- : [7832de5c07e3a173ddc86ebab5735cec] Started GET "/" for 10.42.1.228 at 2021-12-01 16:49:11 +0300
F, [2021-12-01T16:49:11.154435 #13] FATAL -- : [7832de5c07e3a173ddc86ebab5735cec]
[7832de5c07e3a173ddc86ebab5735cec] ActionController::RoutingError (No route matches [GET] "/"):
how to make a rewrite correctly in this case?

Based on the comments, the following seems to have fixed the issue.
You are looking to strip off the /api part off before the request is sent to the backend, thus requesting /api/check_version will become /check_version before it hits the backend:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
...<omitted>...
- path: /api(/|$)(.*)

Related

Kubernetes Ingress path rewrite dosen't work as expected

I have an ingress, defined as the following:
Name: online-ingress
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
jj.cloud.com
/online/(.*) online:80 (172.16.1.66:5001)
/userOnline online:80 (172.16.1.66:5001)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /$1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal AddedOrUpdated 29m (x4 over 74m) nginx-ingress-controller Configuration for default/online-ingress was added or updated
If I test it with no rewrite, it's ok.
curl -X POST jj.cloud.com:31235/userOnline -H 'Content-Type: application/json' -d '{"url":"baidu.com","users":["ua"]}'
OK
However, if I try to use rewrite, it will fail.
curl -X POST jj.cloud.com:31235/online/userOnline -H 'Content-Type: application/json' -d '{"url":"baidu.com","users":["ua"]}'
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.21.3</center>
</body>
</html>
And it will produce the following error logs:
2021/11/03 10:21:25 [error] 134#134: *63 open() "/etc/nginx/html/online/userOnline" failed (2: No such file or directory), client: 172.16.0.0, server: jj.cloud.com, request: "POST /online/userOnline HTTP/1.1", host: "jj.cloud.com:31235"
172.16.0.0 - - [03/Nov/2021:10:21:25 +0000] "POST /online/userOnline HTTP/1.1" 404 153 "-" "curl/7.29.0" "-"
Why the path /online/userOnline doesn't match /online/(.*) and rewrite it to /userOnline? Or are there some other errors?
Here is the yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: online-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: jj.cloud.com
http:
paths:
- path: /online(/|$)/(.*)
pathType: Prefix
backend:
service:
name: online
port:
number: 80
- path: /userOnline
pathType: Prefix
backend:
service:
name: online
port:
number: 80
ingressClassName: nginx
When I checked the generated nginx config, I found (default-online-ingress.conf):
location /online(/|$)/(.*) {
It seems lost of the modifier for regex match, like this:
location ~* "^/online(/|$)/(.*)" {
If it's true, how to make rewrite take effect and generate correct nginx config?
If I understood your issue correctly, you have a problem with captured groups.
According to Nginx Rewrite targets it seems to me,
your patch should be path: /online(/|$)(.*)
your rewrite-target: should be rewrite-target: /$2
in addition, if you use nginx ingress, I believe you should specify that in annotation section as kubernetes.io/ingress.class: nginx
yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: online-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: jj.cloud.com
http:
paths:
- path: /online(/|$)(.*)
pathType: Prefix
backend:
service:
name: online
port:
number: 80
- path: /userOnline
pathType: Prefix
backend:
service:
name: online
port:
number: 80
ingressClassName: inner-nginx

Error when exposing Kubernetes service through NGINX INGRESS and file type: LoadBalancer

I have a Vuejs application built with Docker in 2 stages with Nginx:
# estágio de compilação
FROM node:10-alpine as build-stage
WORKDIR /app
ARG VUE_APP_BASE_URL="minha-base-url"
ENV VUE_APP_BASE_URL=${VUE_APP_BASE_URL}
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# estágio de produção
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY --from=build-stage /app/nginx.conf /etc/nginx/conf.d/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Nginx.conf:
server {
listen 80;
location / {
alias /app/dist;
index index.html index.htm;
try_files $uri $uri/ #rewrites;
}
location #rewrites {
rewrite ^.$ /index.html last;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Everything works perfectly by triggering the docker run command. When going up to kubernetes everything works perfectly using port-forward:
kubectl port-forward deployment/app-front 8082:80
The big problem is when I create the Service with 1- type: LoadBalancer I can't access the application via the external IP generated, 2- also when I try through NGINX INGRESS it gives error 503. Note: I have other services that work perfectly in these 2 situations mentioned above, but these other applications are not built on top of the NGINX image on the docker, so I suspect that the error may come from there due to some conflict but I cannot reach a concrete conclusion. Here are the files:
App-front-deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: app-front
name: app-front
spec:
replicas: 1
selector:
matchLabels:
io.kompose.service: app-front
app: app-front
strategy: {}
template:
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: app-front
app: app-front
spec:
containers:
- image: fabiomdsdj/agendime-front:0.0.3
name: app-front
ports:
- containerPort: 8082
name: http
env:
- name: VUE_APP_BASE_URL
value: "app"
resources: {}
restartPolicy: Always
status: {}
App-front-service.yaml:
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.22.0 (955b78124)
creationTimestamp: null
labels:
io.kompose.service: app-front
name: app-front
spec:
type: ClusterIP
ports:
- name: "8082"
port: 8082
targetPort: 8082
selector:
io.kompose.service: app-front
app: app-front
tier: app-front
App-front-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "app.agendi.me"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: app-front
port:
number: 8082
I've been breaking my head for several days and I can't find the solution, could someone help me?
Note: With these same configurations I can expose other services that I have.

K8S Nginx Ingress issue - invalid condition

I have trouble about nginx ingress using condition
Install Nginx Ingress via helm instal (tested in both nginx-ingress-1.16 and nginx-ingress-1.36
I am try to follow
ingress nginx redirect from www to https
Setup some condition
like
nginx.ingress.kubernetes.io/configuration-snippet: |
if ( $host = "mydomain.co" ) {
rewrite ^ https://www.mydomain.co$uri permanent;
}
When apply the ingress rule, nginx ingress start reload in fail status
-------------------------------------------------------------------------------
W0602 07:35:36.244415 6 queue.go:130] requeuing vincent/demoheader-ingress, err
-------------------------------------------------------------------------------
Error: exit status 1
2020/06/02 07:35:36 [notice] 982#982: ModSecurity-nginx v1.0.0
2020/06/02 07:35:36 [emerg] 982#982: invalid condition "~" in /tmp/nginx-cfg971999838:530
nginx: [emerg] invalid condition "~" in /tmp/nginx-cfg971999838:530
nginx: configuration file /tmp/nginx-cfg971999838 test failed
My Full ingress rule
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: demoheader-ingress
namespace: namespace
annotations:
kubernetes.io/ingress.class: nginx-temp
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
if ( $uri ~* ^/xx/(.*) ) {
rewrite ^ https://www.xxx.co permanent;
}
spec:
rules:
- host: mydomain
http:
paths:
- backend:
serviceName: header-headerv1
servicePort: 80
path: /
EOF
Any idea ?
OK i know what happen in here
I encount a wired issue for k8s apply stuff ….
While official document told you , you can apply object by this method
cat <<EOF | kubectl apply -f -
xxx
yyy
eee
EOF
https://kubernetes.io/docs/reference/kubectl/cheatsheet/
However for ingress rule , if you under a specific condition such like this
nginx.ingress.kubernetes.io/configuration-snippet: |
if ( $host = ^mydomain ) {
rewrite ^ https://www.mydomain$uri permanent;
}
you are unable to make the nginx working again (never config reload success, it will affect the following config change)
Until you delete the ingress rule and re-apply by
kubectl apply -f the-ingress-file

kubernetes annotations being ignored

The following annotations are being ignored by kubernetes. When I describe the ingress they are not showing up and nginx is not using affinity.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ydos-ingress
namespace: ydos
annotations:
nginx.ingress.kubernetes.io/client-body-buffer-size: 1M
nginx.ingress.kubernetes.io/rewrite-target: "/"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "YDOS-SESSION-EX"
nginx.ingress.kubernetes.io/session-cookie-hash: "sha1"
nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"
nginx.ingress.kubernetes.io/auth-tls-secret: "ydos/wildcard-yellowdog-tech-secret"
nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1"
nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false"
spec:
tls:
- hosts:
- service.yellowdog.tech
secretName: wildcard-yellowdog-tech-secret
rules:
- host: service.yellowdog.tech
http:
paths:
- path: /ydos
backend:
serviceName: ydos-svc
servicePort: 80
I would expect annotations and events, not the following;
$ kubectl describe ingress ydos-ingress -n ydos
Name: ydos-ingress
Namespace: ydos
Address: 130.61.9.241
Default backend: default-http-backend:80 (<none>)
TLS:
wildcard-yellowdog-tech-secret terminates service.yellowdog.tech
Rules:
Host Path Backends
---- ---- --------
service.yellowdog.tech
/ydos ydos-svc:80 (<none>)
Annotations:
Events: <none>

Metricbeat failing autodiscover on Kubernetes

Autodiscover not working for metricbeat 6.4.0 in kubernetes 1.9.6.
Nginx module in this use case, uwsgi also tried.
Declaring the module and giving an nginx ip outside of autodiscover works. below is the configmap being used.
Any ideas on some additional ways to set this up or problems that would stop the autodiscover from working.
apiVersion: v1
kind: ConfigMap
metadata:
name: metricbeat-deployment-config
namespace: kube-system
labels:
k8s-app: metricbeat
data:
metricbeat.yml: |-
metricbeat.config.modules:
# Mounted `metricbeat-daemonset-modules` configmap:
path: ${path.config}/modules.d/*.yml
# Reload module configs as they change:
reload.enabled: false
processors:
- add_cloud_metadata:
output.elasticsearch:
hosts: ['${ELASTICSEARCH_HOST:elasticsearch}:${ELASTICSEARCH_PORT:9200}']
---
apiVersion: v1
kind: ConfigMap
metadata:
name: metricbeat-deployment-modules
namespace: kube-system
labels:
k8s-app: metricbeat
data:
autodiscover.yml: |-
metricbeat.autodiscover:
providers:
- type: kubernetes
host: ${HOSTNAME}
#hints.enabled: true
templates:
- condition:
contains:
kubernetes.container.name: nginx
config:
- module: nginx
metricsets: ["stubstatus"]
enable: true
period: 10s
hosts: ["${data.host}:80"]
server_status_path: "nginx_status"
kubernetes.yml: |-
- module: kubernetes
metricsets:
- state_node
- state_deployment
- state_replicaset
- state_pod
- state_container
period: 10s
host: ${NODE_NAME}
hosts: ["kube-state-metrics.monitoring.svc:8080"]

Resources