Uncloud 叢集管理
uc CLI 的參考文件 — 一個使用 Docker 容器、WireGuard 網狀網路與 Caddy 反向代理的去中心化自託管平台。
何時啟動
在處理 Uncloud 叢集時使用此技能,特別是當您需要:
- 使用
uc machine引導或加入機器到叢集 - 使用
uc deploy從 Compose 檔案部署服務 - 透過 Uncloud 發布 HTTP、HTTPS、TCP 或 UDP 連接埠
- 使用
x-caddy、x-ports或--caddyfile設定 Caddy 入口 - 將外部 LAN 設備透過叢集代理進行路由
- 檢查日誌、服務狀態、磁碟區、DNS 或機器放置
運作方式
Uncloud 在由 WireGuard 網狀網路連接的對等機器上運行 Docker 服務。每台機器都是平等的叢集成員;服務在覆蓋網路上通訊,而 Caddy 全域運行以終止公開的 HTTP/HTTPS 流量。Compose 檔案可以使用 Uncloud 擴展來進行入口、放置與產生的 Caddy 設定,而 uc CLI 則負責處理映像檔分發、排程、擴展、日誌與叢集狀態。
範例
uc machine init user@host --name machine-1
uc service run --name web -p app.example.com:8080/https nginx:latest
uc deploy
核心概念
- 無中央控制平面 — 所有機器都是透過 WireGuard 連接的平等對等節點
- Caddy 作為全域服務在每台機器上運行;自動從 Let's Encrypt 取得 TLS
- 覆蓋網路 — 服務預設透過
10.210.0.0/16通訊;網狀網路內提供 DNS - Caddyfile 是自動產生的 — 永遠不要直接編輯它;請使用
x-caddy/--caddyfile
CLI 快速參考
機器
| 指令 | 用途 |
|---|---|
uc machine init user@host | 引導第一台機器 / 新叢集 |
uc machine add user@host | 將機器加入現有叢集 |
uc machine ls | 列出機器 |
uc machine update NAME --public-ip IP | 更新入口的公開 IP |
uc machine rm NAME | 移除機器 |
關鍵 init 標誌:--name、--network 10.210.0.0/16、--no-caddy、--no-dns、--public-ip auto|IP|none
服務
| 指令 | 用途 |
|---|---|
uc service ls / uc ls | 列出服務 |
uc service run IMAGE | 運行單一容器服務 |
uc deploy | 從 compose.yaml 部署 |
uc deploy --no-build | 部署已推送的映像檔而不重新建置 |
uc deploy --recreate | 強制重建服務 |
uc scale SERVICE N | 設定副本數量 |
uc service logs SERVICE | 檢視日誌 |
uc service exec SERVICE | 啟動容器 shell |
uc service inspect SERVICE | 詳細資訊 |
uc service rm SERVICE | 移除服務(保留有名稱的磁碟區) |
uc ps | 跨叢集的所有容器 |
映像檔
uc image push myapp:latest # 將本機映像檔推送至所有機器
uc image push myapp:latest -m machine1,machine2 # 推送至特定機器
uc images # 列出叢集中的映像檔
磁碟區
uc volume ls # 所有磁碟區
uc volume ls -m machine1 # 在特定機器上
uc volume create NAME -m MACHINE
uc volume rm NAME
Caddy
uc caddy config # 顯示目前產生的 Caddyfile(唯讀)
uc caddy deploy # 跨叢集部署/升級 Caddy
DNS 與上下文
uc dns show # 顯示保留的 *.uncld.dev 網域
uc dns reserve # 保留新網域
uc ctx ls # 列出叢集上下文
uc ctx use prod # 切換上下文
連接埠發布
HTTP/HTTPS(經由 Caddy 反向代理)
-p [hostname:]container_port[/protocol]
| 範例 | 意義 |
|---|---|
-p 8080/https | HTTPS,自動使用 service-name.cluster-domain 主機名稱 |
-p app.example.com:8080/https | HTTPS,自訂主機名稱 |
-p 8080/http | 僅 HTTP,無 TLS |
TCP/UDP(繫結至主機,繞過 Caddy)
-p [host_ip:]host_port:container_port[/protocol]@host
| 範例 | 意義 |
|---|---|
-p 5432:5432@host | TCP 5432,在所有介面上 |
-p 127.0.0.1:5432:5432@host | TCP 5432,僅回送 |
-p 53:5353/udp@host | UDP |
Compose 檔案擴展
Uncloud 在 Docker Compose 之上新增了這些擴展:
x-ports — 使用網域發布連接埠
services:
app:
image: app:latest
x-ports:
- example.com:8000/https
- www.example.com:8000/https
- api.example.com:9000/https
x-caddy — 服務的自訂 Caddy 設定
services:
app:
image: app:latest
x-caddy: |
example.com {
redir https://www.example.com{uri} permanent
}
www.example.com {
reverse_proxy {{upstreams 8000}} {
import common_proxy
}
basic_auth /admin/* {
admin $2a$14$...
}
}
可在 x-caddy 內部使用的範本函式:
{{upstreams [service] [port]}}— 健康容器的 IP{{.Name}}— 服務名稱{{.Upstreams}}— 所有服務到 IP 的對應
x-machines — 放置限制
services:
db:
image: postgres:18
x-machines: db-machine # 單一機器名稱
app:
image: app:latest
x-machines:
- machine-1
- machine-2
完整的多服務範例
services:
api:
build: ./api
x-ports:
- api.example.com:3000/https
environment:
DATABASE_URL: postgres://db:5432/mydb
web:
build: ./web
x-ports:
- example.com:8000/https
- www.example.com:8000/https
environment:
API_URL: http://api:3000
db:
image: postgres:18
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
x-machines: db-machine
volumes:
db-data:
路由至外部(非叢集)設備
若要透過 Caddy 曝露外部設備(例如 BMC、NAS、路由器 UI)而不運行真正的容器:
1. 建立 Caddyfile 片段(例如 ~/device.caddyfile):
https://device.example.com {
reverse_proxy https://192.168.1.x {
transport http {
tls_insecure_skip_verify # 自簽 BMC 憑證需要
}
}
log
}
對於明文上游:reverse_proxy http://192.168.1.x:port
2. 使用空操作容器註冊為具名服務:
uc service run \
--name device-bmc \
--caddyfile ~/device.caddyfile \
registry.k8s.io/pause:3.9
pause 是一個最小的空操作容器 — 它什麼都不做,但為 Uncloud 提供一個服務條目來附加 Caddyfile。
3. 驗證:
uc caddy config # 應顯示 device.example.com 區塊
--caddyfile無法與非@host的已發布連接埠結合使用。
DNS 提示: 萬用字元記錄(*.yourdomain.com → cluster-public-ip)表示任何新的子網域可立即生效 — 無需為每個服務更改 DNS。
服務 DNS(內部)
叢集內的服務可以透過名稱互相解析:
| DNS 名稱 | 解析至 |
|---|---|
service-name | 任何健康容器 |
service-name.internal | 同上 |
rr.service-name.internal | 輪詢 |
nearest.service-name.internal | 優先本地機器 |
擴展與全域服務
uc scale web 5 # 5 個副本(分散於各機器)
uc scale web 1 # 縮減
services:
caddy:
deploy:
mode: global # 每台機器上一個容器
映像檔標籤範本(在 compose.yaml 中)
image: myapp:{{gitdate "20060102"}}.{{gitsha 7}}
image: myapp:{{gitsha 7}}.${GITHUB_RUN_ID:-local}
| 函式 | 輸出 |
|---|---|
{{gitsha N}} | 提交 SHA 的前 N 個字元 |
{{gitdate "format"}} | 以 Go 格式顯示的 Git 提交日期 |
{{date "format"}} | 目前日期 |
常見工作流程
從原始碼部署:
uc deploy # 建置 + 推送 + 部署
uc build --push && uc deploy --no-build # 分開執行步驟
檢查服務:
uc inspect web
uc logs -f web
uc logs --since 1h web
uc exec web # 開啟 shell
uc exec web /bin/sh -c "env" # 執行特定指令
零停機部署會自動發生;Uncloud 會等待健康檢查通過後才終止舊容器。
強制重建:
uc deploy --recreate
常見錯誤
| 錯誤 | 修正 |
|---|---|
| 直接編輯 Caddyfile | 在 compose 中使用 x-caddy,或在 uc service run 上使用 --caddyfile |
| 代理具有自簽憑證的 HTTPS 上游 | 加上 transport http { tls_insecure_skip_verify } |
uc caddy config 未顯示使用者定義的區塊 | Caddy 管理 socket 無法連線 — 檢查 uc inspect caddy 與 uc logs caddy |
| 服務無法從容器內連接到外部 LAN IP | 確認執行 Caddy 容器的主機能夠路由到目標網路 |
在 uc service rm 後磁碟區遺失 | 有名稱的磁碟區會保留;只有匿名磁碟區會自動移除 |