Setup K3s 1-node trên VPS 8GB: chơi Kubernetes không tốn nhiều

Chia sẻ bài viết

Mục lục
TL;DR
  • K3s single-node trên VPS 8GB đủ chạy Kubernetes thật để học và prod nhỏ.
  • Cài 1 lệnh curl, sẵn Traefik ingress, local-path storage, metrics-server.
  • RAM K3s ăn ~500MB, còn 7GB cho app pods.
  • Học K8s manifest, Helm chart, kubectl trên cluster thật trước khi lên EKS/GKE.
  • Chi phí VPS 8GB ~990k/tháng - tương đương cafe mỗi ngày, học K8s pro level.

Dev VN muốn học Kubernetes nhưng EKS/GKE/AKS tốn 200-500 USD/tháng cho cluster test. Minikube/Kind chạy local ăn RAM laptop, không deploy được. K3s 1-node trên VPS 8GB là sweet spot: Kubernetes thật, public IP, persistent, chi phí 990k/tháng.

K3s là distro Kubernetes nhẹ của Rancher: binary 50MB, RAM ~500MB master + worker chung. Sẵn Traefik ingress, local-path provisioner, CoreDNS, metrics-server. Compatible 95% K8s API thường.

Bài này hướng dẫn full setup K3s single-node trên Cloud VPS TND 8GB Ubuntu 24.04: install, kubectl, deploy app, Helm chart, monitoring, backup. Đủ cho học + chạy app personal/portfolio.

1. Yêu cầu VPS

  • VPS 8GB RAM, 2-4 vCPU (4GB chạy được nhưng ít app pods).
  • Ubuntu 24.04 hoặc Debian 12 (K3s test kỹ nhất).
  • 20GB disk minimum (Docker image + volume).
  • Public IP và domain để expose qua ingress.

2. Cài K3s 1 lệnh

curl -sfL https://get.k3s.io | sh -

# Verify
sudo k3s kubectl get nodes
# NAME    STATUS   ROLES                  AGE   VERSION
# vps01   Ready    control-plane,master   30s   v1.32.0+k3s1

sudo systemctl status k3s

30 giây xong. K3s sẵn Traefik, local-path storage, CoreDNS. So với cài kubeadm tay mất 1-2 giờ.

3. Setup kubectl alias và config

# Tạo alias kubectl cho user thường
echo 'alias kubectl="sudo k3s kubectl"' >> ~/.bashrc

# Hoặc copy kubeconfig về home dir
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config

# Test
kubectl get pods -A
kubectl version

4. Cài Helm để deploy chart

curl https://baltocdn.com/helm/signing.asc | sudo apt-key add -
echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt update
sudo apt install -y helm

helm version

5. Deploy app đầu tiên: Nginx demo

# nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 64Mi
            cpu: 100m
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
spec:
  ingressClassName: traefik
  rules:
  - host: demo.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx-svc
            port:
              number: 80

# Apply
kubectl apply -f nginx-deploy.yaml

# Verify
kubectl get pods
kubectl get svc
kubectl get ingress

Trỏ DNS demo.yourdomain.com -> IP VPS. Traefik tự nhận route, serve trang Welcome to nginx.

6. Auto SSL với cert-manager

# Cài cert-manager qua Helm
kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager 
  --namespace cert-manager 
  --set installCRDs=true

# Tạo ClusterIssuer Let Encrypt
# letsencrypt-prod.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: traefik

kubectl apply -f letsencrypt-prod.yaml

Thêm annotation vào Ingress để auto cấp SSL:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: traefik
  tls:
  - hosts:
    - demo.yourdomain.com
    secretName: demo-tls
  rules:
  - host: demo.yourdomain.com
    http: ...

7. Persistent volume với local-path

# K3s mặc định có local-path StorageClass
kubectl get sc
# NAME                 PROVISIONER          ...
# local-path (default) rancher.io/local-path

# PVC mẫu
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 5Gi

kubectl apply -f data-pvc.yaml
kubectl get pvc

Local-path lưu data ở /var/lib/rancher/k3s/storage/. Đơn giản, không distributed như Ceph - phù hợp single-node.

8. Deploy Postgres + Redis qua Helm

# Postgres Bitnami chart
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install postgres bitnami/postgresql 
  --set auth.postgresPassword=strong_pwd 
  --set primary.persistence.size=5Gi

# Redis
helm install redis bitnami/redis 
  --set auth.password=strong_pwd 
  --set replica.replicaCount=0

# Verify
kubectl get pods
kubectl get pvc

9. Deploy Next.js app từ Docker Hub

# nextjs-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nextjs-app
spec:
  replicas: 1
  selector:
    matchLabels: {app: nextjs}
  template:
    metadata:
      labels: {app: nextjs}
    spec:
      containers:
      - name: app
        image: ghcr.io/yourname/myapp:latest
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_URL
          value: postgres://postgres:strong_pwd@postgres-postgresql:5432/postgres
        - name: REDIS_URL
          value: redis://:strong_pwd@redis-master:6379
        resources:
          limits:
            memory: 512Mi
            cpu: 500m

kubectl apply -f nextjs-deploy.yaml
kubectl logs -f deployment/nextjs-app

10. Monitoring với Prometheus + Grafana

kubectl create namespace monitoring

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install kps prometheus-community/kube-prometheus-stack 
  --namespace monitoring 
  --set grafana.adminPassword=admin_pwd 
  --set prometheus.prometheusSpec.retention=7d 
  --set prometheus.prometheusSpec.resources.requests.memory=512Mi

# Expose Grafana qua Ingress
kubectl expose svc kps-grafana --name grafana -n monitoring --type=LoadBalancer

# Truy cập Grafana qua port-forward (dev)
kubectl port-forward -n monitoring svc/kps-grafana 3000:80

11. K9s - TUI để quản lý cluster

curl -sS https://webinstall.dev/k9s | bash
k9s

# Hotkey:
# :pods enter -> list pods
# d -> describe
# l -> logs
# s -> shell
# y -> YAML

K9s là TUI tốt nhất cho dev. Thay phải gõ kubectl get/describe/logs dài dòng, dùng K9s navigate bằng phím rất nhanh.

12. Backup cluster với Velero hoặc rclone

# Simple backup: tar /var/lib/rancher/k3s
sudo systemctl stop k3s
sudo tar -czf /tmp/k3s-backup-$(date +%F).tar.gz /var/lib/rancher/k3s /etc/rancher/k3s
sudo systemctl start k3s

# Upload S3
rclone copy /tmp/k3s-backup-*.tar.gz r2:my-bucket/k3s/

# Cao cấp hơn: Velero backup tới S3
helm repo add vmware-tanzu https://vmware-tanzu.github.io/helm-charts
helm install velero vmware-tanzu/velero 
  --namespace velero 
  --create-namespace 
  --set configuration.provider=aws 
  --set credentials.useSecret=true

13. So sánh K3s vs Docker Swarm cho single-node

Tiêu chíK3s single-nodeDocker Swarm single-node
Setup time30 giây15 giây
RAM overhead~500MB~50MB
Learning valueCao (skill K8s)Trung bình
Helm chart1000+ chartKhông có
Auto SSLcert-managerCaddy/Nginx tay
Manifest verbosityYAML dàiCompose ngắn
Career value 2026K8s phổ biếnNiche hơn

14. Limitations của single-node

  • Không có HA - node down là cluster down.
  • Không học được multi-node feature: Pod affinity, node selector.
  • Local-path storage không replicate - mất disk là mất data.
  • Không test được rolling update zero-downtime đúng nghĩa.

Khi quen K3s single, có thể scale ra 3 VPS làm HA cluster với embedded etcd.

Cloud VPS cho vibe coder

Học và chạy Kubernetes thật chỉ 990k/tháng

Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày, network 200Mbps trong nước. VPS 8GB thoải mái chạy K3s + 10-15 app pods, học K8s pro level mà không tốn EKS.

Xem 8 cấu hình Cloud VPS →

FAQ

K3s có thật sự là Kubernetes hay phiên bản con?

K3s là CNCF certified Kubernetes distribution. Strip bớt cloud provider plugin (AWS EBS, GCP PD) không cần cho self-host. API 95% compatible. Manifest viết cho K3s chạy được trên EKS/GKE thực tế.

VPS 4GB chạy được K3s không?

Được nhưng giới hạn. K3s ăn 500MB, còn 3.5GB cho app. Đủ cho 3-5 pod nhỏ. 8GB thoải mái hơn cho 10-15 pod kèm monitoring.

Có thể migrate K3s lên cluster K8s thật (EKS) không?

Có. Manifest YAML chuyển được nguyên. Khác biệt: StorageClass (EBS thay local-path), LoadBalancer (AWS ELB tự cấp). Code app không cần đổi.

Traefik mặc định có đủ cho production không?

Đủ. Traefik v3 mạnh, auto Let Encrypt, middleware rate limit/auth/CORS. Cho startup nhỏ thì không cần Nginx Ingress phức tạp hơn.

Học K3s mất bao lâu để thành thạo?

1-2 tuần để hiểu basic: pod, deployment, service, ingress, configmap, secret. 1-2 tháng cho advanced: Helm, operator, RBAC, network policy, service mesh. Đầu tư đáng vì K8s skill còn dài 10+ năm.

K3s có lưu trữ secret an toàn không?

Secret default chỉ base64 encode (không phải encryption). Cho production nên enable encryption-at-rest: --secrets-encryption flag, hoặc dùng external secret store (Vault, Sealed Secrets).