Add proxy_pass like rule on ingress - nginx

I have the ingress configuration as below:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
rules:
- host: example.com
http:
paths:
- backend:
service:
name: my-app
port:
number: 80
pathType: ImplementationSpecific
tls:
- hosts:
- example.com
secretName: my-ingress-tls
This shows the content of the service my-app on port 80 when example.com is reached. However, I want to implement something else. When going to example.com/hello-world, I want to show content from some other website let's say from hello-world.com. In NGINX it can be achieved using proxy_pass. How can I achieve this in ingress?

Related

Ingress rewrite to two different services from one DNS

I am trying to reach out to two services from my DNS.
Example:- myportal.com
myportal.com/app1
I have my SSO and SSL implementation on "myportal.com" and on the home page I have a button which calls a service "myportal.com/app1". I have tried multiple things but I am not able to configure both properly.
From below ingress config I am able to redirect to "myportal.com/app1" but its not working properly for "myportal.com". I have tried multiple thing including default backend and its not working for me. When I use default backend then "myportal.com" works but it stops redirecting to /app1.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myportal-ingress-test
namespace: appspace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- myportal.com
secretName: secret
rules:
- host: myportal.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: portal-service
port:
number: 8097
- pathType: Prefix
path: /app1(/|$)(.*)
backend:
service:
name: app-ui-service
port:
number: 8087
I am fairly new to kubernetes and I am not sure if it's the correct way to implement such things. I am open to new implementation too if it's using ingress and routing to different services using same dns on different path.
Thanks in advance for the help!
I was able to resolve this issue. The redirect in an ingress file would work for all the paths, so I created a separate ingress for each path with individual redirects.
Ingress 1 - myportal.com (with SSO and SSL)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gcpportal-service-test
namespace: appspace
annotations:
nginx.ingress.kubernetes.io/x-forwarded-prefix: /myportal-service
nginx.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
ingressClassName: nginx
tls:
- hosts:
- myportal.com
secretName: secret
defaultBackend:
service:
name: myportal-service
port:
number: 80
rules:
- host: myportal.com
Ingress 2 - myportal.com/app1 (application deployed)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gcpportal-service-test-1
namespace: appspace
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- myportal.com
secretName: secret
rules:
- host: myportal.com
- pathType: Prefix
path: /app1(/|$)(.*)
backend:
service:
name: app1-ui-service
port:
number: 8087
This helped me to resolve this issue. I also verified that this way is also a standard way and is provided in one of the documentation of nginx.
https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/

Kubernetes nginx ingress https problems

I have set up an on-premises Kubernetes 1 node cluster on Ubuntu
with nginx-ingress and metalLB
I have 2 problems:
If I go to my site with https://www.example.com it works but it doesn't with https://example.com (bad certificate).
I would like to redirect HTTP to HTTPs (HTTP://example.com not working).
I have no problems with other subdomains (subdomain.example.com)
Here is my Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: clientweb-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$1
cert-manager.io/issuer: letsencrypt-prod
spec:
rules:
- host: www.example.com
http:
paths:
- path: /?(.*)
pathType: Prefix
backend:
service:
name: clientweb-service
port:
number: 80
tls:
- hosts:
- example.com
- www.example.com
secretName: ethernial-tls-secret

Ability to exclude one page from https redirection in nginx ingress controller

I have an app in Kubernetes which is served over https. So now I would like to exclude one URL from that rule and use HTTP to serve it for performance reasons. I am struggling with that the whole day and it seems impossible.
These are my ingress YAML:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
field.cattle.io/publicEndpoints: '[{"addresses":["172.31.1.11"],"port":443,"protocol":"HTTPS","serviceName":"myservice:myservice","ingressName":"myservice:myservice","hostname":"app.server.test.mycompany.com","path":"/","allNodes":true}]'
kubernetes.io/ingress.class: nginx
creationTimestamp: "2020-02-17T13:14:19Z"
generation: 1
labels:
app-kubernetes-io/instance: mycompany
app-kubernetes-io/managed-by: Tiller
app-kubernetes-io/name: mycompany
helm.sh/chart: mycompany-1.0.0
io.cattle.field/appId: mycompany
name: mycompany
namespace: mycompany
resourceVersion: "565608"
selfLink: /apis/extensions/v1beta1/namespaces/mycompany/ingresses/mycompany
uid: c6b93108-a28f-4de6-a62b-487708b3f5d1
spec:
rules:
- host: app.server.test.mycompany.com
http:
paths:
- backend:
serviceName: mycompany
servicePort: 80
path: /
tls:
- hosts:
- app.server.test.mycompany.com
secretName: mycompany-tls-secret
status:
loadBalancer:
ingress:
- ip: 172.31.1.11
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
field.cattle.io/publicEndpoints: '[{"addresses":["172.31.1.1"],"port":80,"protocol":"HTTP","serviceName":"mycompany:mycompany","ingressName":"mycompany:mycompany-particular-service","hostname":"app.server.test.mycompany.com","path":"/account_name/particular_service/","allNodes":true}]'
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/use-regex: "true"
creationTimestamp: "2020-02-17T13:14:19Z"
generation: 1
labels:
app-kubernetes-io/instance: mycompany
app-kubernetes-io/managed-by: Tiller
app-kubernetes-io/name: mycompany
helm.sh/chart: mycompany-1.0.0
io.cattle.field/appId: mycompany
name: mycompany-particular-service
namespace: mycompany
resourceVersion: "565609"
selfLink: /apis/extensions/v1beta1/namespaces/mycompany/ingresses/mycompany-particular-service
uid: 88127a02-e0d1-4b2f-b226-5e8d160c1654
spec:
rules:
- host: app.server.test.mycompany.com
http:
paths:
- backend:
serviceName: mycompany
servicePort: 80
path: /account_name/particular_service/
status:
loadBalancer:
ingress:
- ip: 172.31.1.11
So as you can see from above I would like to server /particular_service/ over HTTP. Ingress, however, redirects to HTTPS as TLS is enabled for that host in the first ingress.
Is there any way to disable TLS just for that one specific path when the same host is being used for configuration?
In short summary I would like to have:
https://app.server.test.mycompany.com
but
http://app.server.test.mycompany.com/account_name/particular_service/
I've tested with 2 ingress of the same domain, the first one with tls enabled and the second without tls and it worked.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
name: echo-https
spec:
tls:
- hosts:
- myapp.mydomain.com
secretName: https-myapp.mydomain.com
rules:
- host: myapp.mydomain.com
http:
paths:
- backend:
serviceName: echo-svc
servicePort: 80
path: /
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
name: echo-http
spec:
rules:
- host: myapp.mydomain.com
http:
paths:
- backend:
serviceName: echo-svc
servicePort: 80
path: /insecure
By the Nginx docs:
By default the controller redirects HTTP clients to the HTTPS port 443 using a 308 Permanent Redirect response if TLS is enabled for that Ingress.
This can be disabled globally using ssl-redirect: "false" in the NGINX config map, or per-Ingress with the nginx.ingress.kubernetes.io/ssl-redirect: "false" annotation in the particular resource.
Please let me if that helps.
Also add nginx.ingress.kubernetes.io/ssl-redirect ": "false". It had worked for me previously. You can give it a try.

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 k8s ingress - forcing www AND https?

I have a kubernetes setup that looks like this:
nginx ingress -> load balancer -> nginx app
after getting an SSL certificate for www.foo.com, I've installed it in my nginx ingress as a secret, and it works as expected - traffic to www.foo.com gets redirected to the https version instead, and browsers display a secure connection indicator. Great.
What hasn't been easy, however, is getting the ingress to redirect non-www traffic to the www version of the site. I've tried using kubernetes.io/from-to-www-redirect: "true", but it doesn't seem to do anything - navigating to foo.com doesn't redirect me to the www version of the url, but either takes me to an insecure version of my site, or navigates me to default backend - 404 depending on whether i include foo.com as a host with it's own path in my ingress.
I have been able to set up a patchy redirect by adding the following to my actual application's nginx config -
server {
listen 80;
server_name foo.com;
return 301 http://www.foo.com$request_uri;
}
UPDATE: from-to-www-redirect DOES work; you just have to reference it with nginx.ingress.kubernetes.io rather than kubernetes.io as I was. But, this only works for foo.com - typing in https://foo.com explicitly causes browsers to display a security warning and no redirect to the proper URL of https://www.foo.com occurs.
Here's my current config for the nginx ingress itself:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo-https-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: www.foo.com
http:
paths:
- backend:
serviceName: foo-prod-front
servicePort: 80
path: /
tls:
- hosts:
- www.foo.com
secretName: tls-secret
You need to add the certificate for the domain you want to be redirected:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo-https-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: foo.com
http:
paths:
- backend:
serviceName: foo-prod-front
servicePort: 80
path: /
- host: www.foo.com
http:
paths:
- backend:
serviceName: foo-prod-front
servicePort: 80
path: /
tls:
- hosts:
- foo.com
- www.foo.com
secretName: tls-secret
I am not completely sure, whether from-to-www-redirect works with this setup, but you can replace it with the following lines, which do work:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'foo.com' ) {
rewrite ^ https://www.foo.com$request_uri permanent;
}
I have the following doing the job with the latest nginx-ingress 0.25.1:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-rule-web
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/from-to-www-redirect: 'true'
spec:
rules:
- host: foo.org
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
tls:
- hosts:
- foo.org
- www.foo.org
secretName: letsencrypt-prod
I found the docs to be confusing here as well. Below is an example i have working. I believe you need to define the naked url in tls certs to avoid a cert error(your cert needs to be valid for both foo.com and www.foo.com). You CANNOT list the naked url under rules: hosts because that will get picked up prior to the redirect.
http://foo.com -> https://www.foo.com
https://foo.com -> https://www.foo.com
http://www.foo.com -> https://www.foo.com
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: foo-https-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: www.foo.com
http:
paths:
- backend:
serviceName: foo-frontend
servicePort: 80
path: /
tls:
- hosts:
- foo.com
- www.foo.com
secretName: tls-secret
This is rather a problem with your ssl certificate than the nginx ingress configuration. My guess is that your certificate is only valid for foo.com and not for www.foo.com. If you access www.foo.com your browser shows a security warning because the certificate isn't valid for the domain you are visiting.
I had to solve an issue first:
The solution that worked for me is the one from #demisx but on my first try, the solution was not working for another reason. I had more than one ingress with reference to the "example.com" root host and as described on the documentation this was omitting my www redirect rule.
Documentation refers that "If at some point a new Ingress is created with a host equal to one of the options (like domain.com) the annotation will be omitted."
This is example is wrong:
Ingress 1 - to handle example.com
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-https-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: example-frontend
servicePort: 80
path: /
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-secret
Ingress 2 - to handle example.com/news
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-https-ingress-news
spec:
rules:
- host: example.com. # <--------- I HAD ANOTHER REFERENCE
http:
paths:
- backend:
serviceName: example-news
servicePort: 80
path: /news
- host: www.example.com
http:
paths:
- backend:
serviceName: example-news
servicePort: 80
path: /news
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-secret
Solution - Correct Configuration
Make sure that you don't have any other ingress created with the root domain otherwise the redirect will not work as documentation refers. I removed the reference to example.com host on ingress 2 and then immediately started to work.
Ingress 1 - to handle example.com
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-https-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
serviceName: example-frontend
servicePort: 80
path: /
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-secret
Ingress 2 - to handle example.com/news
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-https-ingress-news
spec:
rules:
# <--------- removed the other reference to the root host
- host: www.example.com
http:
paths:
- backend:
serviceName: example-news
servicePort: 80
path: /news
tls:
- hosts:
- example.com
- www.example.com
secretName: tls-secret
Note: By the way, I didn't need to add the forward annotation to the 2nd ingress cause is already handled by the first ingress. I'm not sure though, if the order of deployment matters for nginx ingress controllers so take this as a note only and try to confirm yourself.

Resources