I run Kubernetes single-node dev cluster with several independent services — Nginx proxy with port 80 and elasticsearch with ports 9200. Is there any way to expose these services with ingress, to have entry point with one LoadBalancer IP? (x.x.x.x:80 and x.x.x.x:9200)
I read about ingress limitation, which can be accessed only with 80 and 443 port. But, maybe, exists some workarounds?
Thx for any advice
UPDATE
I solve my problem with creating several ingresses and utilize the same load balancer. But faced some issue with Nginx ingress, which cost me a lot of time. The simplest way to use my approach, is install ingress controller with helm and parametrize it with exposed services and ports
helm install ingress stable/nginx-ingress --set tcp.4445="default/nginx-proxy:4445" --set tcp.8888="default/demo:8888" --set tcp.19200="default/elasticsearch:19200"
During this process, will be created necessary resources, including configmaps with ports/services. Then we need only create ingress for each service. Take a note, that service must be ClusterIP.
But if later you want to expose some extra services and add everything manualy(create configmap, update ingress service, create ingress, even recreate nginx pod), i cant connect to service :(
So any changes(for me) leads to reinstalling all controller
You just need to setup ingress rules that direct traffic to the correct service.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: nginx
spec:
rules:
- host: nginx.example.com
http:
paths:
- backend:
serviceName: nginx
servicePort: 80
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: elasticsearch
spec:
rules:
- host: elasticsearch.example.com
http:
paths:
- backend:
serviceName: elasticsearch
servicePort: 9200
Understand you have a dev server with not a lot of cool features that a cloud cluster would have. But there are workaround to make it look like one.
** ngress limitation, which can be accessed only with 80 and 443 port?
Yes but you can overwrite it, I wouldnt suggest as its a lot of manual work everytime you need to add / remove port
** Is there any way to expose these services with ingress
There is a much better solution instead.. why dont you use your own domain name say elasticsearch.Dehimb.host / grafana.Dehimb.host etc... ?
Use nginx ingress controller (could use other but the config below is for nginx as example)
Deploy it using help as daemon set instead of a deployment and use the values file changes below https://github.com/helm/charts/blob/master/stable/nginx-ingress/values.yaml#L52
reportNodeInternalIp: true
useHostPort: true
Here is where you can set *.Dehimb.com to k8s Node IP. (kubectl get nodes -owide)
Use your laptop to use dns masq IP as the first name server above its default ISP name server
Now simply create ingress with as many domains as you like, and when you browse from your laptop:
--> it first uses dnsmasq to resolve it to k8s node IPs,
--> there port 80 is open on every node because of the daemon set
--> Those ports are passing traffic to the nginx that has ingress configuration
--> nginx knows which service to pass the traffic to
It could sound slightly complicated but its fun when it all works and its one time setup.
Alternatively you can use metallb (but not as easy to figure out if it breaks)
You can create as many ingress resource as you want but all of them will be using the same LoadBalancer which is used to expose the ingress controller.
You need to have kubernetes cluster IP type services. In the services you can have port
as 80
and targetPort
as 9200
. After that in the ingress you can say servicePort
as 80
.
Alternatively have port
and targetPort
as 9200
in the clusterIP type service and mention 9200
in servicePort
of the ingress.
You are right of the fact that ingress such as nginx can only accept traffic on port 80
and 443
but nginx is reverse proxy meaning it will terminate that client connection and create a new connection to the servicePort
and that servicePort
does not necessarily need to be 80
or 443
i.e it can be 9200
.