在没有GCP负载均衡器的情况下创建kubernetes Nginx入口

So I'm using Kubernetes for a side project and it's great. It's cheaper to run for a small project like the one I'm on (a small cluster of 3-5 instances gives me basically everything I need for ~$30/month on GCP).

The only area where I'm struggling is in trying to use the kubernetes Ingress resource to map into cluster and fan out to my microservices (they're small Go or Node backends). I have the configuration setup for the ingress to map to different services and there's no problem there.

I understand that you can really easily have GCP spin up a LoadBalancer when you create an ingress resource. This is fine, but it also represents another $20-ish/month that adds to the cost of the project. Once/if this thing gets some traction, that could be ignored, but for now and also for the sake of understanding Kubernetes better, I want to the do the following:

  • get a static IP from GCP,
  • use it w/ an ingress resource
  • host the load-balancer in the same cluster (using the nginx load balancer)
  • avoid paying for the external load balancer

Is there any way this can even be done using Kubernetes and ingress resources?

Thanks!

Yes this is possible. Deploy your ingress controller, and deploy it with a NodePort service. Example:

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
  namespace: kube-system
  labels:
    k8s-app: nginx-ingress-controller
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 32080
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    nodePort: 32443
    protocol: TCP
    name: https
  selector:
    k8s-app: nginx-ingress-controller

Now, create an ingress with a DNS entry:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: my-app-service #obviously point this to a valid service + port
          servicePort: 80

Now, assuming your static IP is attached to any kubernetes node running kube-proxy, have DNS updated to point to the static IP, and you should be able to visit myapp.example.com:32080 and the ingress will map you back to your app.

A few additional things:

If you want to use a lower port than 32080, then bear in mind if you're using CNI networking, you'll have trouble with hostport. It's recommend to have a load balancer listening on port 80, I guess you could just have nginx set up to do proxy pass, but it becomes difficult. This is why a load balancer with your cloud provider is recommended :)

You can also make an nginx-ingress chart, have it pull an ephemeral IP and then upgrade it to static. This would leave you with a L7 single zone load balancer.

This guide goes through it. You can ignore the TLS stuff if you use kube-lego, which works just as well with nginx-ingress

https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/static-ip