I am trying to deploy Jenkins on Kubernetes. I have deployed it with ClusterIP along with Nginx Ingress Controller on AKS.
When I access the IP of the Ingress-Controller, the Jenkins login URL (http://ExternalIP/login?from=%2F) comes up. However the UI of the Jenkins page isn't coming up and there is a some sort of redirection happening and keeps growing (http://ExternalIP/login?from=%2F%3Ffrom%3D%252F%253Ffrom%253D%25252F%25253F). I am very new to Ingress controller and annotations. I am not able to figure on what's causing this redirection.
Below are my configuration files. Can anyone please help on what's going wrong ?
ClusterIP-Service.yml
kind: Service
apiVersion: v1
metadata:
name: jenkins-nodeport-svc
namespace: jenkins
labels:
env: poc
app: myapp_jenkins
spec:
ports:
- name: "http"
port: 80
targetPort: 8080
type: ClusterIP
selector:
app: myapp_jenkins
Ingress.yml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
rules:
- http:
paths:
- backend:
serviceName: jenkins-nodeport-svc
servicePort: 80
path: /(.*)
There's something in your ingress:
path: /(.*)
is a regular expression with a single capturing group that match everything. For example with following url: http://ExternalIP/login?from=myurl your capturing group $1 (the first and only one) would match login?from/myurl.
Now the problem is that nginx.ingress.kubernetes.io/rewrite-target: /$2 annotation is rewriting your url with a non existing capturing group.
You don't need rewriting, you just need to plain forward every request to the service.
Here you can find Rewrite Examples if you interested on it.
But in your case you can set:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-headers: Authorization, origin, accept
nginx.ingress.kubernetes.io/cors-allow-methods: GET, OPTIONS
nginx.ingress.kubernetes.io/enable-cors: "true"
spec:
rules:
- http:
paths:
- backend:
serviceName: jenkins-nodeport-svc
servicePort: 80
path: /
and you're good to go.
Related
I need help to create a reverse zone for the external IP of Kubernetes Ingress Website or something that do the some function like a reverse zone.
Basically I need that when I enter the IP of the ingress in the browser, redirects me to the domain name.
Thanks for the help.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: prueba-web-ingress
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: http://example.com
networking.gke.io/managed-certificates: certificateexample
kubernetes.io/ingress.global-static-ip-name: test
kubernetes.io/ingress.allow-http: "false"
spec:
backend:
serviceName: prueba-web
servicePort: 80
Try the following, just change the example.com to your domain:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: reverse-redirect
annotations:
nginx.ingress.kubernetes.io/permanent-redirect: http://example.com
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: "somerandomname" # needs some name, doesn't need to exist
port:
number: 80
When sending a request to nginx ingress without Host header, it will default to the ingress without specified host filed (just like the example above). Such request will receive a following response:
$ curl 123.123.123.123 -I
HTTP/1.1 301 Moved Permanently
Date: Wed, 28 Apr 2021 11:36:05 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: http://example.com
Browser receiving this redirect, will redirect to the domain specified in Location header.
Docs:
permanent redirect annotation
EDIT:
Since you are not using nginx ingress you can try to use a redirect app.
Here is a deployment with some random image I have found on dockerhub that responds to every request with redirect. I don't want to lecture you on security but I feel that I should at leat mention that you should never use random container images from the internet, and if you are, you are doing it on your own resposibiliy. Preferably build one from source and push to your own repo.
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: redir
name: redir
spec:
replicas: 1
selector:
matchLabels:
app: redir
template:
metadata:
creationTimestamp: null
labels:
app: redir
spec:
containers:
- image: themill/docker-nginx-redirect-301
name: docker-nginx-redirect-301
env:
- name: REDIRECT_CODE
value: "302"
- name: REDIRECT_URL
value: https://example.com
Service for the above deployment:
apiVersion: v1
kind: Service
metadata:
labels:
app: redir
name: redir
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: redir
status:
loadBalancer: {}
Now the ingress part:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: prueba-web-ingress
annotations:
networking.gke.io/managed-certificates: certificateexample
kubernetes.io/ingress.global-static-ip-name: test
kubernetes.io/ingress.allow-http: "false"
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: redir
servicePort: 80
- host: example.com
http:
paths:
- path: /
backend:
serviceName: prueba-web
servicePort: 80
Notice the same applies here: no host field set for redir service, although prueba-web service has its host filed set.
We are using Azure App G/w Ingress Controller to expose services hosted within AKS.
E.g.
Service named abc is hosted in AKS as below
apiVersion: v1
kind: Service
metadata:
labels:
project: abc
app: abc
env: dev
name: abc
namespace: abc
spec:
ports:
- name: http
# This is the external port of the cluster
port: 8443
protocol: TCP
targetPort: http
selector:
project: abc
app: abc
env: dev
type: ClusterIP
Ingress Configuration
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-abc
namespace: abc
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
rules:
- http:
paths:
- backend:
serviceName: abc
servicePort: 9000
path: /abc*
Problem Statement
Front-end will send request to the backend like: https://app-gw-ip/abc/operation.
App G/w applies appropriate routing rule and converts the request_uri to "//operation". "abc" in the URL path is overwritten by "/" because of the backend-path-prefix annotation. Whereas we want the request_uri as "/operation"
Is there a way to set backend-path-prefix to empty string ?
I want to replace "abc/" in the URL path with "/". Currently it replaces "abc" with "/".
If I do not use the backend-path-prefix, then backend uri path will be "abc/operation". This will return 404 because abc service will not have any endpoint named abc/operation.
Just use path as path: /abc/*
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-abc
namespace: abc
annotations:
kubernetes.io/ingress.class: azure/application-gateway
appgw.ingress.kubernetes.io/backend-path-prefix: "/"
rules:
- http:
paths:
- backend:
serviceName: abc
servicePort: 9000
path: /abc/*
My ASP.NET Core web application uses basepath in startup like,
app.UsePathBase("/app1");
So the application will run on basepath. For example if the application is running on localhost:5000, then the app1 will be accessible on 'localhost:5000/app1'.
So in nginx ingress or any ingress we can expose the entire container through service to outside of the kubernetes cluster.
My kubernetes deployment YAML file looks like below,
apiVersion: apps/v1
kind: Deployment
metadata:
name: app1-deployment
spec:
selector:
matchLabels:
app: app1
replicas: 1
template:
metadata:
labels:
app: app1
spec:
containers:
- name: app1-container
image: app1:latest
ports:
- containerPort: 5001
---
apiVersion: v1
kind: Service
metadata:
name: app1-service
labels:
app: app1
spec:
type: NodePort
ports:
- name: app1-port
port: 5001
targetPort: 5001
protocol: TCP
selector:
app: app1
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app1-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /app1(/|$)(.*)
backend:
serviceName: server-service
servicePort: 5001
The above ingress will expose the entire container in 'localhost/app1' URL. So the application will run on '/app1' virtual path. But the app1 application will be accessible on 'localhost/app1/app1'.
So I want to know if there is any way to route 'localhost/app1' request to basepath in container application 'localhost:5001/app1' in ingress.
If I understand correctly, now the app is accessible on /app1/app1 and you would like it to be accessible on /app1
To do this, don't use rewrite:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app1-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- http:
paths:
- path: /app1
backend:
serviceName: server-service
servicePort: 5001
I've been setting up a kubernetes cluster and want to protect the dashboard (running at kube.example.com) behind the bitly/oauth2_proxy (running at example.com/oauth2 on image a5huynh/oauth2_proxy:latest) as I want to re-use the OAuth proxy for other services I will be running. Authentication is working perfectly but after a user logs in, i.e. the callback returns, they are sent to example.com where instead they should be sent to the original host kube.example.com that initiated the flow. How can I do this? (I am using the nginx-ingress-controller).
Annotation on OAuth2 Proxy:
kubernetes.io/ingress.class: "nginx",
nginx.ingress.kubernetes.io/force-ssl-redirect: "true",
nginx.ingress.kubernetes.io/secure-backends: "true",
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
Annotation on Dashboard:
kubernetes.io/ingress.class: "nginx",
nginx.ingress.kubernetes.io/auth-signin: "https://example.com/oauth2/start",
nginx.ingress.kubernetes.io/auth-url: "https://example.com/oauth2/auth",
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS",
nginx.ingress.kubernetes.io/force-ssl-redirect: "true",
nginx.ingress.kubernetes.io/secure-backends: "true",
nginx.ingress.kubernetes.io/ssl-passthrough: "true",
nginx.ingress.kubernetes.io/ssl-redirect: "true"
I expect to be redirected to the original host kube.example.com after OAuth flow is complete but am being sent back to the OAuth2 host example.com
After searching for a bit I came across a blog post about performing this in a super simple manor. Unfortunately I found the provided yaml did not quite work correctly as the oauth2_proxy was never being hit due to nginx intercepting all requests (I am not sure if mine was not working due to me wanting the oauth-proxy url to be example.com/oauth2 rather than oauth2.example.com). To fix this I added back the oauth2-proxy path to the Ingress for the proxy i.e.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: oauth2-proxy
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example.com
http:
paths:
- backend:
serviceName: oauth2-proxy
servicePort: 80
path: /
- backend:
serviceName: oauth2-proxy
servicePort: 4180
path: /oauth2
and made sure that the service was also still exposed i.e.
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: oauth2-proxy
name: oauth2-proxy
namespace: default
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
- name: http-proxy
port: 4180
protocol: TCP
targetPort: 4180
selector:
k8s-app: oauth2-proxy
Then to protect services behind the oauth proxy I just need to place the following in the Ingress annotations:
nginx.ingress.kubernetes.io/auth-url: "https://example.com/oauth2/auth"
nginx.ingress.kubernetes.io/auth-signin: "https://example.com/oauth2/start?rd=/redirect/$http_host$request_uri"
I have the following ingress resource for one of my apps
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name:""
annotations:
ingress.kubernetes.io..
spec:
rules:
- host: my-app
http:
paths:
- path: /path/to/service
backend:
serviceName: my-service
servicePort: 80
This works as expected and I can access my service at http://my-app/path/to/service. However the service in my app takes query parameters that dont seem to correctly get redirected for eg:
http://my-app/path/to/service/more/paths
This brings me back to http://my-app/path/to/service
How can I maintain this path structure ?
I believe you need to use wildcards on your path:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name:""
annotations:
ingress.kubernetes.io..
spec:
rules:
- host: my-app
http:
paths:
- path: /path/to/service/*
backend:
serviceName: my-service
servicePort: 80
More information here. Seems like it's hard to find any docs with wildcard examples. Not that this is specific to nginx, it may not work with other ingress controllers.