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 파일은 인그레스, 배치 및 생성된 Caddy 구성을 위해 Uncloud 확장을 사용할 수 있으며, 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 | 컨테이너 셸 접속 |
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 | 자동 service-name.cluster-domain 호스트명으로 HTTPS |
-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. no-op 컨테이너로 명명된 서비스로 등록:
uc service run \
--name device-bmc \
--caddyfile ~/device.caddyfile \
registry.k8s.io/pause:3.9
pause는 최소한의 no-op 컨테이너입니다. 아무것도 하지 않지만 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 # 셸 열기
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 관리 소켓에 연결할 수 없음 — uc inspect caddy 및 uc logs caddy 확인 |
| 컨테이너에서 외부 LAN IP에 도달할 수 없음 | Caddy 컨테이너의 호스트가 대상 네트워크로 라우팅할 수 있는지 확인 |
uc service rm 후 볼륨 손실 | 명명된 볼륨은 유지되며, 익명 볼륨만 자동 제거됨 |