Reputation: 123
I would like to maintain a very low-cost Kubernetes cluster on GCP. I am using a single node pool of e1-small instances. The monthly cost of this instance is $4.91 which is fine. But the problem is the ingress I am using to expose my node ports to an external-IP. The ingress instance uses a Google load balancer which costs around $18. Therefore, I am mostly paying to a useless load balancer which I really don't need. Is there a way that I can expose the IP addresses of those instances without the load balancer?
Upvotes: 1
Views: 933
Reputation: 789
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install $NGINX ingress-nginx/ingress-nginx \
--namespace $NAMESPACE \
--set controller.replicaCount=2 \
--set controller.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set defaultBackend.nodeSelector."beta\.kubernetes\.io/os"=linux \
--set controller.admissionWebhooks.patch.nodeSelector."beta\.kubernetes\.io/os"=linux
That's your load balancer.
Now get yourself a certificate manager...
kubectl label -n $NAMESPACE cert-manager.io/disable-validation=true
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace $NAMESPACE \
--set installCRDs=true \
--set nodeSelector."kubernetes\.io/os"=linux \
--set webhook.nodeSelector."kubernetes\.io/os"=linux \
--set cainjector.nodeSelector."kubernetes\.io/os"=linux
Next you'll need to add a CA Cluster Issuer...
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: $EMAIL_ADDRESS
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
podTemplate:
spec:
nodeSelector:
"kubernetes.io/os": linux
kubectl apply -f cluster-issuer.yaml
You'll also need an ingress and service yaml.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: $INGRESS_NAME
namespace: $NAMESPACE
labels:
app.kubernetes.io/part-of: $NAMESPACE
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
cert-manager.io/cluster-issuer: letsencrypt
spec:
tls:
- hosts:
- $YOUR_DOMAIN
secretName: tls-secret
rules:
- host: $YOUR_DOMAIN
http:
paths:
- backend:
serviceName: $SERVICE_NAME
servicePort: $SERVICE_PORT
apiVersion: v1
kind: Service
metadata:
name: $SERVICE_NAME
namespace: $NAMESPACE
labels:
app.kubernetes.io/part-of: $NAMESPACE
app.kubernetes.io/type: service
spec:
type: ClusterIP
ports:
- name: fart
port: $SERVICE_PORT
targetPort: $SERVICE_PORT
selector:
app.kubernetes.io/name: $DEPLOYMENT_NAME
app.kubernetes.io/part-of: $NAMESPACE
It shouldn't cost anything more to deploy these resources.
If you're so concerned about costs you can deploy a fully functioning and publicly reachable cluster locally with minikube or micro-k8s.
Upvotes: 0
Reputation: 75715
If you expose the nodePort externally, you will expose a port number 10k+. So not a port 80 or 443 for a website. You need to proxy the connection, with a loadbalancer by example.
A solution is to use Cloud Run as reverse proxy with NGINX for example. In this case, you can also use serverless VPC Connector and reach the service through the private IP in your VPC.
Upvotes: 2