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 與 Context
uc dns show # 顯示保留的 *.uncld.dev 網域
uc dns reserve # 保留新網域
uc ctx ls # 列出集群 context
uc ctx use prod # 切換 context
連接埠發布
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、路由器介面),而無需執行實際容器,請執行以下步驟:
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"}} | Git 提交日期(Go 格式) |
{{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 後磁碟區遺失 | 具名磁碟區會保留;只有匿名磁碟區會自動移除 |