Some checks failed
CD Pipeline / deploy (push) Failing after 59s
- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
213 lines
5.6 KiB
Bash
213 lines
5.6 KiB
Bash
#!/bin/bash
|
||
# ==========================================================
|
||
# Docker 服務遷移到 K8s 腳本
|
||
# 用途:將 n8n 和 Superset 從 Docker 遷移到 K8s
|
||
# ==========================================================
|
||
|
||
set -e
|
||
|
||
BACKUP_DIR="/home/wooo/backups/k8s-migration"
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
KUBECONFIG="/home/wooo/.kube/config"
|
||
|
||
log() {
|
||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
|
||
}
|
||
|
||
error() {
|
||
echo "[ERROR] $1" >&2
|
||
exit 1
|
||
}
|
||
|
||
# 確認執行
|
||
confirm() {
|
||
read -p "$1 (y/N): " response
|
||
case "$response" in
|
||
[yY][eE][sS]|[yY]) return 0 ;;
|
||
*) return 1 ;;
|
||
esac
|
||
}
|
||
|
||
# 步驟 1:備份資料
|
||
backup_data() {
|
||
log "=== 步驟 1:備份資料 ==="
|
||
|
||
mkdir -p "$BACKUP_DIR"
|
||
|
||
# 備份 n8n
|
||
log "備份 n8n 資料..."
|
||
docker run --rm -v n8n_data:/data -v "$BACKUP_DIR":/backup \
|
||
alpine tar czf "/backup/n8n_data_${DATE}.tar.gz" -C /data .
|
||
log "✅ n8n 備份完成: $BACKUP_DIR/n8n_data_${DATE}.tar.gz"
|
||
|
||
# 備份 Superset PostgreSQL
|
||
log "備份 Superset PostgreSQL..."
|
||
docker exec superset-postgres pg_dump -U superset superset > \
|
||
"$BACKUP_DIR/superset_db_${DATE}.sql"
|
||
log "✅ Superset DB 備份完成: $BACKUP_DIR/superset_db_${DATE}.sql"
|
||
|
||
# 備份 Superset home
|
||
log "備份 Superset home..."
|
||
docker run --rm -v superset_superset_home:/data -v "$BACKUP_DIR":/backup \
|
||
alpine tar czf "/backup/superset_home_${DATE}.tar.gz" -C /data .
|
||
log "✅ Superset home 備份完成"
|
||
|
||
log "=== 備份完成 ==="
|
||
ls -la "$BACKUP_DIR"
|
||
}
|
||
|
||
# 步驟 2:部署 K8s 服務
|
||
deploy_k8s() {
|
||
log "=== 步驟 2:部署 K8s 服務 ==="
|
||
|
||
export KUBECONFIG="$KUBECONFIG"
|
||
|
||
# 建立 namespace
|
||
log "建立 tools namespace..."
|
||
kubectl apply -f /home/wooo/momo_pro_system/k8s/tools/00-namespace.yaml
|
||
|
||
# 部署 n8n
|
||
log "部署 n8n..."
|
||
kubectl apply -f /home/wooo/momo_pro_system/k8s/tools/01-n8n.yaml
|
||
|
||
# 部署 Superset
|
||
log "部署 Superset..."
|
||
kubectl apply -f /home/wooo/momo_pro_system/k8s/tools/02-superset.yaml
|
||
|
||
# 等待 Pod 就緒
|
||
log "等待 Pod 就緒..."
|
||
kubectl wait --for=condition=ready pod -l app=n8n -n tools --timeout=300s || true
|
||
kubectl wait --for=condition=ready pod -l app=superset -n tools --timeout=300s || true
|
||
|
||
log "=== K8s 部署完成 ==="
|
||
kubectl get pods -n tools
|
||
}
|
||
|
||
# 步驟 3:還原資料到 K8s
|
||
restore_data() {
|
||
log "=== 步驟 3:還原資料 ==="
|
||
|
||
export KUBECONFIG="$KUBECONFIG"
|
||
|
||
# 取得 n8n PVC 路徑
|
||
N8N_PV=$(kubectl get pvc n8n-data -n tools -o jsonpath='{.spec.volumeName}')
|
||
N8N_PATH="/var/lib/rancher/k3s/storage/${N8N_PV}"
|
||
|
||
# 還原 n8n 資料
|
||
log "還原 n8n 資料..."
|
||
LATEST_N8N=$(ls -t "$BACKUP_DIR"/n8n_data_*.tar.gz | head -1)
|
||
if [ -f "$LATEST_N8N" ]; then
|
||
sudo tar xzf "$LATEST_N8N" -C "$N8N_PATH"
|
||
log "✅ n8n 資料已還原"
|
||
fi
|
||
|
||
# 重啟 n8n Pod 以載入資料
|
||
kubectl rollout restart deployment/n8n -n tools
|
||
|
||
log "=== 資料還原完成 ==="
|
||
}
|
||
|
||
# 步驟 4:更新 Nginx
|
||
update_nginx() {
|
||
log "=== 步驟 4:更新 Nginx 配置 ==="
|
||
|
||
# 取得 K8s Service ClusterIP
|
||
export KUBECONFIG="$KUBECONFIG"
|
||
N8N_IP=$(kubectl get svc n8n -n tools -o jsonpath='{.spec.clusterIP}')
|
||
SUPERSET_IP=$(kubectl get svc superset -n tools -o jsonpath='{.spec.clusterIP}')
|
||
|
||
log "n8n ClusterIP: $N8N_IP"
|
||
log "Superset ClusterIP: $SUPERSET_IP"
|
||
|
||
log "請手動更新 /etc/nginx/sites-enabled/monitor:"
|
||
log " n8n_backend: $N8N_IP:5678"
|
||
log " superset_backend: $SUPERSET_IP:8088"
|
||
|
||
log "=== Nginx 更新提示完成 ==="
|
||
}
|
||
|
||
# 步驟 5:停止 Docker 服務
|
||
stop_docker() {
|
||
log "=== 步驟 5:停止 Docker 服務 ==="
|
||
|
||
if confirm "確定要停止 Docker 服務嗎?"; then
|
||
docker stop momo-n8n momo-superset superset-postgres superset-redis 2>/dev/null || true
|
||
log "✅ Docker 服務已停止"
|
||
else
|
||
log "跳過停止 Docker 服務"
|
||
fi
|
||
}
|
||
|
||
# 顯示狀態
|
||
show_status() {
|
||
log "=== 當前狀態 ==="
|
||
|
||
echo ""
|
||
echo "Docker 容器:"
|
||
docker ps --format "table {{.Names}}\t{{.Status}}" | grep -E "n8n|superset" || echo "無相關容器"
|
||
|
||
echo ""
|
||
echo "K8s Pods:"
|
||
export KUBECONFIG="$KUBECONFIG"
|
||
kubectl get pods -n tools 2>/dev/null || echo "tools namespace 不存在"
|
||
}
|
||
|
||
# 主選單
|
||
main() {
|
||
echo "========================================"
|
||
echo " Docker → K8s 遷移工具"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "1) 備份資料"
|
||
echo "2) 部署 K8s 服務"
|
||
echo "3) 還原資料到 K8s"
|
||
echo "4) 更新 Nginx 配置"
|
||
echo "5) 停止 Docker 服務"
|
||
echo "6) 顯示當前狀態"
|
||
echo "7) 完整遷移 (1-5)"
|
||
echo "0) 退出"
|
||
echo ""
|
||
|
||
read -p "請選擇操作: " choice
|
||
|
||
case $choice in
|
||
1) backup_data ;;
|
||
2) deploy_k8s ;;
|
||
3) restore_data ;;
|
||
4) update_nginx ;;
|
||
5) stop_docker ;;
|
||
6) show_status ;;
|
||
7)
|
||
backup_data
|
||
deploy_k8s
|
||
restore_data
|
||
update_nginx
|
||
stop_docker
|
||
;;
|
||
0) exit 0 ;;
|
||
*) error "無效選項" ;;
|
||
esac
|
||
}
|
||
|
||
# 如果有參數,直接執行對應步驟
|
||
if [ -n "$1" ]; then
|
||
case $1 in
|
||
backup) backup_data ;;
|
||
deploy) deploy_k8s ;;
|
||
restore) restore_data ;;
|
||
nginx) update_nginx ;;
|
||
stop) stop_docker ;;
|
||
status) show_status ;;
|
||
all)
|
||
backup_data
|
||
deploy_k8s
|
||
restore_data
|
||
update_nginx
|
||
stop_docker
|
||
;;
|
||
*) echo "用法: $0 [backup|deploy|restore|nginx|stop|status|all]" ;;
|
||
esac
|
||
else
|
||
main
|
||
fi
|