Unul din lucrurile pe care le neglijezi când construiești un homelab e rețeaua. Cumperi hardware, instalezi Proxmox, ridici VM-uri — și între timp totul merge pe un switch de 1Gbps și pe router-ul de la ISP. La un moment dat realizezi că transferurile între noduri sunt limitate de rețea, nu de disk sau CPU, și că ar fi cazul să faci lucrurile cum trebuie.

Iată cum arată rețeaua de acasă după câteva iterații.

Hardware-ul de rețea

Întregul stack e TP-Link Omada — un ecosistem gestionat centralizat printr-un controller hardware dedicat:

  • ER605 v2.0 — router/gateway
  • OC200 — Omada Hardware Controller, gestionează întregul stack
  • SG2008P v3.20 — switch managed PoE 8 porturi – 4 alimenteaza AP-urile, 1 alimenteaza OC200
  • EAP653 x2 — AP-uri Wi-Fi 6 (etaj 2 și parter 2)
  • EAP265 HD x2 — AP-uri Wi-Fi 5 (etaj 1 și parter 1)

OC200 e un controller hardware dedicat — un dispozitiv mic cât o cutie de chibrituri mai mare care rulează Omada Controller fără să consume resurse din Proxmox sau să depindă de el. Avantajul față de varianta software: e întotdeauna activ independent de starea cluster-ului, ceea ce contează dacă faci modificări de rețea exact când un nod Proxmox e down.

Avantajul unui stack integrat: configurezi un VLAN o dată în controller și se propagă automat pe switch și pe toate AP-urile. Roaming-ul Wi-Fi între cele 4 AP-uri funcționează transparent — nu simți trecerea de la un AP la altul. Față de soluția de a cumpăra echipamente de la producători diferiți și a le gestiona separat, diferența de confort e semnificativă.

2.5Gbps — unde contează

Nu toată rețeaua are 2.5Gbps — nu are sens. Telefoanele, laptopurile și dispozitivele IoT se descurcă perfect pe 1Gbps. Dar între nodurile Proxmox și QNAP, lățimea de bandă contează direct în performanța homelab-ului:

  • Live migration între nodurile Proxmox — copierea memoriei RAM a unui VM în câteva secunde, nu zeci
  • Backup-uri VM pe NFS spre QNAP — un backup de 50GB în 3 minute, nu 7
  • Plex direct play de pe QNAP spre clienți cu cerințe mari de bandwidth (4K remux, Dolby Atmos)
  • Transferuri de fișiere mari spre/dinspre NAS

Switch-urile de 2.5Gbps sunt luate de pe AliExpress — mă zgârcesc intenționat aici. Un switch unmanaged de 2.5Gbps cu 5-8 porturi costă 80–150 RON pe AliExpress față de 400–600 RON pentru echivalentul de brand. Pentru traficul intern de homelab, diferența de calitate nu justifică diferența de preț.

Topologia: nodurile Proxmox (pve00, pve01, pve02) și QNAP-ul sunt conectate la switch-urile de 2.5Gbps. Switch-urile de 2.5Gbps sunt conectate uplink la SG2008P-ul Omada care face managementul VLAN-urilor. Am mai incercat sa folosesc adaptoare de retea (tot de pe aliexpress) pentru nodurile proxmox dar rezultatele au fost dezamagitoare, asa ca am abandonat si le tin in cutia cu maimute.

3 VLAN-uri — separare clară

Rețeaua e împărțită în trei zone cu politici de trafic diferite:

VLAN Default — uz general

Laptopuri, telefoane, televizoare, calculatoare. Trafic standard spre internet, fără restricții interne.

VLAN IoT

Becuri smart, prize inteligente, camere, termostate, orice dispozitiv care “sună acasă” în mod dubios. Izolat de rețeaua principală — un dispozitiv IoT compromis nu are acces la laptopuri sau la NAS. Poate ieși pe internet dar nu poate comunica cu celelalte VLAN-uri.

Aceasta e poate cea mai importantă decizie de securitate dintr-un homelab. Dispozitivele IoT au firmware actualizat rar, vulnerabilități cunoscute și producători care dispar sau abandonează suportul. Le dai acces la internet pentru că au nevoie să funcționeze, dar le izolezi de restul rețelei.

VLAN Sandbox/HomeLab

Nodurile Proxmox, QNAP, VM-urile și LXC-urile din cluster. Acces la internet controlat, comunicare liberă între componente. Separat de rețeaua de uz general pentru că un experiment care merge prost (un container care consumă tot bandwidth-ul, un VM care face broadcast storms) nu afectează restul casei.

ER605 face routing între VLAN-uri cu reguli explicite — ce poate vorbi cu ce e definit clar, nu implicit.

Diagrama rețelei

Internet
    │
  ER605
    │
  SG2008P Switch Omada
    ├── VLAN Default  ──► Laptopuri, telefoane, TV
    ├── VLAN IoT      ──► Becuri, camere, smart home
    └── VLAN HomeLab  ──► Proxmox + QNAP
              │
    ┌─────────┴──────────┐
    │                    │
Switch 2.5G         Switch 2.5G
(AliExpress)        (AliExpress)
    │                    │
pve00  pve01         pve02  QNAP
                           TS-464

OC200 — Omada Hardware Controller (independent)

AP-uri Omada (4x) — toate VLAN-urile propagate wireless
  EAP653 Etaj 2
  EAP653 Parter 2
  EAP265 Etaj 1
  EAP265 Parter 1

Ce funcționează bine

OC200 ca controller hardware dedicat — independent de cluster-ul Proxmox, mereu activ, consum neglijabil. Îți dă vizibilitate completă pe tot stack-ul: câți clienți sunt pe fiecare AP, ce bandwidth consumă, uptime per dispozitiv.

VLAN-urile prin controller — configuri o dată, se propagă pe switch și pe toate AP-urile automat. Dacă adaugi un AP nou, preia automat configurația VLAN existentă.

2.5Gbps intern — transferurile între Proxmox și QNAP sunt limitate acum de QNAP, nu de rețea. Switch-urile ieftine de pe AliExpress nu au dat nicio problemă în utilizare reală.

Ce aș schimba

Switch-urile de 2.5Gbps de pe AliExpress sunt unmanaged — nu pot face trunking VLAN pe ele. Asta înseamnă că traficul de homelab și traficul de management merg pe același cablu fizic spre SG2008P, unde se separă. Funcționează, dar nu e elegant. La o viitoare iterație aș lua un switch managed de 2.5Gbps — există opțiuni TP-Link TL-SG105-M2 la ~200 RON care fac trunking VLAN și s-ar integra mai curat în stack-ul Omada.

Altfel — rețeaua funcționează exact cum ar trebui. Izolarea IoT dă liniște, 2.5Gbps intern face homelab-ul considerabil mai rapid, și gestionarea centralizată prin OC200 elimină nevoia de a accesa fiecare dispozitiv separat.

Posturi din aceeași serie:

Uptime Kuma este un tool dragut de monitorizare, face automat rapoarte SLA, monitorizeaza site-uri, este destul de util. Pentru a monitoriza ill.ro folosesc altceva (UptimeRobot), m-am gandit sa fie independent de homelab, ca daca pica homelab-ul nu mai imi zice nimeni ca a cazut site-ul…
Voi folosi ArgoCD pentru a testa si invata cum functioneaza acest tool… l-am instalat si pana acum e doar o interfata web… Asadar sa instalam cu ArgoCD.

Pentru pasii astia avem niste prerechizite:
1. Un share nfs pentru persistent storage (il foloseste uptime kuma ca sa tina minte tot ce face)
2. Un cont de github sau orice repo, eu o sa folosesc github ca inca nu am deployat asa ceva in homelab.
3. metalLB functional 🙂

1. Mai intai share-ul NFS: am folosit v3 pentru simplitate, am permis accesul full din reteaua de acasa, desigur in afara homelab-ului vom avea autentificare si altele. Am creat un share numit uptime-kuma.

Pe nodurile k8s (control/worker) vom instala nfs-common si testam daca share-ul nfs este disponibil si putem scrie pe el.

apt install -y nfs-common
mkdir /mnt/test-nfs
mount -t nfs -o nfsvers=3 IP_NFS:/uptime-kuma /mnt/test-nfs
touch testnfs
cd /mnt/test-nfs && ls

Ar trebui sa vedem fisierul. Daca e acolo, inseamna ca nodurile noastre pot accesa NFS, trecem mai departe.

2. Github. Facem un nou repo, o sa il numesc argoCD si vom crea intr-un director nou urmatoarele fisiere:

Prima oara facem un namespace, fisierul uptimekuma-namespace.yaml.

apiVersion: v1
kind: Namespace
metadata:
  name: uptime-kuma

Definim un persistent volume – uptimekuma-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv-uptime-kuma
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=3
  nfs:
    path: /uptime-kuma
    server: IP_NFS #adresa ip a serverului nfs

Persistent volume claim uptimekuma-pvclaim.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: uptime-kuma-pvc
  namespace: uptime-kuma
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
  storageClassName: slow

Definim serviciul – uptimekuma-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: uptime-kuma-tcp
  namespace: uptime-kuma
spec:
  type: LoadBalancer #nu specificam ip, lasam metallb sa aleaga pentru noi
  ports:
  - name: web-ui
    protocol: TCP
    port: 3001
    targetPort: 3001
  selector:
    app: uptime-kuma

Si in final, deployment-ul uptimekuma-deplyment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: uptime-kuma
  namespace: uptime-kuma
spec:
  selector:
    matchLabels:
      app: uptime-kuma
  replicas: 1
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: uptime-kuma
    spec:
      containers:
      - name: uptime-kuma
        image: louislam/uptime-kuma:1
        imagePullPolicy: IfNotPresent
        env:
        # only need to set PUID and PGUI because of NFS server
        - name: PUID
          value: "1000"
        - name: PGID
          value: "1000"
        ports:
        - containerPort: 3001
          name: web-ui
        resources:
          limits:
            cpu: 200m
            memory: 512Mi
          requests:
            cpu: 50m
            memory: 128Mi
        livenessProbe:
          tcpSocket:
            port: web-ui
          initialDelaySeconds: 60
          periodSeconds: 10
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /
            port: web-ui
          initialDelaySeconds: 30
          periodSeconds: 10
        volumeMounts:
        - name: data
          mountPath: /app/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: uptime-kuma-pvc

Pasul 2, sa intram in ArgoCD, sa definim un repository si o aplicatie. Rezultatele ar arata ca in printscreen-urile de mai jos. Avem nevoie de 2-3 lucruri:
– repository URL: tip https sau cum vreti voi, si path-ul.
– project – o sa fie default, ca nu am altceva definit
– cluster – o sa aleaga automat clusterul pe care este instalat
– path: uptimekuma – e directorul unde am pus tot.
– sync: am lasat manual

Dupa ce accesezi aplicatia si dai click pe sync, argo o sa downloadeze yaml-urile din repo, din directorul ales si o sa inceapa sa le aplice.
Rezultatul ar trebui sa arate asa:

Teoretic ar trebui sa poti accesa uptime kuma, pe ip-ul pe care il aloca metallb… si sa vezi interfata.

Orice schimbare a yaml-urilor din github vor fi semnalate de ArgoCD. Daca ai pus sincronizarea pe automat ar trebui ca orice modificare faci sa fie deployata in Kubernetes automat, sa zicem ca modifici numarul de replici (pod-uri) pentru aplicatia ta.. sau faci un update… Mai jos exemplu:

“BestMan” m-a sfatuit sa ma uit si la ArgoCD. Rachete, magie, gitops, kubernetzi…
Sa incepem cu o traducere:

Argo CD este un instrument declarativ CICD pentru aplicațiile Kubernetes. Acesta utilizează stilul GitOps pentru a crea și gestiona clustere Kubernetes. Atunci când se fac modificări în configurația aplicației din Git, Argo CD o compară cu configurația aplicației care rulează și notifică utilizatorii pentru a sincroniza starea dorită cu cea actuală.
Argo CD a fost dezvoltat în cadrul proiectului Argo al Cloud Native Computing Foundation (CNCF), un proiect destinat în special gestionării ciclului de viață al aplicațiilor Kubernetes. Acest proiect include, de asemenea, Argo Workflow, Argo Rollouts și Argo Events. Fiecare dintre acestea rezolvă un set specific de probleme în procesul de dezvoltare agilă și contribuie la livrarea scalabilă și securizată a aplicațiilor Kubernetes.

Cumva in github pui yaml-urile, asta verifica ce e acolo si face treaba. Asta e magie, ca pana acum stateam cu 20j de fisiere yaml pe nodu de control si le pierdeam, le suprascriam, nu mai stiam care fisier e ce imi trebuie… nah, gandire de sysadmin.
Am deja cont de github, o sa fac un repo nou si o sa il folosesc pentru a instala “Uptime Kuma” cu ArgoCD.

Instalarea ArgoCD e simpla, am facut un namespace nou si am folosit manifestul lor.
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Dupa 2-3 minute am vazut si podurile:

Mai devreme am pus MetalLB si as vrea sa il folosesc sa ajung la ArgoCD. Se poate folosi si nodeport dar e mai elegant asa, fara sa accesezi porturi ciudate. Dezavantajul pe care il vad eu pe termen lung o sa trebuiasca sa extinzi pool-ul de ip-uri folosit de metallb. Deci, revenim:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

Teoretic acum ar trebui sa am ArgoCD publicat pe unu din ip-urile alea din loadbalancer, pe porturile 443 si 80.

O sa avem nevoie de parola (userul e admin). Avem o parola random creata la instalare…
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
Accesam 192.168.111.220:80, user si parola avem. Iaca!

Avem ArgoCD functional, teoretic putem incepe sa il folosim.
Next post, instalare “Uptime Kuma” cu ArgoCD.

MetalLB este o soluție de LoadBalancer pentru clusterele Kubernetes care de pe infrastructură bare-metal, asa cum am si eu in HomeLab. Spre deosebire de cloud-uri (eks de ex) unde ai deja solutii native… pe onprem (bare metal) ai nevoie de o solutie pentru a expune serviciile catre retea si de acolo… mai departe, pe internet daca este cazul 😀

Instalarea MetalLB

Eu am folosit manifestul lor..
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/main/config/manifests/metallb-native.yaml
In cateva zeci de secunde se for initializa toate componentele si vom avea ceva de genul
kubectl get pods -n metallb-system

Pentru a configura MetalLB vom avea nevoie de un spatiu de ip-uri din zona in care tinem si nodurile de k8s. Daca avem DHCP va trebui sa rezervam zona aceea… Creaza un fisier de ex metallb-config.yaml si aplica configuratia.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: default-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.111.220-192.168.111.230
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: l2advertisement
  namespace: metallb-system

kubectl apply -f metallb-config.yaml

Destul de simplu… pentru a vedea logurile metallb

kubectl logs -n metallb-system -l app=metallb

Ca sa ii vedem utilitatea putem sa cream un nginx mic si stingher, facem un yaml nou, nginx-lb.yaml iar la serviciu specificam tipul LoadBalancer.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-lb
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-lb
  template:
    metadata:
      labels:
        app: nginx-lb
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-lb
  namespace: default
spec:
  selector:
    app: nginx-lb
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Se aplica configuratia, dupa care K8s va crea un POD conform specificatiilor si un serviciu prin care publicam nginx-ul pe portul 80.
kubectl apply -f nginx-lb.yaml

Va trebui sa se regaseasca in lista serviciul si un IP din pool-ul setat mai sus pentru metallb.

Din browser va trebui sa puteti accesa serviciul pe portul 80, pe acel ip.

Easy peasy!

In postul trecut am scris despre un NAS home-made. Nu e o idee rea, ar fi fost maximum de performant pentru ce am eu nevoie dar nu am facut proiectul. M-am oprit la un NAS comercial, adica ala din titlu. Am vazut niste dezavantaje care m-au enervat, in speta lipsa pe piata a placilor de baza cu 4-6 porturi SATA si 2 NVME-uri. Domne, nu exista! Eu spun ca e blat cu aia care fac NAS-uri, ca altfel cum sa nu fie posibil sa pui 2NVME si 4SATA pe langa un PCIEx cu care sa extinzi cu diverse nebunii?

Am ales calea usoara, nu imi pare rau, ba mai mult decat atat, chiar ma bucur ca am facut pasul.

Configuratia este
– 2 nvme x 512GB – folosit pentru cache, raid0 ca sa am mai mult. Riscul este ca daca moare vreunu as putea sa pierd date…. (filme, vm-uri sau containere de test, deci nimic grav)
– 4 sata x 10TB HGST HUH721010ALE604, raid 5. M-am gandit sa le pun la raid10 dar pierdeam 2 disk-uri de capacitate. Asa un disk poate sa pice si nu pierd date vs 2 disk-uri care pot pica. E safe si asa, parerea mea.
– 32 GB RAM – 2 sodimm-uri de 16GB de la Kingston, pe care le aveam deja.

Likes:
– Compact si cat de cat silentios
– 2 x 2.5gbps retea
– Plex / Qbittorrent / *arr ruleaza direct pe NAS, nu mai trebuie sa ruleze pe nodurile de proxmox
– Out of the box cam orice share ai nevoie, pot sa il folosesc ca timemachine pentru laptops

Software-ul pe care il poti instala pe el este cat se poate de divers, folosesc deja container station si am cateva containere Docker, printre care si tehnitium dns pe care il folosesc pentru dhcp dar si DNS blackhole in locul lui PiHole. Container station poate porni si k3s. Pe langa container station mai este un Virtualisation Station in care poti rula VM-uri micute (nu as recomanda ceva resource intensive din cauza procesorului)…

Consum:
– In jur de 40W in idle. Daca as fi avut sistemul de operare instalat pe NVME-uri ar fi intrat in idle disk-urile rotative si as fi economisit vreo 20W… asta atata vreme cat nu ar fi soft nici un request catre ele (qbittorrent oprit, nfs oprit…) deci nu se aplica.

Il folosesc deja sa rulez din proxmox VM-uri de pe un shared storage (NFS mi-a parut cel mai simplu si rapid), am caching pe acel volum deci nu trag “direct” de pe discurile rotative – cache read-write, evident. Il folsesc sa fac backup-uri VM-urilor din proxmox, zilnic.
In laboratorul de k8s (kubernetes) deja e folosit pentru persistent storage… Very nice!