Kubernetes ingress rule - docker

I have a k8s 1.9.0 cluster and following is my ingress rule.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
labels:
app: report
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "gayan.test.com"
http:
paths:
- path: /report
backend:
serviceName: qc-report-svc
servicePort: 80
- path: /report/*
backend:
serviceName: qc-report-svc
servicePort: 80
So I have two requests.
Request one - https://gayan.test.com/report/ping This request hit the pod and return the response.
(GET /ping 200 302.079 ms - 63)
Request two - wss://gayan.test.com/report/socket.io/?EIO=3&transport=websocket.
This request doesn't even hit the server. I think this is related to ingress rule.
My question is how can I send all the /report traffic to qc-report-svc service?

Assuming you are using the Nginx Ingress Controller you need to add the nginx.org/websocket-services annotation to enable WebSocket support.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
labels:
app: report
annotations:
ingress.kubernetes.io/rewrite-target: /
nginx.org/websocket-services: "qc-report-svc"
spec:
rules:
- host: "gayan.test.com"
http:
paths:
- path: /report
backend:
serviceName: qc-report-svc
servicePort: 80

Related

Reverse DNS for Kubernetes Ingress Website External IP

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.

Expose basepath in container through service in nginx ingress on kubernetes

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

Exposing Neo4j Bolt using Kubernetes Ingress

I'm trying to build a Neo4j Learning Tool for some of our Trainings. I want to use Kubernetes to spin up a Neo4j Pod for each participant to use. Currently I struggle exposing the bolt endpoint using an Ingress and I don't know why.
Here are my deployment configs:
apiVersion: apps/v1
kind: Deployment
metadata:
name: neo4j
namespace: learn
labels:
app: neo-manager
type: database
spec:
replicas: 1
selector:
matchLabels:
app: neo-manager
type: database
template:
metadata:
labels:
app: neo-manager
type: database
spec:
containers:
- name: neo4j
imagePullPolicy: IfNotPresent
image: neo4j:3.5.6
ports:
- containerPort: 7474
- containerPort: 7687
protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
name: neo4j-service
namespace: learn
labels:
app: neo-manager
type: database
spec:
selector:
app: neo-manager
type: database
ports:
- port: 7687
targetPort: 7687
name: bolt
protocol: TCP
- port: 7474
targetPort: 7474
name: client
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: neo4j-ingress
namespace: learn
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: learn.neo4j.com
http:
paths:
- path: /
backend:
serviceName: neo4j-service
servicePort: 7474
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: learn
data:
7687: "learn/neo4j-service:7687"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: learn
spec:
replicas: 1
selector:
matchLabels:
app: ingress-nginx
template:
metadata:
labels:
app: ingress-nginx
spec:
containers:
- name: nginx-ingress-controller
image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0-beta.16
args:
- /nginx-ingress-controller
- --tcp-services-configmap=${POD_NAMESPACE}/tcp-services
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
The client gets exposed nicely and it reachable under learn.neo4j.com but I don't know where to point it to to connect to the DB using bolt. Whatever I try, it fails saying ServiceUnavailable: Websocket Connection failure (WebSocket network error: The operation couldn’t be completed. Connection refused in the console).
What am I missing?
The nginx-ingress-controller by default creates http(s) proxies only.
In your case you're trying to use a different protocol (bolt) so you need to configure your ingress controller in order for it to make a TCP proxy.
In order to do so, you need to create a configmap (in the nginx-ingress-controller namespace) similar to the following:
apiVersion: v1
kind: ConfigMap
metadata:
name: tcp-services
namespace: ingress-nginx
data:
7687: "<your neo4j namespace>/neo4j-service:7687"
Then, make sure your ingress controller has the following flag in its command:
--tcp-services-configmap tcp-services
This will make your nginx-ingress controller listen to port 7687 with a TCP proxy.
You can delete the neo4j-bolt-ingress Ingress, that's not going to be used.
Of course you have to ensure that the ingress controller correctly exposes the 7687 port the same way it does with ports 80 and 443, and possibly you'll have to adjust the settings of any firewall and load balancer you might have.
Source: https://kubernetes.github.io/ingress-nginx/user-guide/exposing-tcp-udp-services/
It automatically tries to connect to port 7687 by default - if you enter the connection url http://learn.neo4j.bolt.com:80 (or https), it works.
I haven't used kubernetes ingress in this context before, but I think that when you use HTTP or HTTPS to connect to Neo4J, you still require external availability to connect to the the bolt port (7687). Does your setup allow for that?
Try using multi-path mapping in your Ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: neo4j-ingress
namespace: learn
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: learn.neo4j.com
http:
paths:
- path: /browser
backend:
serviceName: neo4j-service
servicePort: 7474
- path: /
backend:
serviceName: neo4j-service
servicePort: 7687
You should then be able to access the UI at learn.neo4j.com/browser. The bolt Connect URL would have to specified as:
bolt+s://learn.neo4j.com:443/

Paths in Kubernetes Ingress Specs

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.

Rewriting paths with Traefik

Can someone give a simple example on how to route the following URLs:
http://monitor.app.com/service-one
http://monitor.app.com/service-two
http://monitor.app.com/service-three
http://monitor.app.com/service-four
To the following backend services?
http://service-one/monitor
http://service-two/monitor
http://service-three/monitor
http://service-four/monitor
Preferably using the [file] syntax of Traefik, although any is fine.
Here is a configuration for your example. Adjust it according to your real cluster configuration:
apiVersion: v1
kind: Service
metadata:
name: service-one
spec:
selector:
k8s-app: service-one-app
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: service-two
spec:
selector:
k8s-app: service-two-app
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: service-three
spec:
selector:
k8s-app: service-three-app
ports:
- port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: monitor.app
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/rewrite-target: /monitor # set path to result request
spec:
rules:
- host: monitor.app.com
http:
paths:
- path /service-one # path for routing, it will be removed because of PathPrefixStrip settings
backend:
serviceName: service-one
servicePort: 80
- path /service-two # path for routing, it will be removed because of PathPrefixStrip settings
backend:
serviceName: service-two
servicePort: 80
- path /service-three # path for routing, it will be removed because of PathPrefixStrip settings
backend:
serviceName: service-three
servicePort: 80
Additional information could be found here:
Kubernetes Ingress Controller
Kubernetes Ingress Provider
kubernetes ingress rewrite-target implementation #1723

Resources