Answer by Deepthink R1
Here’s a tailored setup for your k3s-based Kubernetes cluster on Alpine Linux with NFS storage, IPv6 disabled, and self-hosted apps like Nextcloud:
1. Pre-Installation Requirements
VM Specifications
- OS: Alpine Linux (Edge or latest stable release).
- Resource Allocation (per VM):
- Control Plane (Master): 2 vCPUs, 2GB RAM, 20GB Disk.
- Worker Nodes: 2 vCPUs, 2GB RAM, 20GB Disk (scale as needed).
- Networking:
- Static IPv4 addresses (e.g.,
192.168.1.10for master,192.168.1.11for worker). - Disable IPv6 (see steps below).
- Open ports:
6443(k3s API),8472(Flannel),2049(NFS).
- Static IPv4 addresses (e.g.,
2. Disable IPv6
On all nodes:
# Edit /etc/modprobe.d/disable-ipv6.conf
echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.d/disable-ipv6.conf
echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.d/disable-ipv6.conf
sysctl -p
reboot3. Prepare Alpine Linux for k3s
Install dependencies on all nodes:
apk update
apk add openrc nfs-utils cni-plugins containerd
rc-update add containerd
rc-service containerd startLoad required kernel modules:
echo "br_netfilter" >> /etc/modules
modprobe br_netfilter4. Install k3s
Control Plane (Master Node):
# Install k3s server with Flannel and disable Traefik/Metrics
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik --disable servicelb --disable metrics-server" sh -s -Worker Nodes:
# Join using the master node's IP and token (from /var/lib/rancher/k3s/server/node-token)
curl -sfL https://get.k3s.io | K3S_URL=https://<MASTER_IP>:6443 K3S_TOKEN=<TOKEN> sh -s -5. Configure NFS Storage
On the NFS Server (Physical Machine):
# Share a directory (e.g., /mnt/nfs_share)
echo "/mnt/nfs_share 192.168.1.0/24(rw,sync,no_subtree_check)" >> /etc/exports
rc-service nfs startOn All k3s Nodes:
# Install NFS client tools
apk add nfs-utilsCreate a PersistentVolume (PV) and PersistentVolumeClaim (PVC):
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: <NFS_SERVER_IP>
path: /mnt/nfs_share
---
# nfs-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100GiApply with kubectl apply -f nfs-pv.yaml -f nfs-pvc.yaml.
6. Deploy Apps (Nextcloud, Vaultwarden, etc.)
Example: Nextcloud Deployment:
# nextcloud.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextcloud
spec:
replicas: 1
selector:
matchLabels:
app: nextcloud
template:
metadata:
labels:
app: nextcloud
spec:
containers:
- name: nextcloud
image: nextcloud:latest
ports:
- containerPort: 80
volumeMounts:
- name: nfs-storage
mountPath: /var/www/html
volumes:
- name: nfs-storage
persistentVolumeClaim:
claimName: nfs-pvc
---
apiVersion: v1
kind: Service
metadata:
name: nextcloud-svc
spec:
type: LoadBalancer
selector:
app: nextcloud
ports:
- port: 80
targetPort: 80Repeat similarly for Vaultwarden, Paperless-ngx, etc., adjusting ports and storage paths.
7. MetalLB for Load Balancing
Install MetalLB (Layer 2 mode):
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yamlConfigure IP pool (e.g., 192.168.1.200-192.168.1.250):
# metallb-config.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: home-lab-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.200-192.168.1.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: home-lab-l2
namespace: metallb-system8. Ingress Controller (Replace Traefik)
Install Nginx Ingress:
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm install ingress-nginx ingress-nginx/ingress-nginxExample Ingress for Nextcloud:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nextcloud-ingress
spec:
ingressClassName: nginx
rules:
- host: nextcloud.home.lab
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nextcloud-svc
port:
number: 809. Security & Monitoring
Firewall Rules (Alpine Linux):
apk add iptables
iptables -A INPUT -p tcp --dport 6443 -j ACCEPT # k3s API
iptables -A INPUT -p udp --dport 8472 -j ACCEPT # Flannel
iptables -A INPUT -p tcp --dport 2049 -j ACCEPT # NFS
iptables-save > /etc/iptables/rules.v4Prometheus + Grafana:
helm install prometheus prometheus-community/kube-prometheus-stack10. Verify the Setup
kubectl get nodes # Check node status
kubectl get pods -A # Verify app pods
kubectl get svc # Confirm LoadBalancer IPsTroubleshooting Tips
- NFS Permissions: Ensure the NFS share has
no_root_squashif apps need root access. - Alpine + k3s: If k3s fails to start, check
/var/log/k3s.logfor missing kernel modules. - MetalLB Issues: Confirm the IP pool doesn’t overlap with existing DHCP ranges.
Summary
- Cluster: Lightweight k3s on Alpine Linux.
- Storage: Shared NFS for persistent data (Nextcloud, Paperless-ngx, etc.).
- Networking: MetalLB + Nginx Ingress for external access.
- Apps: Deploy via Helm or YAML manifests with PVCs for storage.
Let me know if you need detailed manifests for specific apps like Vaultwarden or Bookstack!