Homelab: Cloudflare i K3S

Domowy Homelab krążył za mną od jakiegoś czasu. Przerażała mnie jednak myśl tego, że mam zmienne IP i inne wydatki. Jednak po odkryciu usług Cloudflare Tunnel, sprawa sporo się ułatwiła.

Setup

Czym jest DDNS ?

DDNS (Dynamic Domain Name System) to usługa, która automatycznie aktualizuje rekordy DNS, gdy zmienia się adres IP urządzenia.

DDNS mam w domu, dzięki użyciu usługi w NAS Synology, ale mimo to jest to usługa dość ograniczona, podobnie jak routing w web platform od Synology. Można było zainstalować Nginx w Dockerze i kierować porty 80 i 443 tam, aby rozwiązywać routing, ale było to uciążliwe. Zakupiłem więc Mini PC Dell Optiflex 7050 z konfiguracją: i5 6gen, 16 GB RAM i 512 SSD, aby zainstalować na nim Proxmox i Kubernetes.

W przyszłości planuję dokupić więcej RAM, aby ten master PC mógł obsługiwać dodatkowe usługi, jak baza danych czy Home Assistant z dodatkami.

Przy okazji, to także sposób na szybszy hosting dedykowanego serwera do gry Satisfactory, który na procesorze z Synology… zaczynał zawodzić.

Proxmox

Tutaj, miałem wiele opcji, bo mogłem zainstalować bezpośrednio Ubuntu i na nim postawić k3s, ale.. Zachęciła mnie myśl o separacji usług na osobne maszyny (kontenery), z myślą np. o Home Assistant w przyszłości. Proxmox, dzięki swoim skryptom, sporo to ułatwia, a hyper-v od MS mam wrażenie, że jest jednak trochę ociężałe i nie ma web panelu.

Proxmox to dystrybucja oparta na Debianie, która oferuje wirtualizację. Dodatkowym atutem jest obsługa przez web panel. Społeczność wokół Proxmox jest bogata, więc jest pełno gotowych skryptów z obrazami i konfiguracjami, np. do szybkiego postawienia Home Assistant z usługami.

Proxmox można pobrać za darmo ze strony: https://www.proxmox.com/en/downloads 

Strona ze skryptami: https://tteck.github.io/Proxmox/

ISO na pendrive wrzuciłem za pomocą Rufus, a następnie w BIOS ustawiłem bootowanie z pendrive i zainstalowałem Proxmox zgodnie z prostym przewodnikiem. Ustawiłem też stałe IP na routerze.

Warto zainstalować skrypt „Proxmox VE Post Install” z powyższej strony.

Warto też dodać, że Jeśli w sytuacjach, gdy posiadacie nas, to śmiało możecie podłączyć do każdej instancji dysk sieciowy po SMB czy NFS. Warto tylko dodać, że do LXC, musicie odznaczyć Typ instalacji, jako unprivileged, przy tworzeniu, bo inaczej nie będziecie nawet mieli opcji ustawienia tego potem. Więcej o tym napiszę w późniejszych wpisach.

Kubernetes

Ostatnio coraz częściej pracuję z Kubernetesem w firmie. Na początku wydawał się, bardziej skomplikowany niż trzeba, głównie przez pliki konfiguracyjne, które są trudniejsze niż np. Docker Compose.

Swojego master node stworzyłem na podstawie Debian LXC, który jest lżejszy i bardziej wydajny niż VM. Kontener ma 14 GB RAM i 4 vCPU, ponieważ obsługuje także dedykowany serwer do gry Satisfactory. W przyszłości będzie można dodać kolejne węzły, np. Raspberry Pi 4+.

Zainstalowałem K3s na Debian LXC: [https://k3s.io/](https://k3s.io/), co było bardzo proste. Aktualne dokumenty instalacyjne można znaleźć tutaj: https://docs.k3s.io/quick-start

Dla łatwiejszego dostępu do konfiguracji klastra:

cp /etc/rancher/k3s/k3s.yaml ~/.kube/config

lub

export KUBECONFIG=/etc/rancher/k3s/k3s.yaml

Polecam także narzędzie K9s, które znacznie ułatwia zarządzanie Kubernetes. Instrukcje instalacji znajdziesz tutaj: https://k9scli.io

Certyfikat

Kupiłem domenę lifelike.cloud, aby podpiąć certyfikat. Na potrzeby tego artykułu tworzę self-signed certificate, ponieważ ostateczny certyfikat będzie dostarczony przez Cloudflare Tunnel.

Tworzenie klucza prywatnego:

openssl genrsa -out wildcard.key 2048

Tworzenie CSR:

openssl req -new -key wildcard.key -subj "/CN=*.lifelike.cloud" -out wildcard.csr

Tworzenie certyfikatu ważnego rok:

openssl x509 -req -in wildcard.csr -signkey wildcard.key -out wildcard.crt -days 365

Podpinanie certyfikatu jako sekret w Kubernetes:

kubectl create secret tls tls-cert --cert=wildcard.crt --key=wildcard.key

Serwisy

Stawiam API dostępne w open source na moim GitHubie: https://github.com/aluspl/CoffeeRecipesApi/tree/develop.

Obraz aplikacji jest hostowany w Docker Hub jako:

aluspl/coffeerecipesapi:develop

Najpierw łączymy się z master node i tworzymy plik `api.yml`:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: coffeerecipes-api
  labels:
    app: coffeerecipes-api
spec:
  replicas: 1
  selector:
    matchLabels:
      app: coffeerecipes-api
  template:
    metadata:
      labels:
        app: coffeerecipes-api
    spec:
      containers:
        - name: coffeerecipes-api
          image: aluspl/coffeerecipesapi:develop
          imagePullPolicy: Always
          ports:
            - containerPort: 80
          env:
            - name: ConnectionStrings__Marten
              value: "Host=ip;Port=6432;Database=coffeerecipes;Username=postgres;Password=password#;"
            - name: Media__ConnectionStrings
              value: "blobStorageConnectionString"
            - name: ASPNETCORE_URLS
              value: "http://*:80"
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
          resources:
            limits:
              memory: "2024Mi"
              cpu: "500m"
            requests:
              memory: "1024Mi"
              cpu: "500m"

---

# Service dla aplikacji .NET
apiVersion: v1
kind: Service
metadata:
  name: coffeerecipes-api-service
spec:
  selector:
    app: coffeerecipes-api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      name: "http"
---

# Ingress dla aplikacji z użyciem Traefik
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: coffeerecipes-api-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
spec:
  tls:
    - hosts:
        - dev-api-recipes.lifelike.cloud
      secretName: lifelike-cloud-tls
  rules:
    - host: dev-api-recipes.lifelike.cloud
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: coffeerecipes-api-service
                port:
                  number: 80

Następnie aplikujemy konfigurację:

kubectl apply -f api.yaml

Cloudflare Tunnel

Cloudflare Tunnel pozwala na udostępnienie serwisów na zewnątrz bez otwierania portów na routerze. Chroni także przed atakami DDoS. Ustawiłem domenę na Cloudflare, aby zarządzać rekordami DNS.

Link do dokumentacji Cloudflare Tunnel: https://developers.cloudflare.com/cloudflare-one/tutorials/many-cfd-one-tunnel.

Przykład konfiguracji:

apiVersion: v1
kind: ConfigMap
metadata:
  name: cloudflared
data:
  config.yaml: |
    tunnel: lifelikecloudtunnel
    credentials-file: /etc/cloudflared/creds/credentials.json
    ingress:
    - hostname: dev-api-recipes.lifelike.cloud
      service: http://coffeerecipes-api-service:80

Teraz aplikujemy konfigurację:

kubectl apply -f cloudflare.yaml

Podsumowanie

Temat Homelab może wydawać się skomplikowany, ale po zrozumieniu podstaw, wszystko staje się łatwiejsze. Zachęcam do eksperymentowania i dalszej zabawy z technologiami!

Przy okazji, w kolejnej części, opowiem więcej o przejściu z ręcznie tworzonego certyfikatu, do automatycznie odnawianego let’s encrypt oraz przeniesieniu zmiennych typu connection stringi (do bazy czy blob storage) do kubernetesowych secretów.

p.s Dzięki Łukasz i Teodor za merytoryczne sprawdzenie artykułu.

Azure: Blob Storage

Hej Wam. Trzeba trochę odkurzyć projekt, a z racji, że w chwili pisania tego artykułu wylądowałem na ławce, postanowiłem się podszkolić z wiedzy, która przyda się każdemu. Mi się przydała do mojego projektu.
Nie jest też to droga usługa, przynajmniej na potrzebę usług takich jak galeria na stronie.
W tej części nie tylko opowiem Wam na temat założenia Storage Account, ale także jak obsłużyć “Bloby”.
Przy okazji, to już 2 lata od regularnego pisania w ramach DSP. Dzisiaj nie dałbym radę pisać 2x tygodniowo wpisów jak wtedy.

Czytaj dalej „Azure: Blob Storage”

.Net Core – DEV OPS for Dummies

Dev Ops for DUmmies

Jesli tu jesteś, to wiedz, że ten artykuł potrzebuje lekkiego update. Net Core poszło o 6 wersji do przodu, a docker-compose dalej ten sam 🙂

Miało być więcej o Angularze, ale ostatnie wygaśnięcie mojego rocznego darmowego planu na Azure oraz całkiem fajny pakiet webowy z kredytami na digitalocean (DigitalOcean: Cloud Computing, Simplicity at Scale) , który był na Humble Bundle… zmotywował mnie, aby trochę zabawić się w DEV OPS.
O instalacji dockerów na ubuntu wspominałem już wcześniej, ale przypomnę trochę tu o nim z miłym dodatkiem w postaci docker-compose. Do tego, co nieco o zabezpieczeniu za pomocą certyfikatu. Kod dostępny jak zawsze na github. Co ważniejsze, zmotywowało mnie to do pracy nad własnymi umiejętnościami oraz pogodzenie się z Ubuntu (Gdyż na Windows Home dockery nie działają, a SSH jest ubogie).

Czytaj dalej „.Net Core – DEV OPS for Dummies”

Własna Firma – Od Zera do Przedsiębiorcy

Własna Firma

Hej. Dzisiaj trochę zarządzania, czyli własna firma. Mija właśnie 5 miesięcy, odkąd prowadzę własną działalność gospodarczą. Opiszę w tym miejscu, dlaczego to się opłaca i nie jest tak straszne, jakby się mogło Wam wydawać. Wpis będzie dotyczyć działalności jednoosobowej. Wpis powstał na doświadczeniach  z moją firmą, warto skontaktować się z księgowością po więcej pytań

Czytaj dalej „Własna Firma – Od Zera do Przedsiębiorcy”