Files
brunoandClaude 2848a75aa2 feat: 配置完整 CI/CD 流程和 Kubernetes 部署
## 🚀 CI/CD 流程

### Gitea Actions Workflow
- 自动构建 Backend 和 Frontend Docker 镜像
- 推送镜像到 Harbor (192.168.1.83:8080)
- 自动部署到 Kubernetes learn namespace
- 支持滚动更新和健康检查

### Docker 镜像
- **Backend**: Python 3.11 + FastAPI
  - 多阶段构建优化
  - 健康检查探针
  - 生产环境优化
- **Frontend**: Node 18 + Vue 3 + Nginx
  - 多阶段构建
  - Gzip 压缩
  - 静态资源缓存优化

## ☸️ Kubernetes 部署

### 基础设施
- Namespace: learn
- PostgreSQL 15 (持久化存储)
- ConfigMap 和 Secret 管理
- Service 和 Ingress 配置

### 应用部署
- Backend: 2 副本,资源限制
- Frontend: 2 副本,Nginx 服务
- 健康检查:Liveness + Readiness Probes
- 滚动更新策略

### 访问配置
- Ingress: pager.learn.local
- Frontend: http://pager.learn.local
- API: http://pager.learn.local/api
- API Docs: http://pager.learn.local/api/docs

## 📊 Grafana 监控

### ServiceMonitor
- Prometheus 自动服务发现
- Backend、Frontend、PostgreSQL 指标采集
- 30s 采集间隔

### Dashboard 面板
- HTTP 请求速率和响应时间
- Pod CPU 和内存使用
- 数据库连接数
- 错误率 (4xx/5xx)
- Pod 重启次数
- 磁盘使用率

## 📦 新增文件

### Docker
- `backend/Dockerfile` - 后端镜像构建
- `frontend/Dockerfile` - 前端镜像构建
- `frontend/nginx.conf` - Nginx 配置
- `.dockerignore` - 构建优化

### CI/CD
- `.gitea/workflows/ci-cd.yaml` - Gitea Actions 配置

### Kubernetes
- `k8s/namespace.yaml` - Namespace 定义
- `k8s/configmap.yaml` - 应用配置
- `k8s/secret.yaml` - 敏感信息
- `k8s/postgres.yaml` - PostgreSQL 部署
- `k8s/deployment.yaml` - 应用部署
- `k8s/service.yaml` - Service 配置
- `k8s/ingress.yaml` - Ingress 路由

### 监控
- `k8s/monitoring/servicemonitor.yaml` - Prometheus 采集
- `k8s/monitoring/grafana-dashboard.json` - Dashboard 定义
- `k8s/monitoring/install-dashboard.sh` - 安装脚本

### 文档和脚本
- `CICD_DEPLOY.md` - 完整部署文档
- `deploy.sh` - 快速部署脚本

## 🔧 配置要求

### Gitea Secrets
- `HARBOR_PASSWORD`: Harbor 密码
- `KUBECONFIG`: K8s 配置 (base64 编码)

### Harbor
- 项目: pager
- 认证: admin/admin123

### Kubernetes
- 版本: 1.24+
- Namespace: learn
- Ingress Controller: nginx

## 📝 使用说明

### 自动部署
```bash
git push origin master
# 自动触发 CI/CD 流程
```

### 手动部署
```bash
./deploy.sh
```

### 查看状态
```bash
kubectl get pods -n learn
kubectl logs -f -l app=pager-backend -n learn
```

### 监控
1. 部署 ServiceMonitor: `kubectl apply -f k8s/monitoring/`
2. 安装 Grafana Dashboard: `cd k8s/monitoring && ./install-dashboard.sh`

## 🎯 特性

- ✅ 自动化 CI/CD 流程
- ✅ Docker 多阶段构建优化
- ✅ Kubernetes 高可用部署
- ✅ 滚动更新零停机
- ✅ 健康检查和自动恢复
- ✅ Prometheus + Grafana 监控
- ✅ 完整的故障排查文档

🤖 Generated with [Claude Code](https://claude.com/claude-code)

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

134 lines
3.6 KiB
Bash
Executable File

#!/bin/bash
# Quick deployment script for Pager application
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
NAMESPACE="learn"
HARBOR_URL="192.168.1.83:8080"
HARBOR_PROJECT="pager"
echo -e "${GREEN}🚀 Pager Application Deployment Script${NC}"
echo "============================================"
echo ""
# Function to print section headers
section() {
echo ""
echo -e "${YELLOW}>>> $1${NC}"
}
# Function to check command exists
check_command() {
if ! command -v $1 &> /dev/null; then
echo -e "${RED}❌ Error: $1 is not installed${NC}"
exit 1
fi
}
# Check prerequisites
section "Checking prerequisites"
check_command kubectl
check_command docker
echo -e "${GREEN}✅ All prerequisites met${NC}"
# Check kubectl connectivity
section "Checking Kubernetes connectivity"
if ! kubectl cluster-info &> /dev/null; then
echo -e "${RED}❌ Error: Cannot connect to Kubernetes cluster${NC}"
exit 1
fi
echo -e "${GREEN}✅ Connected to Kubernetes cluster${NC}"
# Create namespace if not exists
section "Creating namespace: $NAMESPACE"
if kubectl get namespace $NAMESPACE &> /dev/null; then
echo -e "${YELLOW}⚠️ Namespace $NAMESPACE already exists${NC}"
else
kubectl apply -f k8s/namespace.yaml
echo -e "${GREEN}✅ Namespace created${NC}"
fi
# Deploy PostgreSQL
section "Deploying PostgreSQL"
kubectl apply -f k8s/postgres.yaml
echo "⏳ Waiting for PostgreSQL to be ready..."
kubectl wait --for=condition=ready pod -l app=pager-postgres -n $NAMESPACE --timeout=300s || true
echo -e "${GREEN}✅ PostgreSQL deployed${NC}"
# Deploy secrets and config
section "Deploying secrets and configuration"
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/configmap.yaml
echo -e "${GREEN}✅ Secrets and ConfigMaps deployed${NC}"
# Check if we should deploy application
read -p "Do you want to deploy application pods? (requires images in Harbor) [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
section "Deploying application"
# Get current git commit
GIT_SHA=$(git rev-parse --short HEAD)
IMAGE_TAG="master-${GIT_SHA}"
echo "Using image tag: $IMAGE_TAG"
# Update deployment with image tag
sed "s|IMAGE_TAG|$IMAGE_TAG|g" k8s/deployment.yaml > /tmp/deployment-temp.yaml
kubectl apply -f /tmp/deployment-temp.yaml
kubectl apply -f k8s/service.yaml
kubectl apply -f k8s/ingress.yaml
rm /tmp/deployment-temp.yaml
echo "⏳ Waiting for deployments to be ready..."
kubectl rollout status deployment/pager-backend -n $NAMESPACE --timeout=300s || true
kubectl rollout status deployment/pager-frontend -n $NAMESPACE --timeout=300s || true
echo -e "${GREEN}✅ Application deployed${NC}"
else
echo -e "${YELLOW}⏭️ Skipping application deployment${NC}"
fi
# Deploy monitoring
read -p "Do you want to deploy monitoring (ServiceMonitor)? [y/N]: " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
section "Deploying monitoring"
kubectl apply -f k8s/monitoring/servicemonitor.yaml
echo -e "${GREEN}✅ Monitoring deployed${NC}"
fi
# Show deployment status
section "Deployment Status"
echo ""
echo "📦 Pods:"
kubectl get pods -n $NAMESPACE
echo ""
echo "🌐 Services:"
kubectl get svc -n $NAMESPACE
echo ""
echo "🔌 Ingress:"
kubectl get ingress -n $NAMESPACE
echo ""
echo -e "${GREEN}🎉 Deployment Complete!${NC}"
echo ""
echo "Next steps:"
echo "1. Add to /etc/hosts: 192.168.1.83 pager.learn.local"
echo "2. Access frontend: http://pager.learn.local"
echo "3. Access API docs: http://pager.learn.local/api/docs"
echo "4. View logs: kubectl logs -f -l app=pager-backend -n $NAMESPACE"
echo "5. Monitor in Grafana"
echo ""