Files
ljwx-stock/deploy-to-k8s.sh
brunoandClaude e135a6396f feat: 实现完整的 CICD 流程
- 添加 Gitea Actions 工作流 (.gitea/workflows/)
  - cicd.yml: 完整 CICD 流程(构建、测试、推送、部署)
  - test.yml: 快速测试工作流

- 配置 Kubernetes 部署清单 (k8s/)
  - namespace.yaml: 创建 claude-stock namespace
  - configmap.yaml: 应用配置和 Ollama 连接配置
  - deployment.yaml: 后端和前端部署(支持 Node IP 连接 Ollama)
  - service.yaml: 服务定义、RBAC 和网络策略
  - ollama-bridge.yaml: 四种 K8s 与宿主 Ollama 通信方案
  - secrets.sh: 自动创建 K8s Secrets

- 部署脚本和工具
  - deploy-to-k8s.sh: 一键 K8s 部署脚本
  - verify-cicd.sh: CICD 环境验证脚本

- 文档
  - CICD_DEPLOYMENT_GUIDE.md: 完整部署指南(中文)
  - QUICK_START.md: 5 分钟快速启动指南(中文)

关键功能:
✅ Gitea Runners(Docker + K8s)
✅ Harbor 镜像仓库集成
✅ 自动化测试和安全扫描
✅ K8s 滚动更新和健康检查
✅ Ollama 集成(使用 Node IP 解决通信问题)
✅ 完整的部署后验证

🤖 Generated with Claude Code

Co-Authored-By: Claude <[email protected]>
2025-11-13 11:56:09 +08:00

139 lines
3.7 KiB
Bash
Executable File

#!/bin/bash
# Claude Stock - Kubernetes 部署脚本
# 此脚本用于快速部署到 Kubernetes
set -e
NAMESPACE="claude-stock"
REGISTRY="localhost:8443"
REGISTRY_USER="admin"
REGISTRY_PASSWORD="${HARBOR_PASSWORD:-}"
echo "🚀 Claude Stock - Kubernetes 部署脚本"
echo "======================================="
echo ""
# 检查前置条件
echo "1️⃣ 检查前置条件..."
{
command -v kubectl >/dev/null 2>&1 || { echo "❌ kubectl 未安装"; exit 1; }
kubectl cluster-info > /dev/null 2>&1 || { echo "❌ K8s 集群不可用"; exit 1; }
echo "✅ kubectl 已安装"
echo "✅ K8s 集群可用"
}
echo ""
# 检查 Harbor 访问
echo "2️⃣ 检查 Harbor 访问..."
if [ -z "$REGISTRY_PASSWORD" ]; then
echo "⚠️ 未设置 HARBOR_PASSWORD"
read -p "请输入 Harbor 密码: " REGISTRY_PASSWORD
fi
echo ""
# 创建 namespace
echo "3️⃣ 创建 namespace..."
kubectl create namespace $NAMESPACE --dry-run=client -o yaml | kubectl apply -f -
echo "✅ Namespace $NAMESPACE 已创建/更新"
echo ""
# 创建 Harbor 镜像拉取 secret
echo "4️⃣ 创建镜像拉取凭证..."
kubectl create secret docker-registry harbor-secret \
--docker-server=$REGISTRY \
--docker-username=$REGISTRY_USER \
--docker-password="$REGISTRY_PASSWORD" \
--docker-email=[email protected] \
-n $NAMESPACE \
--dry-run=client -o yaml | kubectl apply -f -
echo "✅ 镜像拉取凭证已创建"
echo ""
# 创建应用 secrets
echo "5️⃣ 创建应用秘钥..."
bash k8s/secrets.sh
echo ""
# 部署配置和应用
echo "6️⃣ 部署应用..."
{
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/configmap.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml
}
if [ $? -eq 0 ]; then
echo "✅ 应用部署完成"
else
echo "❌ 应用部署失败"
exit 1
fi
echo ""
# 等待部署完成
echo "7️⃣ 等待部署完成(最多 5 分钟)..."
kubectl rollout status deployment/claude-stock-backend -n $NAMESPACE --timeout=5m || {
echo "⚠️ Backend 部署超时"
kubectl describe deployment/claude-stock-backend -n $NAMESPACE
}
echo ""
# 获取服务信息
echo "8️⃣ 获取服务信息..."
echo ""
echo "=== Backend Service ==="
kubectl get svc claude-stock-backend -n $NAMESPACE -o wide
echo ""
echo "=== Frontend Service ==="
kubectl get svc claude-stock-frontend -n $NAMESPACE -o wide
echo ""
# 获取 Pod 状态
echo "=== Pod Status ==="
kubectl get pods -n $NAMESPACE
echo ""
# 获取 Pod IP(如果可用)
BACKEND_POD=$(kubectl get pod -n $NAMESPACE -l app=claude-stock-backend -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
if [ -n "$BACKEND_POD" ]; then
echo "=== Backend Pod 详情 ==="
echo "Pod Name: $BACKEND_POD"
BACKEND_IP=$(kubectl get pod $BACKEND_POD -n $NAMESPACE -o jsonpath='{.status.podIP}')
echo "Pod IP: $BACKEND_IP"
echo ""
fi
# 验证健康状态
echo "9️⃣ 验证健康状态..."
if [ -n "$BACKEND_POD" ]; then
for i in {1..5}; do
if kubectl exec -n $NAMESPACE $BACKEND_POD -- curl -f http://localhost:8000/health > /dev/null 2>&1; then
echo "✅ Backend 服务健康"
break
fi
echo "⏳ 等待 Backend 启动... ($i/5)"
sleep 10
done
fi
echo ""
# 端口转发(用于本地访问)
echo "🔟 配置端口转发(可选)..."
echo ""
echo "要在本地访问服务,运行:"
echo " kubectl port-forward svc/claude-stock-backend 8000:80 -n $NAMESPACE"
echo " kubectl port-forward svc/claude-stock-frontend 8090:8090 -n $NAMESPACE"
echo ""
# 查看日志
echo "📋 查看日志:"
echo " kubectl logs -f deployment/claude-stock-backend -n $NAMESPACE"
echo " kubectl logs -f deployment/claude-stock-frontend -n $NAMESPACE"
echo ""
echo "✅ 部署完成!"
echo ""
echo "📊 已部署的资源:"
kubectl get all -n $NAMESPACE