← Quay lại Blog
navigationdevopsfleetkubernetes

Docker + K3s trên edge: GitOps cho robot fleet

Hướng dẫn triển khai Docker và K3s trên edge device — quản lý, cập nhật OTA và giám sát hàng trăm robot với GitOps workflow.

Nguyễn Anh Tuấn10 tháng 3, 20268 phút đọc
Docker + K3s trên edge: GitOps cho robot fleet

Tại sao K3s cho edge robot fleet?

Quản lý Docker trên một edge device thì đơn giản — nhưng khi fleet mở rộng lên 50, 100 hay 500 robot, bạn cần một orchestrator. K3s là bản Kubernetes siêu nhẹ, được Rancher (nay thuộc SUSE) phát triển riêng cho edge và IoT. Binary chỉ ~70MB, chạy mượt trên ARM64 với 512MB RAM — lý tưởng cho các robot chạy Jetson Nano, Raspberry Pi hay bất kỳ SBC nào.

So với K8s đầy đủ, K3s loại bỏ các thành phần không cần thiết ở edge (cloud controller, storage driver nặng) và thay etcd bằng SQLite hoặc embedded etcd nhẹ hơn nhiều. Kết quả: bạn có đầy đủ Kubernetes API mà không cần server beefy.

Server rack và edge device trong hệ thống robot công nghiệp

Kiến trúc: Control plane + K3s agents

Mô hình triển khai cho robot fleet gồm 2 tầng:

┌──────────────────────────────────────────────┐
│          CONTROL PLANE (Cloud/Server)         │
│  ┌────────────┐ ┌──────────┐ ┌─────────────┐│
│  │ K3s Server │ │ FluxCD   │ │ Prometheus  ││
│  │ (API)      │ │ (GitOps) │ │ + Grafana   ││
│  └────────────┘ └──────────┘ └─────────────┘│
│          │          │              │          │
│          ▼          ▼              ▼          │
│      ┌─────── Tailscale VPN Mesh ──────┐    │
└──────┼──────────────────────────────────┼────┘
       │                                  │
┌──────▼──────┐  ┌──────────────┐  ┌─────▼───────┐
│  Robot #1   │  │  Robot #2    │  │  Robot #N   │
│  K3s Agent  │  │  K3s Agent   │  │  K3s Agent  │
│  ARM64      │  │  ARM64       │  │  ARM64      │
│  Jetson     │  │  RPi 4       │  │  Jetson     │
└─────────────┘  └──────────────┘  └─────────────┘

Control plane chạy trên cloud server (có thể là OCI free tier ARM64) — nơi đặt K3s server, GitOps controller và monitoring stack. Mỗi robot chạy K3s agent, tự động join cluster qua VPN mesh.

Cài đặt K3s Server và Agent

K3s Server (trên cloud)

# Cài K3s server với embedded etcd
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="server \
  --cluster-init \
  --tls-san=k3s.vnrobo.com \
  --disable=traefik \
  --write-kubeconfig-mode=644" sh -

# Lấy token để agent join
cat /var/lib/rancher/k3s/server/node-token

K3s Agent (trên mỗi robot)

# Cài K3s agent — chỉ 1 dòng lệnh
curl -sfL https://get.k3s.io | K3S_URL="https://k3s.vnrobo.com:6443" \
  K3S_TOKEN="<server-token>" \
  INSTALL_K3S_EXEC="agent \
    --node-label=robot-type=welding \
    --node-label=factory=hanoi-01 \
    --node-label=zone=production" sh -

Label giúp bạn target deployment đến nhóm robot cụ thể — ví dụ chỉ update robot hàn ở nhà máy Hà Nội.

Docker Multi-stage Build cho ARM64

Mỗi robot chạy container application riêng. Multi-stage build giữ image nhỏ gọn cho edge:

# === Build stage ===
FROM --platform=$TARGETPLATFORM python:3.11-slim AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

COPY src/ ./src/
# Pre-compile Python files
RUN python -m compileall src/

# === Runtime stage ===
FROM --platform=$TARGETPLATFORM python:3.11-slim

RUN groupadd -r robot && useradd -r -g robot -d /app robot
COPY --from=builder /install /usr/local
COPY --from=builder /app/src /app/src

WORKDIR /app
USER robot

HEALTHCHECK --interval=30s --timeout=5s \
  CMD python -c "import requests; requests.get('http://localhost:8080/health')"

CMD ["python", "src/main.py"]

Build multi-arch và push lên registry:

# Tạo buildx builder
docker buildx create --name fleet-builder --use

# Build ARM64 + AMD64, push lên ghcr.io
docker buildx build \
  --platform linux/arm64,linux/amd64 \
  -t ghcr.io/vnrobo/robot-controller:v2.1.0 \
  -t ghcr.io/vnrobo/robot-controller:latest \
  --push .

Image chỉ ~85MB thay vì ~900MB — tiết kiệm băng thông khi OTA update qua 4G/5G.

FluxCD: GitOps cho robot fleet

GitOps nghĩa là Git repository là single source of truth. Bạn push manifest vào Git, FluxCD tự động reconcile cluster state. Không SSH vào từng robot, không chạy kubectl apply thủ công.

Cài đặt FluxCD

# Bootstrap FluxCD vào K3s cluster
flux bootstrap github \
  --owner=vnrobo \
  --repository=fleet-config \
  --path=clusters/production \
  --personal

Cấu trúc Git repository

fleet-config/
├── clusters/
│   └── production/
│       ├── flux-system/         # FluxCD components
│       └── kustomization.yaml   # Entry point
├── apps/
│   ├── robot-controller/
│   │   ├── deployment.yaml
│   │   ├── service.yaml
│   │   └── kustomization.yaml
│   └── telemetry-agent/
│       ├── daemonset.yaml
│       └── kustomization.yaml
└── infrastructure/
    ├── monitoring/
    │   ├── prometheus.yaml
    │   └── grafana.yaml
    └── networking/
        └── tailscale.yaml

Kubernetes Manifests cho robot

# apps/robot-controller/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: robot-controller
  namespace: fleet
spec:
  replicas: 1  # 1 per robot node
  selector:
    matchLabels:
      app: robot-controller
  template:
    metadata:
      labels:
        app: robot-controller
    spec:
      nodeSelector:
        robot-type: welding        # Chỉ deploy lên robot hàn
      tolerations:
        - key: "edge"
          operator: "Exists"
      containers:
        - name: controller
          image: ghcr.io/vnrobo/robot-controller:v2.1.0
          resources:
            limits:
              memory: "256Mi"
              cpu: "500m"
            requests:
              memory: "128Mi"
              cpu: "250m"
          env:
            - name: ROBOT_ID
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: MQTT_BROKER
              value: "mqtt.vnrobo.com"
          ports:
            - containerPort: 8080
          livenessProbe:
            httpGet:
              path: /health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 30

Dashboard giám sát hệ thống và metrics trên màn hình

OTA Updates: Rolling và Canary

Rolling Update — cập nhật tuần tự

Mặc định K8s rolling update sẽ update từng pod một. Với robot fleet, bạn muốn kiểm soát chặt hơn:

# apps/robot-controller/deployment.yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1       # Tối đa 1 robot offline cùng lúc
      maxSurge: 0             # Không tạo pod mới (edge không dư resource)

Canary Deployment — thử nghiệm trên vài robot trước

Dùng Flagger (add-on của FluxCD) để canary:

# apps/robot-controller/canary.yaml
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: robot-controller
  namespace: fleet
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: robot-controller
  progressDeadlineSeconds: 600
  analysis:
    interval: 60s
    threshold: 3              # 3 lần fail → rollback
    iterations: 5             # 5 vòng kiểm tra
    metrics:
      - name: error-rate
        thresholdRange:
          max: 1              # Rollback nếu error > 1%
        interval: 60s
      - name: latency-p99
        thresholdRange:
          max: 500            # Rollback nếu p99 > 500ms
        interval: 60s

Workflow canary: push image mới lên Git, FluxCD detect thay đổi, Flagger deploy lên 10% robot, monitor metrics, nếu OK thì tiếp tục rollout, nếu lỗi thì tự động rollback. Zero human intervention.

Monitoring: Prometheus + Grafana trên edge

Mỗi robot expose metrics qua /metrics endpoint. Prometheus trên control plane scrape qua VPN:

# infrastructure/monitoring/prometheus-scrape.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: robot-metrics
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: robot-controller
  endpoints:
    - port: metrics
      interval: 30s
      path: /metrics
  namespaceSelector:
    matchNames:
      - fleet

Metrics cần thu thập từ robot:

Metric Mô tả Alert threshold
robot_cpu_temp Nhiệt độ CPU > 80°C
robot_battery_pct Pin còn lại < 20%
robot_task_latency_ms Độ trễ xử lý > 200ms (p95)
robot_connection_status Trạng thái kết nối == 0 (offline)
robot_error_count Số lỗi tích lũy > 10/phút

Grafana dashboard hiển thị fleet overview: bản đồ nhà máy với trạng thái real-time của từng robot, biểu đồ lịch sử performance, và alert khi có robot bất thường.

Networking: Tailscale VPN Mesh

Robot trong nhà máy thường nằm sau NAT, firewall phức tạp. Tailscale (built on WireGuard) tạo mesh VPN peer-to-peer — mỗi robot kết nối trực tiếp đến control plane mà không cần mở port:

# Trên mỗi robot — 1 lệnh duy nhất
curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --authkey=tskey-auth-xxxxx --hostname=robot-$(hostname)

Ưu điểm so với VPN truyền thống:

Nếu bạn muốn tự host, Headscale là bản open-source thay thế Tailscale server.

Quy trình deploy end-to-end

Tóm tắt toàn bộ workflow từ code đến robot:

Developer push code
       │
       ▼
GitHub Actions: build + test + push ARM64 image
       │
       ▼
Developer cập nhật image tag trong fleet-config repo
       │
       ▼
FluxCD detect thay đổi (poll mỗi 60s)
       │
       ▼
Flagger canary deploy: 10% robot
       │
       ▼
Prometheus check metrics (5 vòng × 60s)
       │
       ├── OK → Rollout 100% fleet
       └── FAIL → Auto rollback

Toàn bộ quá trình không cần SSH vào bất kỳ robot nào. Bạn chỉ cần push code và push manifest — hệ thống tự lo phần còn lại.

Kết luận

Docker + K3s + FluxCD là combo mạnh mẽ cho robot fleet management. K3s mang sức mạnh Kubernetes xuống edge device nhỏ gọn, FluxCD biến Git thành single source of truth, và Tailscale giải quyết bài toán networking phức tạp trong nhà máy. Với canary deployment và monitoring tự động, bạn có thể tự tin cập nhật hàng trăm robot mà không lo downtime.

Nếu fleet của bạn dưới 20 robot, Docker Compose + Watchtower có thể đủ dùng (xem bài viết Docker cho IoT). Nhưng khi scale lên, K3s là bước tiến tự nhiên — và bạn sẽ không hối hận.


Bài viết liên quan

Bài viết liên quan

Multi-robot Coordination: Thuật toán phân công task
fleetamrprogramming

Multi-robot Coordination: Thuật toán phân công task

Các thuật toán phân công nhiệm vụ cho đội robot — từ Hungarian algorithm, auction-based đến RL-based task allocation.

20/3/202612 phút đọc
Wheeled Humanoid: Tương lai robot logistics và warehouse
humanoidfleetamr

Wheeled Humanoid: Tương lai robot logistics và warehouse

Robot hình người trên bánh xe — tại sao thiết kế hybrid này đang thay đổi ngành logistics và vận hành kho hàng.

3/3/202611 phút đọc
Tự động hóa nhà máy điện tử Bắc Ninh: Bài học thực tế
amrautomationfleet

Tự động hóa nhà máy điện tử Bắc Ninh: Bài học thực tế

Phân tích quá trình tự động hóa tại các nhà máy điện tử FDI ở Bắc Ninh — thách thức, giải pháp và bài học cho doanh nghiệp Việt.

19/2/202610 phút đọc