1
votes

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

3

3 Answers

3
votes

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... ?

  1. Use nginx ingress controller (could use other but the config below is for nginx as example)

  2. 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

  1. Now setup your dns using dnsmasq, may be a small node somewhere or even container on your host using this image : https://github.com/jpillora/docker-dnsmasq

Here is where you can set *.Dehimb.com to k8s Node IP. (kubectl get nodes -owide)

  1. Use your laptop to use dns masq IP as the first name server above its default ISP name server

  2. 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)

2
votes

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
2
votes

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.