<p>Thus far I've set up a kubernetes cluster that runs my NodeJS deployment. I am now ready to expose it to "the world" and after reading up on services to do this, I believe all of them require a Load Balancer. Usually these Load Balancers are created by a cloud provider that is hosting kubernetes. I came across several limitations with these, some are priced highly, some have limits on connections etc...</p>

<p>I am now trying to figure out how to avoid these Load Balancers and expose my kubernetes cluster, but in a performant, secure and manageable way. I've looked through documentation and there seem to be mentionings of things like <code>NodePort</code> and <code>Ingress</code>. As far as I understood <code>NodePort</code> only works for a single machine in the cluster? and <code>Ingress</code> still  requires traffic to come from somewhere, usually a Load Balancer.</p>

<p>This is my current manifest, where should I go from here in terms of exposing it to the public, ideally with a method that allows SSL certs, rate limiting etc... usual stuff you'd need in production</p>

<p><strong>development.yaml</strong></p>

<pre><code>---
# ClusterIP
apiVersion: v1
kind: Service
metadata:
  name: development-actions-cip
spec:
  type: ClusterIP
  selector:
    app: development-actions
  ports:
    - protocol: TCP
      port: 80
      targetPort: 4000
---
# Actions NodeJS server
apiVersion: apps/v1
kind: Deployment
metadata:
  name: development-actions
spec:
  replicas: 1
  selector:
    matchLabels:
      app: development-actions
  template:
    metadata:
      labels:
        app: development-actions
    spec:
      containers:
        - image: my-image/latest
          name: development-actions
          ports:
            - containerPort: 4000
              protocol: TCP
</code></pre>

<p>To solve the problem there are some ways:</p>

<ol>
<li>You can use a service known as MetalLB which is a popularly used for bare metal deployments. It provides a network load balancer.</li>
<li>If you do not want to use the load balancer provided by the cloud provider you can create your custom load balancer with help of a reverse proxy (may be Nginx service). This machine can be a dedicated instance that can be only loaded with routing and load balancing capabilities. The ingress controller that you create after this can be allowed to take traffic from this machine. This is user defined edge creation. </li>
<li>As mentioned in the solution above you can use <code>hostNetwork:true</code> with your nginx-ingress Pods so that these machines can directly be accessed over the machine network.</li>
<li>You can use the externalIP directly with the nginx ingress pods where you can directly assign a public IP to the service and connect the service over the internet.</li>
</ol>

<p>For more information and setup details visit the official documentation for Nginx ingress at:  <a href="https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#over-a-nodeport-service" rel="nofollow noreferrer">https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#over-a-nodeport-service</a></p>

<p>I have tried all of these options for deploying my application and my suggestion would be that if you are using some cloud service to deploy your cluster use the cloud service provider's load balancer as it is much more secure, highly available, and reliable. I you are using on premise deployments go for the user defined edge creation, or MetalLB service</p>
