添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

233
qiming-rcoder/make/k8s.mk Normal file
View File

@@ -0,0 +1,233 @@
# ============================================================================
# K8s 开发/部署 Makefile (Kustomize)
# ============================================================================
IMAGE ?= rcoder:test-k8s
K8S_IMAGE_REGISTRY ?= nuwax-docker-images-registry.cn-hangzhou.cr.aliyuncs.com/dev/rcoder:latest
KUSTOMIZE_DIR ?= k8s/manifests
ROLLOUT_TIMEOUT ?= 180s
# Namespace 按 overlay 推导
K8S_NAMESPACE_DEV := nuwax-rcoder-dev
K8S_NAMESPACE_PROD := nuwax-rcoder-prod
# 本地 k3s 同步配置make dev-build-k8s 构建后自动 import 到本地 k3s
SUDO ?= sudo
K3S_CTR ?= $(SUDO) k3s ctr
K3S_NAMESPACE ?= k8s.io
# 设为 1 跳过本地 k3s import例如机器没装 k3s 或不想 import
SKIP_K3S_IMPORT ?= 0
# 设为 1 跳过 build 后自动 rollout restart
SKIP_ROLLOUT_RESTART ?= 0
# ============================================================================
# 镜像构建
# ============================================================================
dev-build-k8s: docker-build-master-base
@echo "☸️ 构建 K8s 镜像..."
@echo "📍 镜像名称: $(IMAGE)"
@echo "⏳ 这可能需要较长时间(包含 Rust 编译)..."
@docker build -f docker/rcoder-master/Dockerfile -t $(IMAGE) --build-arg CARGO_FLAGS="--features kubernetes" .
@echo "✅ K8s 镜像构建完成!"
@echo ""
@echo "📤 推送镜像到阿里云仓库..."
@docker tag $(IMAGE) $(K8S_IMAGE_REGISTRY)
@skopeo copy docker-daemon:$(K8S_IMAGE_REGISTRY) docker://$(K8S_IMAGE_REGISTRY)
@echo "✅ 镜像已推送到 $(K8S_IMAGE_REGISTRY)"
@$(MAKE) -s --no-print-directory _k8s-import-image
@$(MAKE) -s --no-print-directory _k8s-rollout-restart
@echo ""
@echo "💡 下一步: make dev-up-k8s 启动 K8s 开发模式 (镜像已就位)"
# 内部 target: 把刚构建的镜像直接导入本地 k3s containerd, 跳过 registry 网络往返
# 使用 docker save | k3s ctr image import, 完全离线
_k8s-import-image:
@if [ "$(SKIP_K3S_IMPORT)" = "1" ]; then \
echo ""; echo "⏭ 跳过 k3s 本地 import (SKIP_K3S_IMPORT=1)"; exit 0; \
fi
@if ! command -v k3s >/dev/null 2>&1; then \
echo ""; echo "⚠️ 未检测到 k3s (本机非 k3s 节点), 跳过本地 import"; \
echo " 远程 registry 已更新, 其他集群仍可正常拉取"; exit 0; \
fi
@echo ""
@echo "📥 导入镜像到本地 k3s containerd (跳过 registry 网络往返)..."
@echo " 方式: docker save | k3s ctr image import"
@docker save $(K8S_IMAGE_REGISTRY) | $(K3S_CTR) -n $(K3S_NAMESPACE) image import - >/dev/null
@echo "✅ 镜像已 import 到本地 k3s 节点 ($(K3S_NAMESPACE) namespace)"
# 内部 target: 重启已部署的 rcoder Deployment 使其拉取/使用新 image
# imagePullPolicy 是 IfNotPresent, 节点上已经是新 image, restart 后即生效
_k8s-rollout-restart:
@if [ "$(SKIP_ROLLOUT_RESTART)" = "1" ]; then \
echo "⏭ 跳过 rollout restart (SKIP_ROLLOUT_RESTART=1)"; exit 0; \
fi
@if ! command -v kubectl >/dev/null 2>&1; then exit 0; fi
@echo ""
@echo "🔄 重启已部署的 rcoder Deployment (使新镜像生效)..."
@for ns in $(K8S_NAMESPACE_DEV) $(K8S_NAMESPACE_PROD); do \
if kubectl get deploy rcoder -n $$ns >/dev/null 2>&1; then \
kubectl rollout restart deploy/rcoder -n $$ns >/dev/null && \
echo "$$ns: rollout restart 已触发"; \
else \
echo " - $$ns: deploy 不存在, 跳过"; \
fi; \
done
# ============================================================================
# 开发模式快捷命令 (默认指向 dev overlay)
# ============================================================================
# 启动 K8s 开发模式(使用 Kustomize dev overlay
dev-up-k8s:
@echo "☸️ 启动 K8s 开发模式 (overlays/dev -> $(K8S_NAMESPACE_DEV))..."
@echo ""
@echo "[1/4] 检查 JuiceFS CSI Driver..."
@kubectl rollout status daemonset/juicefs-csi-driver-node -n kube-system --timeout=120s 2>/dev/null || \
(echo "⚠️ JuiceFS CSI 未部署,请先执行: helm install juicefs-csi-driver juicefs/juicefs-csi-driver --namespace kube-system" && exit 1)
@echo ""
@echo "[2/4] 部署 dev overlay..."
@kubectl apply -k $(KUSTOMIZE_DIR)/overlays/dev
@echo ""
@echo "[3/4] 等待存储层就绪..."
@kubectl wait --for=condition=ready pod -l app=postgresql -n $(K8S_NAMESPACE_DEV) --timeout=180s 2>/dev/null || echo "⚠️ PostgreSQL 等待超时,继续..."
@kubectl wait --for=condition=ready pod -l app=minio -n $(K8S_NAMESPACE_DEV) --timeout=180s 2>/dev/null || echo "⚠️ MinIO 等待超时,继续..."
@kubectl wait --for=condition=complete job/minio-init -n $(K8S_NAMESPACE_DEV) --timeout=120s 2>/dev/null || echo "⚠️ MinIO 初始化等待超时,继续..."
@echo ""
@echo "[4/4] 等待 RCoder 就绪..."
@kubectl rollout status deploy/rcoder -n $(K8S_NAMESPACE_DEV) --timeout=$(ROLLOUT_TIMEOUT)
@echo ""
@echo "📋 K8s 部署状态:"
@kubectl get pods -n $(K8S_NAMESPACE_DEV)
@echo ""
@kubectl get pvc -n $(K8S_NAMESPACE_DEV)
@echo ""
@kubectl get storageclass | grep juice || true
@echo ""
@echo "💡 查看日志: make dev-logs-k8s"
# 重启 K8s 开发模式(重新构建镜像+部署)
dev-restart-k8s: dev-build-k8s
@echo "☸️ 重启 K8s 开发模式..."
@kubectl apply -k $(KUSTOMIZE_DIR)/overlays/dev
@kubectl delete pods -n $(K8S_NAMESPACE_DEV) -l app=rcoder --ignore-not-found
@kubectl rollout status deploy/rcoder -n $(K8S_NAMESPACE_DEV) --timeout=$(ROLLOUT_TIMEOUT)
@echo "✅ K8s 部署已重启!"
@kubectl get pods -n $(K8S_NAMESPACE_DEV)
# 停止 K8s 开发模式
dev-down-k8s:
@echo "☸️ 停止 K8s 开发模式..."
@kubectl delete -k $(KUSTOMIZE_DIR)/overlays/dev --ignore-not-found
@echo "✅ K8s 开发栈已从集群移除"
# 查看 K8s 开发模式日志
dev-logs-k8s:
@echo "☸️ 查看 K8s 开发模式日志..."
@kubectl logs -n $(K8S_NAMESPACE_DEV) -l app=rcoder -f
# ============================================================================
# 多环境部署命令
# ============================================================================
# 部署开发环境
deploy-dev:
@echo "☸️ 部署开发环境..."
@kubectl apply -k $(KUSTOMIZE_DIR)/overlays/dev
@kubectl rollout status deploy/rcoder -n $(K8S_NAMESPACE_DEV) --timeout=$(ROLLOUT_TIMEOUT)
@echo "✅ 开发环境部署完成!"
# 部署生产环境
deploy-prod:
@echo "☸️ 部署生产环境..."
@kubectl apply -k $(KUSTOMIZE_DIR)/overlays/prod
@kubectl rollout status deploy/rcoder -n $(K8S_NAMESPACE_PROD) --timeout=$(ROLLOUT_TIMEOUT)
@echo "✅ 生产环境部署完成!"
# 清理指定环境
undeploy-dev:
@echo "☸️ 清理开发环境..."
@kubectl delete -k $(KUSTOMIZE_DIR)/overlays/dev --ignore-not-found
undeploy-prod:
@echo "☸️ 清理生产环境..."
@kubectl delete -k $(KUSTOMIZE_DIR)/overlays/prod --ignore-not-found
# 验证 Kustomize 配置(构建不部署)
kustomize-build:
@echo "☸️ 验证 Kustomize 配置..."
@echo "=== Base ==="
@kubectl kustomize $(KUSTOMIZE_DIR)/base >/dev/null && echo " ✓"
@echo "=== Dev Overlay ==="
@kubectl kustomize $(KUSTOMIZE_DIR)/overlays/dev >/dev/null && echo " ✓"
@echo "=== Prod Overlay ==="
@kubectl kustomize $(KUSTOMIZE_DIR)/overlays/prod >/dev/null && echo " ✓"
# ============================================================================
# 本地 K8s 测试 (OrbStack / k3d / kind)
# ============================================================================
K8S_LOCAL_NAMESPACE := rcoder-local
K8S_LOCAL_IMAGE ?= rcoder-local:latest
K8S_LOCAL_AGENT_IMAGE ?= rcoder-agent-runner-local:latest
# 构建本地 K8s 测试镜像(不推送到远程仓库)
dev-build-k8s-local:
@echo "🔨 构建本地 K8s 测试镜像..."
@echo "📦 [1/2] 构建 rcoder (features=kubernetes)..."
@docker build -f docker/rcoder-master/Dockerfile -t $(K8S_LOCAL_IMAGE) --build-arg CARGO_FLAGS="--features kubernetes" .
@echo "📦 [2/2] 构建 agent-runner..."
@echo " 步骤 1: 在 Docker 中编译 agent_runner 二进制..."
@docker build -f docker/rcoder-agent-runner/Dockerfile.build -t rcoder-agent-runner-build-local .
@mkdir -p docker/rcoder-agent-runner/bin
@docker create --name build-container-local rcoder-agent-runner-build-local 2>/dev/null || true
@docker cp build-container-local:/build/target/release/agent_runner docker/rcoder-agent-runner/bin/agent_runner
@docker rm build-container-local
@docker rmi rcoder-agent-runner-build-local
@echo " 步骤 2: 构建最终 agent-runner 镜像..."
@cd docker/rcoder-agent-runner && docker build -f Dockerfile --build-arg INSTALL_EBPF_TOOLS=false -t $(K8S_LOCAL_AGENT_IMAGE) .
@echo "✅ 本地镜像构建完成!"
@docker images | grep -E "rcoder-local|rcoder-agent-runner-local"
# 启动本地 K8s 测试OrbStack 自动共享 Docker 镜像,无需手动 import
dev-up-k8s-local:
@echo "☸️ 启动本地 K8s 测试 ($(K8S_LOCAL_NAMESPACE))..."
@kubectl apply -k $(KUSTOMIZE_DIR)/overlays/local
@echo ""
@echo "🔄 重启 Pod 使新镜像生效..."
@kubectl delete pods -n $(K8S_LOCAL_NAMESPACE) -l app=rcoder --ignore-not-found
@echo ""
@echo "⏳ 等待 RCoder 就绪..."
@kubectl rollout status deploy/rcoder -n $(K8S_LOCAL_NAMESPACE) --timeout=$(ROLLOUT_TIMEOUT)
@echo ""
@echo "📋 部署状态:"
@kubectl get pods -n $(K8S_LOCAL_NAMESPACE)
@kubectl get pvc -n $(K8S_LOCAL_NAMESPACE)
@echo ""
@echo "💡 访问: http://localhost:30087"
@echo "💡 日志: make dev-logs-k8s-local"
# 重启本地 K8s 测试
dev-restart-k8s-local:
@echo "☸️ 重启本地 K8s 测试..."
@kubectl delete pods -n $(K8S_LOCAL_NAMESPACE) -l app=rcoder --ignore-not-found
@kubectl rollout status deploy/rcoder -n $(K8S_LOCAL_NAMESPACE) --timeout=$(ROLLOUT_TIMEOUT)
@echo "✅ 已重启!"
# 停止本地 K8s 测试
dev-down-k8s-local:
@echo "☸️ 停止本地 K8s 测试..."
@kubectl delete -k $(KUSTOMIZE_DIR)/overlays/local --ignore-not-found
@echo "✅ 已清理"
# 查看本地 K8s 测试日志
dev-logs-k8s-local:
@kubectl logs -n $(K8S_LOCAL_NAMESPACE) -l app=rcoder -f --tail=100
# 一键构建+部署(本地 K8s 测试)
dev-local-k8s: dev-build-k8s-local dev-up-k8s-local
@echo "🎉 本地 K8s 测试环境已就绪!"