Installation nodejs using K3s in High Availability (HA) Mode with MetalLB

1. Prepare the Environment
- Prerequisites:
- Multiple Linux nodes (virtual or bare metal) with unique hostnames.
- Shared network segment with 2–3 free IPs for MetalLB.
- SSH access to all nodes.
2. Install K3s in High Availability (HA) Mode
K3s offers two HA modes: with external DB (etcd, MySQL, PostgreSQL) or embedded etcd. Here is a simplified approach using embedded etcd:
a. On the first server node, initialize the cluster:
# Set a strong secret token
SECRET=CHANGE_ME_SECRET_TOKEN
curl -sfL https://get.k3s.io | sh -s - server \
--token=${SECRET} \
--cluster-init \
--disable traefik \
--disable servicelb \ --write-kubeconfig-mode=644
- --disable traefik disables the default ingress; you can use your own.
- --disable servicelb disables the default load balancer in K3s (Klipper), required to use MetalLB instead.
b. On additional server nodes, join the cluster:
curl -sfL https://get.k3s.io | sh -s - server \
--token=${SECRET} \
--server https://:6443 \
--disable traefik \
--disable servicelb \
--write-kubeconfig-mode=644
c. On agent (worker) nodes, join:
Get the node token from one server node:
cat /var/lib/rancher/k3s/server/node-token
On the worker node:
curl -sfL https://get.k3s.io | K3S_URL=https://:6443 K3S_TOKEN= sh
Verify with:
kubectl get nodes
3. Install MetalLB for Load Balancing
a. Install MetalLB (manifest method):
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
Or via Helm:
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb --namespace metallb-system --create-namespace
b. Set up an IP Address Pool for MetalLB
Create a metallb-config.yaml file:
apiVersion: metallb.io/v1beta1 kind: IPAddressPool
metadata:
name: default
namespace: metallb-system
spec:
addresses:
- 192.168.1.240-192.168.1.250 # Adjust to match your network!
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement metadata:
name: default
namespace: metallb-system
Then apply it:
kubectl apply -f metallb-config.yaml
This allocates a set of external IPs for MetalLB to hand out to LoadBalancer type services.
4. Install Node.js in Pods on K3s
You typically do not install Node.js directly on the cluster nodes, but inside containers.
For example, you can create a Deployment using the official Node.js container image:
node-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
spec:
replicas: 3
selector:
matchLabels:
app: nodejs-app
template:
metadata:
labels:
app: nodejs-app
spec:
containers:
- name: nodejs
image: node:18 # Or another version you need
ports:
- containerPort: 3000 command: ["node", "YOUR_APP.js"] # replace with your script
Apply:
kubectl apply -f node-deployment.yaml
5. Expose Node.js with LoadBalancer Service
Create a nodejs-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nodejs-service
spec:
selector:
app: nodejs-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Apply:
kubectl apply -f nodejs-service.yaml
After a few moments, kubectl get svc will show an EXTERNAL-IP assigned from MetalLB's pool. This service distributes incoming requests to all Node.js pods, providing both load balancing and high availability.
In Summary:
Deploy K3s with HA mode and disable built-in load balancer (servicelb).
Install MetalLB and configure your external IP pool.
Deploy Node.js apps as Kubernetes Deployments.
Use LoadBalancer-type Services to expose your apps via MetalLB, providing external traffic balancing and failover.
This approach gives you both cluster control-plane and application-level high availability.
|