mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-06-28 22:41:23 +08:00
deploy
This commit is contained in:
231
deploy/README.md
Normal file
231
deploy/README.md
Normal file
@@ -0,0 +1,231 @@
|
||||
# S3 Balance 部署指南
|
||||
|
||||
本目录包含 S3 Balance 服务的各种部署方案,从简单的 Docker Compose 到生产级的 Kubernetes 部署。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
deploy/
|
||||
├── docker/ # Docker 和 Docker Compose 部署
|
||||
│ ├── docker-compose.yml # Docker Compose 配置
|
||||
│ ├── Dockerfile # Docker 镜像构建文件
|
||||
│ ├── start-monitoring.sh # 一键启动脚本
|
||||
│ └── config.docker.yaml # Docker 环境配置
|
||||
├── kubernetes/ # Kubernetes 原生部署
|
||||
│ ├── namespace.yaml # 命名空间
|
||||
│ ├── configmap.yaml # 配置映射
|
||||
│ ├── deployment.yaml # 部署配置
|
||||
│ ├── service.yaml # 服务暴露
|
||||
│ └── ingress.yaml # 入口配置
|
||||
├── helm/ # HELM Chart 部署
|
||||
│ └── s3-balance/ # HELM Chart 目录
|
||||
└── monitoring/ # 监控系统配置
|
||||
├── prometheus.yml # Prometheus 配置
|
||||
├── s3_balance_alerts.yml # 告警规则
|
||||
└── grafana/ # Grafana 配置和仪表板
|
||||
```
|
||||
|
||||
## 🐳 Docker Compose 部署(推荐开发环境)
|
||||
|
||||
### 快速启动(含完整监控栈)
|
||||
```bash
|
||||
cd deploy/docker
|
||||
./start-monitoring.sh
|
||||
```
|
||||
|
||||
### 手动启动
|
||||
```bash
|
||||
cd deploy/docker
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 访问地址
|
||||
- S3 Balance API: http://localhost:8080
|
||||
- Grafana 面板: http://localhost:3000 (admin/admin123)
|
||||
- Prometheus: http://localhost:9090
|
||||
- 监控指标: http://localhost:8080/metrics
|
||||
|
||||
### 配置文件
|
||||
编辑 `config.docker.yaml` 来自定义:
|
||||
- 存储桶配置
|
||||
- 负载均衡策略
|
||||
- 监控指标设置
|
||||
|
||||
## ☸️ Kubernetes 部署(推荐生产环境)
|
||||
|
||||
### 基础部署
|
||||
```bash
|
||||
cd deploy/kubernetes
|
||||
kubectl apply -f namespace.yaml
|
||||
kubectl apply -f configmap.yaml
|
||||
kubectl apply -f deployment.yaml
|
||||
kubectl apply -f service.yaml
|
||||
```
|
||||
|
||||
### 高可用部署
|
||||
```bash
|
||||
kubectl apply -f hpa.yaml # 水平自动扩缩容
|
||||
kubectl apply -f pdb.yaml # Pod 中断预算
|
||||
```
|
||||
|
||||
### 外部访问
|
||||
```bash
|
||||
kubectl apply -f ingress.yaml
|
||||
```
|
||||
|
||||
### 配置说明
|
||||
- 使用 ConfigMap 管理配置文件
|
||||
- 支持 HPA 自动扩缩容
|
||||
- 集成集群 DNS 服务发现
|
||||
- 支持多环境配置(dev/test/prod)
|
||||
|
||||
## 📊 HELM Chart 部署(推荐企业环境)
|
||||
|
||||
### 安装 Chart
|
||||
```bash
|
||||
cd deploy/helm
|
||||
helm install s3-balance ./s3-balance
|
||||
```
|
||||
|
||||
### 自定义参数
|
||||
```bash
|
||||
helm install s3-balance ./s3-balance -f custom-values.yaml
|
||||
```
|
||||
|
||||
### 升级版本
|
||||
```bash
|
||||
helm upgrade s3-balance ./s3-balance
|
||||
```
|
||||
|
||||
### HELM 优势
|
||||
- 参数化配置
|
||||
- 多环境管理
|
||||
- 版本控制
|
||||
- 依赖管理
|
||||
|
||||
## 🔧 监控集成
|
||||
|
||||
所有的部署方案都集成了完整的监控系统:
|
||||
|
||||
### Prometheus 指标
|
||||
- S3 Balance 业务指标
|
||||
- 系统资源指标
|
||||
- 自定义应用指标
|
||||
|
||||
### Grafana 仪表板
|
||||
- 服务概览面板
|
||||
- 性能分析面板
|
||||
- 容量监控面板
|
||||
- 错误率跟踪面板
|
||||
|
||||
### 告警规则
|
||||
- 存储桶健康状态告警
|
||||
- 高错误率告警
|
||||
- 高延迟告警
|
||||
- 容量使用率告警
|
||||
|
||||
## 🚨 部署要求
|
||||
|
||||
### 系统要求
|
||||
- Docker & Docker Compose(开发环境)
|
||||
- Kubernetes 1.19+(生产环境)
|
||||
- HELM 3.0+(企业环境)
|
||||
|
||||
### 资源要求
|
||||
- CPU: 0.5-2 core
|
||||
- Memory: 512MB-2GB
|
||||
- Storage: 1GB-100GB(根据使用情况)
|
||||
- Network: 内网访问存储桶
|
||||
|
||||
### 网络要求
|
||||
- 访问后端 S3 存储桶
|
||||
- Prometheus Pushgateway(可选)
|
||||
- 外部监控系统(可选)
|
||||
|
||||
## 📋 环境变量
|
||||
|
||||
### S3 Balance
|
||||
- `CONFIG_FILE`: 配置文件路径
|
||||
- `LOG_LEVEL`: 日志级别 (debug/info/warn/error)
|
||||
- `TZ`: 时区设置
|
||||
|
||||
### Prometheus
|
||||
- `STORAGE_TSDB_RETENTION_TIME`: 数据保留时间
|
||||
- `WEB_ENABLE_LIFECYCLE`: 启用生命周期管理
|
||||
|
||||
### Grafana
|
||||
- `GF_SECURITY_ADMIN_USER`: 管理员用户名
|
||||
- `GF_SECURITY_ADMIN_PASSWORD`: 管理员密码
|
||||
- `GF_USERS_ALLOW_SIGN_UP`: 是否允许注册
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 生产环境建议
|
||||
1. **资源限制**: 设置合理的CPU/内存限制
|
||||
2. **健康检查**: 配置完整的探针检查
|
||||
3. **持久化**: 重要数据使用持久化存储
|
||||
4. **备份**: 定期备份配置和数据库
|
||||
5. **监控**: 集成现有监控系统
|
||||
|
||||
### 高可用建议
|
||||
1. **多副本**: 部署多个实例
|
||||
2. **负载均衡**: 集群内负载均衡
|
||||
3. **自动扩缩容**: 基于负载自动扩缩容
|
||||
4. **多区域**: 跨可用区部署
|
||||
|
||||
### 安全建议
|
||||
1. **镜像安全**: 使用官方基础镜像
|
||||
2. **访问控制**: 配置RBAC权限
|
||||
3. **网络隔离**: 使用网络策略
|
||||
4. **敏感信息**: 使用Secret管理凭证
|
||||
|
||||
## 🔧 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
**Pod 启动失败**
|
||||
```bash
|
||||
kubectl describe pod <pod-name>
|
||||
kubectl logs <pod-name>
|
||||
```
|
||||
|
||||
**配置错误**
|
||||
```bash
|
||||
kubectl get configmap s3-balance-config -o yaml
|
||||
```
|
||||
|
||||
**服务无法访问**
|
||||
```bash
|
||||
kubectl get service s3-balance-service
|
||||
kubectl get ingress s3-balance-ingress
|
||||
```
|
||||
|
||||
### 性能调优
|
||||
- 调整负载均衡策略
|
||||
- 优化数据库连接池
|
||||
- 配置合理的缓存策略
|
||||
- 监控资源使用情况
|
||||
|
||||
## 🔗 集成外部系统
|
||||
|
||||
### 已有 Prometheus
|
||||
在外部 Prometheus 配置中添加:
|
||||
```yaml
|
||||
scrape_configs:
|
||||
- job_name: 's3-balance'
|
||||
static_configs:
|
||||
- targets: ['s3-balance-service.default.svc.cluster.local:8080']
|
||||
```
|
||||
|
||||
### 现有监控系统
|
||||
- 通过 exporters 暴露指标
|
||||
- 使用统一的日志格式
|
||||
- 集成告警通知渠道
|
||||
|
||||
## 📖 参考文献
|
||||
|
||||
- [Docker Compose 文档](https://docs.docker.com/compose/)
|
||||
- [Kubernetes 官方文档](https://kubernetes.io/docs/)
|
||||
- [HELM 官方文档](https://helm.sh/docs/)
|
||||
- [Prometheus 最佳实践](https://prometheus.io/docs/practices/)
|
||||
- [Grafana 文档](https://grafana.com/docs/)
|
||||
45
deploy/docker/Dockerfile
Normal file
45
deploy/docker/Dockerfile
Normal file
@@ -0,0 +1,45 @@
|
||||
# 多阶段构建用于减小镜像大小
|
||||
FROM golang:1.24-alpine AS builder
|
||||
|
||||
# 安装构建依赖(包括CGO支持的sqlite3)
|
||||
RUN apk add --no-cache gcc musl-dev sqlite-dev git ca-certificates tzdata
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /build
|
||||
|
||||
# 复制 Go 模块文件
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download && go mod tidy
|
||||
|
||||
# 复制源码
|
||||
COPY . .
|
||||
|
||||
# 构建应用(启用CGO)
|
||||
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build \
|
||||
-ldflags='-w -s -X main.version=$(git describe --tags --always)' \
|
||||
-o s3-balance \
|
||||
cmd/s3-balance/main.go
|
||||
|
||||
# 运行时镜像
|
||||
FROM alpine:latest
|
||||
|
||||
# 安装运行时依赖(包括sqlite库)
|
||||
RUN apk --no-cache add ca-certificates tzdata sqlite-libs
|
||||
|
||||
# 设置时区
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# 复制二进制文件
|
||||
COPY --from=builder /build/s3-balance /app/s3-balance
|
||||
|
||||
# 创建配置和数据目录
|
||||
RUN mkdir -p /app/config /app/data
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8080
|
||||
|
||||
# 运行应用
|
||||
ENTRYPOINT ["/app/s3-balance"]
|
||||
CMD ["-config", "/app/config/config.yaml"]
|
||||
62
deploy/docker/config.docker.yaml
Normal file
62
deploy/docker/config.docker.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
# Docker 配置 - 启用监控
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
read_timeout: 30s
|
||||
write_timeout: 30s
|
||||
idle_timeout: 60s
|
||||
|
||||
database:
|
||||
type: "sqlite"
|
||||
dsn: "data/s3-balance.db"
|
||||
max_open_conns: 25
|
||||
max_idle_conns: 5
|
||||
conn_max_lifetime: 300
|
||||
log_level: "info"
|
||||
auto_migrate: true
|
||||
|
||||
# 示例存储桶配置 - 请根据实际情况修改
|
||||
buckets:
|
||||
- name: "minio-bucket"
|
||||
endpoint: "http://minio:9000"
|
||||
region: "us-east-1"
|
||||
access_key_id: "minioadmin"
|
||||
secret_access_key: "minioadmin"
|
||||
max_size: "1GB"
|
||||
weight: 10
|
||||
enabled: true
|
||||
use_ssl: false
|
||||
path_style: true
|
||||
virtual: false
|
||||
|
||||
- name: "user-data"
|
||||
endpoint: ""
|
||||
region: "us-east-1"
|
||||
access_key_id: ""
|
||||
secret_access_key: ""
|
||||
max_size: "1GB"
|
||||
weight: 10
|
||||
enabled: true
|
||||
use_ssl: true
|
||||
path_style: false
|
||||
virtual: true
|
||||
|
||||
balancer:
|
||||
strategy: "least-space"
|
||||
health_check_period: 30s
|
||||
update_stats_period: 60s
|
||||
retry_attempts: 3
|
||||
retry_delay: 1s
|
||||
|
||||
# 监控指标 - 启用状态
|
||||
metrics:
|
||||
enabled: true
|
||||
path: "/metrics"
|
||||
port: 9090
|
||||
|
||||
s3api:
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE"
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
virtual_host: false
|
||||
proxy_mode: false
|
||||
auth_required: false
|
||||
90
deploy/docker/docker-compose.yml
Normal file
90
deploy/docker/docker-compose.yml
Normal file
@@ -0,0 +1,90 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# S3 Balance 服务
|
||||
s3-balance:
|
||||
build:
|
||||
context: ../..
|
||||
dockerfile: deploy/docker/Dockerfile
|
||||
container_name: s3-balance
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ../docker/config.docker.yaml:/app/config/config.yaml
|
||||
- ../docker/data:/app/data
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
command: ["/app/s3-balance", "-config", "/app/config/config.yaml"]
|
||||
|
||||
# Prometheus 监控
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: prometheus
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ../monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
- ../monitoring/s3_balance_alerts.yml:/etc/prometheus/s3_balance_alerts.yml
|
||||
- prometheus_data:/prometheus
|
||||
command:
|
||||
- '--config.file=/etc/prometheus/prometheus.yml'
|
||||
- '--storage.tsdb.path=/prometheus'
|
||||
- '--web.console.libraries=/etc/prometheus/console_libraries'
|
||||
- '--web.console.templates=/etc/prometheus/consoles'
|
||||
- '--storage.tsdb.retention.time=200h'
|
||||
- '--web.enable-lifecycle'
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
|
||||
# Grafana 可视化
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: grafana
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- grafana_data:/var/lib/grafana
|
||||
- ../monitoring/grafana/provisioning:/etc/grafana/provisioning
|
||||
- ../monitoring/grafana/dashboards:/var/lib/grafana/dashboards
|
||||
environment:
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin123
|
||||
- GF_USERS_ALLOW_SIGN_UP=false
|
||||
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- prometheus
|
||||
|
||||
# Node Exporter (可选,监控宿主机)
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
ports:
|
||||
- "9100:9100"
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
command:
|
||||
- '--path.procfs=/host/proc'
|
||||
- '--path.sysfs=/host/sys'
|
||||
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
|
||||
networks:
|
||||
- monitoring
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
prometheus_data:
|
||||
driver: local
|
||||
grafana_data:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
monitoring:
|
||||
driver: bridge
|
||||
72
deploy/docker/start-monitoring.sh
Normal file
72
deploy/docker/start-monitoring.sh
Normal file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
# S3 Balance + 监控栈 一键启动(修复版)
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 正在启动 S3 Balance + 监控栈(修复CGO版本)..."
|
||||
|
||||
# 检查 Docker 和 Docker Compose
|
||||
if ! command -v docker &> /dev/null; then
|
||||
echo "❌ Docker 未安装,请先安装 Docker"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
echo "❌ Docker Compose 未安装,请先安装 Docker Compose"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 创建必要目录
|
||||
echo "📁 创建必要目录..."
|
||||
mkdir -p data grafana/provisioning/datasources grafana/provisioning/dashboards
|
||||
|
||||
# 构建 S3 Balance 镜像(使用固定 Go 版本)
|
||||
echo "🔨 构建 S3 Balance 镜像..."
|
||||
docker build -t s3-balance:latest -f ../docker/Dockerfile ../..
|
||||
|
||||
# 停止已有容器(如果存在)
|
||||
echo "🛑 清理已有容器..."
|
||||
docker-compose down 2>/dev/null || true
|
||||
|
||||
# 启动服务
|
||||
echo "🐳 启动 Docker 容器..."
|
||||
docker-compose up -d
|
||||
|
||||
# 等待服务启动
|
||||
echo "⏳ 等待服务启动..."
|
||||
sleep 25
|
||||
|
||||
# 检查服务状态
|
||||
echo "🔍 检查服务状态..."
|
||||
if docker-compose ps | grep -q "Up"; then
|
||||
echo ""
|
||||
echo "✅ 服务启动完成!"
|
||||
else
|
||||
echo ""
|
||||
echo "❌ 服务启动可能失败,检查日志:"
|
||||
echo "docker-compose logs"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 输出访问信息
|
||||
echo ""
|
||||
echo "🔗 访问地址:"
|
||||
echo " 📊 Grafana 面板: http://localhost:3000 (用户名: admin, 密码: admin123)"
|
||||
echo " 🔥 Prometheus: http://localhost:9090"
|
||||
echo " 📈 指标端点: http://localhost:8080/metrics"
|
||||
echo " 🐳 Node 指标: http://localhost:9100/metrics"
|
||||
echo ""
|
||||
echo "🔧 管理命令:"
|
||||
echo " docker-compose logs -f s3-balance # 查看 S3 Balance 日志"
|
||||
echo " docker-compose logs -f prometheus # 查看 Prometheus 日志"
|
||||
echo " docker-compose logs -f grafana # 查看 Grafana 日志"
|
||||
echo " docker-compose down # 停止所有服务"
|
||||
echo " docker-compose restart s3-balance # 重启 S3 Balance"
|
||||
echo ""
|
||||
echo "📊 指标查询示例:"
|
||||
echo " - 存储桶健康: s3_balance_bucket_healthy"
|
||||
echo " - QPS: rate(s3_balance_s3_operations_total[1m])"
|
||||
echo " - 延迟: histogram_quantile(0.95, s3_balance_s3_operation_duration_seconds_bucket)"
|
||||
echo ""
|
||||
echo "🎉 享受完整的 S3 Balance 监控体验!"
|
||||
9
deploy/helm/s3-balance-servicemonitor/Chart.yaml
Normal file
9
deploy/helm/s3-balance-servicemonitor/Chart.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v2
|
||||
name: s3-balance-servicemonitor
|
||||
description: A Helm chart for ServiceMonitor to monitor S3 Balance
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "1.0.0"
|
||||
|
||||
# Usage:
|
||||
# helm install s3-balance-monitoring ./s3-balance-servicemonitor -n monitoring
|
||||
20
deploy/helm/s3-balance/Chart.yaml
Normal file
20
deploy/helm/s3-balance/Chart.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
apiVersion: v2
|
||||
name: s3-balance
|
||||
description: A Helm chart for S3 Balance load balancing service
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "1.0.0"
|
||||
icon: https://helm.sh/img/helm.svg
|
||||
keywords:
|
||||
- s3
|
||||
- storage
|
||||
- load-balancer
|
||||
- object-storage
|
||||
- minio
|
||||
- aws-s3
|
||||
home: https://github.com/example/s3-balance
|
||||
sources:
|
||||
- https://github.com/example/s3-balance
|
||||
maintainers:
|
||||
- name: S3 Balance Team
|
||||
email: admin@example.com
|
||||
155
deploy/helm/s3-balance/production-values.yaml
Normal file
155
deploy/helm/s3-balance/production-values.yaml
Normal file
@@ -0,0 +1,155 @@
|
||||
# HELM Values 生产环境配置
|
||||
replicaCount: 3
|
||||
|
||||
image:
|
||||
repository: your-registry.com/s3-balance
|
||||
tag: v1.0.0
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
annotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "8080"
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: s3-balance.your-domain.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: s3-balance-tls
|
||||
hosts:
|
||||
- s3-balance.your-domain.com
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 3
|
||||
maxReplicas: 20
|
||||
targetCPUUtilizationPercentage: 70
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
config:
|
||||
configYaml: |
|
||||
# 生产环境配置
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
read_timeout: 30s
|
||||
write_timeout: 30s
|
||||
idle_timeout: 60s
|
||||
|
||||
database:
|
||||
type: "sqlite"
|
||||
dsn: "/app/data/s3-balance.db"
|
||||
max_open_conns: 100
|
||||
max_idle_conns: 20
|
||||
conn_max_lifetime: 600
|
||||
log_level: "warn"
|
||||
auto_migrate: true
|
||||
|
||||
buckets:
|
||||
# 生产存储桶配置
|
||||
- name: "prod-minio"
|
||||
endpoint: "https://your-minio-endpoint.com"
|
||||
region: "us-east-1"
|
||||
access_key_id: "CHANGEME"
|
||||
secret_access_key: "CHANGEME"
|
||||
max_size: "500GB"
|
||||
weight: 10
|
||||
enabled: true
|
||||
use_ssl: true
|
||||
path_style: true
|
||||
virtual: false
|
||||
|
||||
balancer:
|
||||
strategy: "least-space"
|
||||
health_check_period: 30s
|
||||
update_stats_period: 60s
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
path: "/metrics"
|
||||
port: 8080
|
||||
|
||||
s3api:
|
||||
access_key: "your-access-key"
|
||||
secret_key: "your-secret-key"
|
||||
virtual_host: false
|
||||
proxy_mode: false
|
||||
auth_required: true
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: "fast-ssd"
|
||||
accessMode: ReadWriteOnce
|
||||
size: 20Gi
|
||||
|
||||
monitoring:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
namespace: monitoring
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
labels:
|
||||
release: prometheus
|
||||
|
||||
prometheusRule:
|
||||
enabled: true
|
||||
namespace: monitoring
|
||||
labels:
|
||||
release: prometheus
|
||||
rules:
|
||||
- alert: BucketDown
|
||||
expr: up{job="s3-balance"} == 0
|
||||
for: 5m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "S3 Balance 服务不可用"
|
||||
description: "S3 Balance 服务已经连续5分钟不可用"
|
||||
- alert: HighErrorRate
|
||||
expr: rate(s3_balance_s3_operations_total{status="error"}[5m]) > 0.05
|
||||
for: 2m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "高错误率告警"
|
||||
description: "错误率超过5%,操作类型: {{ $labels.operation }}"
|
||||
|
||||
nodeSelector:
|
||||
disktype: ssd
|
||||
|
||||
tolerations:
|
||||
- key: "highcpu"
|
||||
operator: "Equal"
|
||||
value: "true"
|
||||
effect: "NoSchedule"
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- s3-balance
|
||||
topologyKey: kubernetes.io/hostname
|
||||
34
deploy/helm/s3-balance/templates/_helpers.tpl
Normal file
34
deploy/helm/s3-balance/templates/_helpers.tpl
Normal file
@@ -0,0 +1,34 @@
|
||||
{{/*
|
||||
Return the proper s3-balance image name
|
||||
*/}}
|
||||
{{- define "s3-balance.image" -}}
|
||||
{{- $registryName := .Values.image.repository -}}
|
||||
{{- $tag := .Values.image.tag | default .Chart.AppVersion -}}
|
||||
{{- printf "%s:%s" $registryName $tag -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the chart name
|
||||
*/}}
|
||||
{{- define "s3-balance.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the full name
|
||||
*/}}
|
||||
{{- define "s3-balance.fullname" -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Return the service account name
|
||||
*/}}
|
||||
{{- define "s3-balance.serviceAccountName" -}}
|
||||
{{- default (include "s3-balance.fullname" .) .Values.serviceAccount.name -}}
|
||||
{{- end -}}
|
||||
26
deploy/helm/s3-balance/templates/_labels.tpl
Normal file
26
deploy/helm/s3-balance/templates/_labels.tpl
Normal file
@@ -0,0 +1,26 @@
|
||||
{{/*
|
||||
Labels
|
||||
*/}}
|
||||
{{- define "s3-balance.labels" -}}
|
||||
helm.sh/chart: {{ include "s3-balance.chart" . }}
|
||||
{{ include "s3-balance.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "s3-balance.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "s3-balance.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "s3-balance.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end -}}
|
||||
9
deploy/helm/s3-balance/templates/configmap.yaml
Normal file
9
deploy/helm/s3-balance/templates/configmap.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |{{ .Values.config.configYaml | nindent 4 }}
|
||||
93
deploy/helm/s3-balance/templates/deployment.yaml
Normal file
93
deploy/helm/s3-balance/templates/deployment.yaml
Normal file
@@ -0,0 +1,93 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "s3-balance.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "s3-balance.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "s3-balance.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ include "s3-balance.image" . }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: TZ
|
||||
value: "Asia/Shanghai"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /metrics
|
||||
port: http
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /metrics
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 10 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "s3-balance.fullname" . }}-config
|
||||
- name: data
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "s3-balance.fullname" . }}-data
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
33
deploy/helm/s3-balance/templates/hpa.yaml
Normal file
33
deploy/helm/s3-balance/templates/hpa.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
32
deploy/helm/s3-balance/templates/ingress.yaml
Normal file
32
deploy/helm/s3-balance/templates/ingress.yaml
Normal file
@@ -0,0 +1,32 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ingress.className }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "s3-balance.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
21
deploy/helm/s3-balance/templates/prometheusrule.yaml
Normal file
21
deploy/helm/s3-balance/templates/prometheusrule.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.monitoring.enabled }}
|
||||
{{- if .Values.prometheusRule.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PrometheusRule
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Values.prometheusRule.namespace | default .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
{{- with .Values.prometheusRule.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
groups:
|
||||
- name: {{ include "s3-balance.name" . }}
|
||||
rules:
|
||||
{{- with .Values.prometheusRule.rules }}
|
||||
{{ toYaml . | indent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
21
deploy/helm/s3-balance/templates/pvc.yaml
Normal file
21
deploy/helm/s3-balance/templates/pvc.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
{{/*
|
||||
Persistent Volume Claim template
|
||||
*/}}
|
||||
{{- if .Values.persistence.enabled }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}-data
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.persistence.accessMode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size }}
|
||||
{{- if .Values.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
41
deploy/helm/s3-balance/templates/service.yaml
Normal file
41
deploy/helm/s3-balance/templates/service.yaml
Normal file
@@ -0,0 +1,41 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
{{- with .Values.service.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "s3-balance.selectorLabels" . | nindent 4 }}- name: metrics
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}-metrics
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
service-type: metrics
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: metrics
|
||||
port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
selector:
|
||||
{{- include "s3-balance.selectorLabels" . | nindent 4 }}
|
||||
11
deploy/helm/s3-balance/templates/serviceaccount.yaml
Normal file
11
deploy/helm/s3-balance/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "s3-balance.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
24
deploy/helm/s3-balance/templates/servicemonitor.yaml
Normal file
24
deploy/helm/s3-balance/templates/servicemonitor.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
{{- if .Values.monitoring.enabled }}
|
||||
{{- if .Values.monitoring.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "s3-balance.fullname" . }}
|
||||
namespace: {{ .Values.monitoring.serviceMonitor.namespace | default .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "s3-balance.labels" . | nindent 4 }}
|
||||
{{- with .Values.monitoring.serviceMonitor.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "s3-balance.selectorLabels" . | nindent 6 }}
|
||||
service-type: metrics
|
||||
endpoints:
|
||||
- port: metrics
|
||||
interval: {{ .Values.monitoring.serviceMonitor.interval }}
|
||||
scrapeTimeout: {{ .Values.monitoring.serviceMonitor.scrapeTimeout }}
|
||||
path: /metrics
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
174
deploy/helm/s3-balance/values.yaml
Normal file
174
deploy/helm/s3-balance/values.yaml
Normal file
@@ -0,0 +1,174 @@
|
||||
# 默认值
|
||||
replicaCount: 3
|
||||
|
||||
image:
|
||||
repository: s3-balance
|
||||
tag: latest
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: [ ]
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
create: true
|
||||
annotations: { }
|
||||
name: ""
|
||||
|
||||
podAnnotations: { }
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
fsGroup: 2000
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
annotations: { }
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: "nginx"
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
hosts:
|
||||
- host: s3-balance.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: true
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
targetCPUUtilizationPercentage: 70
|
||||
targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: { }
|
||||
|
||||
tolerations: [ ]
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app.kubernetes.io/name
|
||||
operator: In
|
||||
values:
|
||||
- s3-balance
|
||||
topologyKey: kubernetes.io/hostname
|
||||
|
||||
config:
|
||||
# S3 Balance 配置
|
||||
configYaml: |
|
||||
# HELM 配置的 S3 Balance
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
read_timeout: 30s
|
||||
write_timeout: 30s
|
||||
idle_timeout: 60s
|
||||
|
||||
database:
|
||||
type: "sqlite"
|
||||
dsn: "/app/data/s3-balance.db"
|
||||
max_open_conns: 50
|
||||
max_idle_conns: 10
|
||||
conn_max_lifetime: 600
|
||||
log_level: "info"
|
||||
auto_migrate: true
|
||||
|
||||
buckets:
|
||||
# 示例配置 - 请根据实际情况修改
|
||||
- name: "minio-bucket"
|
||||
endpoint: "http://minio:9000"
|
||||
region: "us-east-1"
|
||||
access_key_id: "minioadmin"
|
||||
secret_access_key: "minioadmin"
|
||||
max_size: "50GB"
|
||||
weight: 10
|
||||
enabled: true
|
||||
use_ssl: false
|
||||
path_style: true
|
||||
virtual: false
|
||||
|
||||
balancer:
|
||||
strategy: "least-space"
|
||||
health_check_period: 30s
|
||||
update_stats_period: 60s
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
path: "/metrics"
|
||||
port: 8080
|
||||
|
||||
s3api:
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE"
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
virtual_host: false
|
||||
proxy_mode: false
|
||||
auth_required: false
|
||||
|
||||
# 监控配置
|
||||
monitoring:
|
||||
enabled: true
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
namespace: ""
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
labels: { }
|
||||
|
||||
# PrometheusRule 配置
|
||||
prometheusRule:
|
||||
enabled: true
|
||||
namespace: ""
|
||||
labels: { }
|
||||
rules:
|
||||
- alert: HighErrorRate
|
||||
expr: rate(s3_balance_s3_operations_total{status="error"}[5m]) > 0.1
|
||||
for: 2m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "S3 Balance 错误率过高"
|
||||
description: "S3 Balance 错误率超过10%: {{ $labels.operation }}"
|
||||
- alert: HighLatency
|
||||
expr: histogram_quantile(0.95, rate(s3_balance_s3_operation_duration_seconds_bucket[5m])) > 1
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "操作延迟过高"
|
||||
description: "操作延迟 P95 超过1秒"
|
||||
|
||||
# 持久化存储
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
accessMode: ReadWriteOnce
|
||||
size: 5Gi
|
||||
56
deploy/kubernetes/configmap.yaml
Normal file
56
deploy/kubernetes/configmap.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: s3-balance-config
|
||||
namespace: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
data:
|
||||
config.yaml: |
|
||||
# Kubernetes 生产环境配置
|
||||
server:
|
||||
host: "0.0.0.0"
|
||||
port: 8080
|
||||
read_timeout: 30s
|
||||
write_timeout: 30s
|
||||
idle_timeout: 60s
|
||||
|
||||
database:
|
||||
type: "sqlite"
|
||||
dsn: "/app/data/s3-balance.db"
|
||||
max_open_conns: 50
|
||||
max_idle_conns: 10
|
||||
conn_max_lifetime: 600
|
||||
log_level: "info"
|
||||
auto_migrate: true
|
||||
|
||||
buckets:
|
||||
# 示例配置 - 请替换为实际存储桶
|
||||
- name: "prod-bucket-1"
|
||||
endpoint: "http://minio-svc:9000"
|
||||
region: "us-east-1"
|
||||
access_key_id: "minioadmin"
|
||||
secret_access_key: "minioadmin"
|
||||
max_size: "100GB"
|
||||
weight: 10
|
||||
enabled: true
|
||||
use_ssl: false
|
||||
path_style: true
|
||||
virtual: false
|
||||
|
||||
balancer:
|
||||
strategy: "least-space"
|
||||
health_check_period: 30s
|
||||
update_stats_period: 60s
|
||||
|
||||
metrics:
|
||||
enabled: true
|
||||
path: "/metrics"
|
||||
port: 8080
|
||||
|
||||
s3api:
|
||||
access_key: "AKIAIOSFODNN7EXAMPLE"
|
||||
secret_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
||||
virtual_host: false
|
||||
proxy_mode: false
|
||||
auth_required: false
|
||||
92
deploy/kubernetes/deployment.yaml
Normal file
92
deploy/kubernetes/deployment.yaml
Normal file
@@ -0,0 +1,92 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: s3-balance-deployment
|
||||
namespace: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 3
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: s3-balance
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: s3-balance
|
||||
tier: backend
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- s3-balance
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers:
|
||||
- name: s3-balance
|
||||
image: s3-balance:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
env:
|
||||
- name: TZ
|
||||
value: "Asia/Shanghai"
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /app/config
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8080
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8080
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: s3-balance-config
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
restartPolicy: Always
|
||||
terminationGracePeriodSeconds: 30
|
||||
40
deploy/kubernetes/hpa.yaml
Normal file
40
deploy/kubernetes/hpa.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: s3-balance-hpa
|
||||
namespace: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: s3-balance-deployment
|
||||
minReplicas: 3
|
||||
maxReplicas: 10
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 70
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: 80
|
||||
behavior:
|
||||
scaleUp:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 50
|
||||
periodSeconds: 60
|
||||
scaleDown:
|
||||
stabilizationWindowSeconds: 300
|
||||
policies:
|
||||
- type: Percent
|
||||
value: 10
|
||||
periodSeconds: 60
|
||||
22
deploy/kubernetes/ingress.yaml
Normal file
22
deploy/kubernetes/ingress.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: s3-balance-ingress
|
||||
namespace: s3-balance
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: s3-balance.local
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: s3-balance-service
|
||||
port:
|
||||
number: 8080
|
||||
7
deploy/kubernetes/namespace.yaml
Normal file
7
deploy/kubernetes/namespace.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
tier: backend
|
||||
34
deploy/kubernetes/service.yaml
Normal file
34
deploy/kubernetes/service.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: s3-balance-service
|
||||
namespace: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
spec:
|
||||
selector:
|
||||
app: s3-balance
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: s3-balance-metrics-service
|
||||
namespace: s3-balance
|
||||
labels:
|
||||
app: s3-balance
|
||||
service-type: metrics
|
||||
spec:
|
||||
selector:
|
||||
app: s3-balance
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: metrics
|
||||
type: ClusterIP
|
||||
279
deploy/monitoring/grafana/dashboards/s3-balance-dashboard.json
Normal file
279
deploy/monitoring/grafana/dashboards/s3-balance-dashboard.json
Normal file
@@ -0,0 +1,279 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"description": "S3 Balance 负载均衡服务监控 Dashboard",
|
||||
"editable": true,
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": 1,
|
||||
"links": [],
|
||||
"panels": [
|
||||
{
|
||||
"datasource": "Prometheus",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"vis": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": true,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "reqps"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "rate(s3_balance_s3_operations_total[5m])",
|
||||
"legendFormat": "{{operation}} - {{bucket}} - {{status}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "QPS (操作/秒)",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": "Prometheus",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"options": {
|
||||
"0": {
|
||||
"color": "red",
|
||||
"index": 0,
|
||||
"text": "Unhealthy"
|
||||
},
|
||||
"1": {
|
||||
"color": "green",
|
||||
"index": 1,
|
||||
"text": "Healthy"
|
||||
}
|
||||
},
|
||||
"type": "value"
|
||||
}
|
||||
],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "none"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"text": {},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.0.0",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "s3_balance_bucket_healthy",
|
||||
"legendFormat": "{{bucket}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "存储桶健康状态",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": "Prometheus",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"vis": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": true,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
},
|
||||
"id": 3,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": ["avg"],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.50, s3_balance_s3_operation_duration_seconds_bucket)",
|
||||
"legendFormat": "P50 - {{operation}}",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.95, s3_balance_s3_operation_duration_seconds_bucket)",
|
||||
"legendFormat": "P95 - {{operation}}",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.99, s3_balance_s3_operation_duration_seconds_bucket)",
|
||||
"legendFormat": "P99 - {{operation}}",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"title": "操作延迟 (秒)",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 30,
|
||||
"style": "dark",
|
||||
"tags": ["s3-balance", "monitoring"],
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "S3 Balance 监控面板",
|
||||
"uid": "s3-balance-monitoring",
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
# Grafana 仪表板提供者配置
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: 'S3 Balance'
|
||||
orgId: 1
|
||||
folder: ''
|
||||
type: file
|
||||
disableDeletion: false
|
||||
updateIntervalSeconds: 10
|
||||
allowUiUpdates: true
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards
|
||||
@@ -0,0 +1,11 @@
|
||||
# Grafana 数据源配置
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
access: proxy
|
||||
url: http://prometheus:9090
|
||||
isDefault: true
|
||||
jsonData:
|
||||
timeInterval: 5s
|
||||
30
deploy/monitoring/prometheus.yml
Normal file
30
deploy/monitoring/prometheus.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
# Prometheus 配置 - 抓取 S3 Balance 指标
|
||||
global:
|
||||
scrape_interval: 15s # 抓取间隔
|
||||
evaluation_interval: 15s # 评估间隔
|
||||
|
||||
# 告警规则文件
|
||||
rule_files:
|
||||
- "s3_balance_alerts.yml"
|
||||
|
||||
# 抓取配置
|
||||
scrape_configs:
|
||||
# S3 Balance 服务指标
|
||||
- job_name: 's3-balance'
|
||||
static_configs:
|
||||
- targets: ['s3-balance:8080']
|
||||
metrics_path: '/metrics'
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
|
||||
# Node Exporter (系统指标)
|
||||
- job_name: 'node-exporter'
|
||||
static_configs:
|
||||
- targets: ['node-exporter:9100']
|
||||
scrape_interval: 15s
|
||||
|
||||
# 告警配置
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- static_configs:
|
||||
- targets: [] # 可以添加 AlertManager 地址
|
||||
73
deploy/monitoring/s3_balance_alerts.yml
Normal file
73
deploy/monitoring/s3_balance_alerts.yml
Normal file
@@ -0,0 +1,73 @@
|
||||
# S3 Balance 告警规则
|
||||
groups:
|
||||
- name: s3_balance_alerts
|
||||
rules:
|
||||
# 存储桶不健康告警
|
||||
- alert: BucketUnhealthy
|
||||
expr: s3_balance_bucket_healthy == 0
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "存储桶 {{ $labels.bucket }} 不健康"
|
||||
description: "存储桶 {{ $labels.bucket }} ({{ $labels.endpoint }}) 已经连续5分钟不可用"
|
||||
|
||||
# 错误率过高告警
|
||||
- alert: HighErrorRate
|
||||
expr: rate(s3_balance_s3_operations_total{status="error"}[5m]) > 0.1
|
||||
for: 2m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "存储桶 {{ $labels.bucket }} 错误率过高"
|
||||
description: "存储桶 {{ $labels.bucket }} 错误率超过10%,操作: {{ $labels.operation }}"
|
||||
|
||||
# 操作延迟过高告警
|
||||
- alert: HighLatency
|
||||
expr: histogram_quantile(0.95, rate(s3_balance_s3_operation_duration_seconds_bucket[5m])) > 1
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "{{ $labels.operation }} 操作延迟过高"
|
||||
description: "{{ $labels.operation }} 操作95%分位数延迟超过1秒"
|
||||
|
||||
# 存储桶使用率告警
|
||||
- alert: BucketUsageHigh
|
||||
expr: s3_balance_bucket_usage_bytes / s3_balance_bucket_capacity_bytes > 0.9
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "存储桶 {{ $labels.bucket }} 使用率过高"
|
||||
description: "存储桶 {{ $labels.bucket }} 使用率超过90%"
|
||||
|
||||
# 存储桶满告警
|
||||
- alert: BucketFull
|
||||
expr: s3_balance_bucket_usage_bytes / s3_balance_bucket_capacity_bytes >= 0.95
|
||||
for: 1m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "存储桶 {{ $labels.bucket }} 即将满了"
|
||||
description: "存储桶 {{ $labels.bucket }} 使用率达到95%"
|
||||
|
||||
# QPS过低告警 (可能服务异常)
|
||||
- alert: LowQPS
|
||||
expr: rate(s3_balance_s3_operations_total[5m]) == 0
|
||||
for: 10m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "QPS异常低"
|
||||
description: "系统QPS为0,可能服务异常无请求"
|
||||
|
||||
# 负载均衡失败告警
|
||||
- alert: BalancerDecisionFailure
|
||||
expr: increase(s3_balance_balancer_decisions_total[5m]) == 0
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "负载均衡决策异常"
|
||||
description: "5分钟内没有负载均衡决策,可能存储桶全部不可用"
|
||||
309
deploy/start.sh
Executable file
309
deploy/start.sh
Executable file
@@ -0,0 +1,309 @@
|
||||
#!/bin/bash
|
||||
|
||||
# S3 Balance 快速部署脚本
|
||||
# 支持 Docker、Docker Compose、Kubernetes、HELM 四种部署方式
|
||||
|
||||
set -e
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "S3 Balance 快速部署脚本"
|
||||
echo ""
|
||||
echo "用法: ./start.sh [选项]"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " -m, --mode MODE 部署模式: docker|compose|kubernetes|helm"
|
||||
echo " -e, --env ENV 环境: dev|test|prod (默认: dev)"
|
||||
echo " -b, --build 构建镜像"
|
||||
echo " -p, --port PORT 服务端口 (默认: 8080)"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " ./start.sh -m compose -e prod"
|
||||
echo " ./start.sh -m kubernetes --build"
|
||||
echo " ./start.sh -m helm -e test"
|
||||
}
|
||||
|
||||
# 默认参数
|
||||
MODE="compose"
|
||||
ENV="dev"
|
||||
BUILD=false
|
||||
PORT="8080"
|
||||
|
||||
# 解析命令行参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-m|--mode)
|
||||
MODE="$2"
|
||||
shift 2
|
||||
;;
|
||||
-e|--env)
|
||||
ENV="$2"
|
||||
shift 2
|
||||
;;
|
||||
-b|--build)
|
||||
BUILD=true
|
||||
shift
|
||||
;;
|
||||
-p|--port)
|
||||
PORT="$2"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知选项: $1"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 输出配置信息
|
||||
echo "🚀 S3 Balance 快速部署开始..."
|
||||
echo "📋 配置信息:"
|
||||
echo " 部署模式: $MODE"
|
||||
echo " 环境: $ENV"
|
||||
echo " 构建镜像: $BUILD"
|
||||
echo " 服务端口: $PORT"
|
||||
echo ""
|
||||
|
||||
# 检查必要工具
|
||||
check_requirements() {
|
||||
local tool=$1
|
||||
local tool_name=$2
|
||||
if ! command -v $tool &> /dev/null; then
|
||||
echo "❌ $tool_name 未安装"
|
||||
return 1
|
||||
fi
|
||||
echo "✅ $tool_name 已安装"
|
||||
}
|
||||
|
||||
# Docker 模式部署
|
||||
deploy_docker() {
|
||||
echo "📦 Docker 单容器部署..."
|
||||
|
||||
check_requirements docker "Docker" || exit 1
|
||||
|
||||
if [ "$BUILD" = true ]; then
|
||||
echo "🔨 构建 Docker 镜像..."
|
||||
docker build -t s3-balance:$MODE-$ENV -f deploy/docker/Dockerfile .
|
||||
fi
|
||||
|
||||
echo "🚀 启动容器..."
|
||||
docker run -d \
|
||||
--name s3-balance-$ENV \
|
||||
-p $PORT:8080 \
|
||||
-v $(pwd)/deploy/docker/config.docker.yaml:/app/config/config.yaml \
|
||||
-v s3-balance-data:/app/data \
|
||||
-e TZ=Asia/Shanghai \
|
||||
--restart unless-stopped \
|
||||
s3-balance:$MODE-$ENV
|
||||
|
||||
echo "✅ Docker 容器已启动"
|
||||
}
|
||||
|
||||
# Docker Compose 模式部署
|
||||
deploy_compose() {
|
||||
echo "🐳 Docker Compose 部署..."
|
||||
|
||||
check_requirements docker "Docker" || exit 1
|
||||
check_requirements docker-compose "Docker Compose" || exit 1
|
||||
|
||||
if [ "$BUILD" = true ]; then
|
||||
echo "🔨 构建 Docker 镜像..."
|
||||
cd deploy/docker
|
||||
docker build -t s3-balance:$MODE-$ENV -f Dockerfile ../..
|
||||
fi
|
||||
|
||||
echo "🚀 启动服务栈..."
|
||||
cd deploy/docker
|
||||
|
||||
# 修改 docker-compose.yml 中的端口
|
||||
if [ "$PORT" != "8080" ]; then
|
||||
sed -i.bak "s/8080:8080/$PORT:8080/" docker-compose.yml
|
||||
fi
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
# 恢复配置文件
|
||||
if [ "$PORT" != "8080" ]; then
|
||||
mv docker-compose.yml.bak docker-compose.yml
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
echo "✅ Docker Compose 服务已启动"
|
||||
}
|
||||
|
||||
# Kubernetes 模式部署
|
||||
deploy_kubernetes() {
|
||||
echo "☸️ Kubernetes 部署..."
|
||||
|
||||
check_requirements kubectl "kubectl" || exit 1
|
||||
check_requirements kubectl "Kubernetes 集群连接" || exit 1
|
||||
|
||||
echo "🚀 应用 Kubernetes 配置..."
|
||||
cd deploy/kubernetes
|
||||
|
||||
# 替换环境变量
|
||||
if [ "$ENV" != "dev" ]; then
|
||||
# 根据环境替换镜像标签
|
||||
sed -i.bak 's/image: s3-balance:latest/image: s3-balance:'"$ENV"'/' deployment.yaml
|
||||
fi
|
||||
|
||||
kubectl apply -f namespace.yaml
|
||||
kubectl apply -f configmap.yaml
|
||||
kubectl apply -f deployment.yaml
|
||||
kubectl apply -f service.yaml
|
||||
kubectl apply -f ingress.yaml
|
||||
|
||||
# 如果是生产环境,应用 HPA
|
||||
if [ "$ENV" = "prod" ]; then
|
||||
kubectl apply -f hpa.yaml
|
||||
echo "📊 已启用水平自动扩缩容"
|
||||
fi
|
||||
|
||||
# 恢复配置文件
|
||||
if [ -f deployment.yaml.bak ]; then
|
||||
mv deployment.yaml.bak deployment.yaml
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
echo "✅ Kubernetes 部署完成"
|
||||
}
|
||||
|
||||
# HELM 模式部署
|
||||
deploy_helm() {
|
||||
echo "🔧 HELM Chart 部署..."
|
||||
|
||||
check_requirements helm "HELM" || exit 1
|
||||
check_requirements kubectl "kubectl" || exit 1
|
||||
|
||||
echo "🚀 部署 HELM Chart..."
|
||||
cd deploy/helm
|
||||
|
||||
# 根据环境选择 values 文件
|
||||
VALUES_FILE="values.yaml"
|
||||
if [ "$ENV" = "prod" ] && [ -f "production-values.yaml" ]; then
|
||||
VALUES_FILE="production-values.yaml"
|
||||
fi
|
||||
|
||||
# 安装或升级 Chart
|
||||
if helm status s3-balance-$ENV 2>/dev/null; then
|
||||
echo "⬆️ 升级现有 HELM 发布..."
|
||||
helm upgrade s3-balance-$ENV s3-balance -f $VALUES_FILE \
|
||||
--namespace s3-balance-$ENV \
|
||||
--create-namespace \
|
||||
--wait
|
||||
else
|
||||
echo "📦 安装新的 HELM Chart..."
|
||||
helm install s3-balance-$ENV s3-balance -f $VALUES_FILE \
|
||||
--namespace s3-balance-$ENV \
|
||||
--create-namespace \
|
||||
--wait
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
echo "✅ HELM Chart 部署完成"
|
||||
}
|
||||
|
||||
# 通用后处理
|
||||
post_deploy() {
|
||||
echo ""
|
||||
echo "⏳ 等待服务启动..."
|
||||
sleep 10
|
||||
|
||||
case $MODE in
|
||||
docker)
|
||||
echo ""
|
||||
echo "✅ Docker 部署完成!"
|
||||
echo "🔗 访问地址:"
|
||||
echo " 📊 指标端点: http://localhost:$PORT/metrics"
|
||||
echo ""
|
||||
echo "📝 Docker 命令:"
|
||||
echo " docker logs -f s3-balance-$ENV # 查看日志"
|
||||
echo " docker stop s3-balance-$ENV # 停止服务"
|
||||
echo " docker rm s3-balance-$ENV # 删除容器"
|
||||
;;
|
||||
|
||||
compose)
|
||||
echo ""
|
||||
echo "✅ Docker Compose 部署完成!"
|
||||
echo "🔗 访问地址:"
|
||||
echo " 📊 Grafana 面板: http://localhost:3000 (admin/admin123)"
|
||||
echo " 🔥 Prometheus: http://localhost:9090"
|
||||
echo " 📈 指标端点: http://localhost:$PORT/metrics"
|
||||
echo ""
|
||||
echo "📝 Compose 命令:"
|
||||
echo " cd deploy/docker && docker-compose logs -f # 查看日志"
|
||||
echo " cd deploy/docker && docker-compose down # 停止服务"
|
||||
;;
|
||||
|
||||
kubernetes)
|
||||
echo ""
|
||||
echo "✅ Kubernetes 部署完成!"
|
||||
echo "🔗 检查状态:"
|
||||
echo " kubectl get pods -n s3-balance"
|
||||
echo " kubectl get svc -n s3-balance"
|
||||
echo " kubectl get ingress -n s3-balance"
|
||||
echo ""
|
||||
echo "📋 常用命令:"
|
||||
echo " kubectl logs -f deployment/s3-balance-deployment -n s3-balance"
|
||||
echo " kubectl scale deployment s3-balance-deployment --replicas=5 -n s3-balance"
|
||||
;;
|
||||
|
||||
helm)
|
||||
echo ""
|
||||
echo "✅ HELM Chart 部署完成!"
|
||||
echo "🔗 检查状态:"
|
||||
echo " helm status s3-balance-$ENV -n s3-balance-$ENV"
|
||||
echo " kubectl get pods -n s3-balance-$ENV"
|
||||
echo " kubectl get svc -n s3-balance-$ENV"
|
||||
echo ""
|
||||
echo "🔧 HELM 命令:"
|
||||
echo " helm uninstall s3-balance-$ENV -n s3-balance-$ENV"
|
||||
echo " helm list -A"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo ""
|
||||
echo "📊 监控指标查询:"
|
||||
echo " - 存储桶健康: s3_balance_bucket_healthy"
|
||||
echo " - QPS: rate(s3_balance_s3_operations_total[1m])"
|
||||
echo " - 延迟: histogram_quantile(0.95, s3_balance_s3_operation_duration_seconds_bucket)"
|
||||
echo ""
|
||||
echo "🎉 部署完成!享受 S3 Balance 服务!"
|
||||
}
|
||||
|
||||
# 主执行逻辑
|
||||
main() {
|
||||
echo "🚀 开始部署 S3 Balance..."
|
||||
|
||||
# 根据模式执行部署
|
||||
case $MODE in
|
||||
docker)
|
||||
deploy_docker
|
||||
;;
|
||||
compose)
|
||||
deploy_compose
|
||||
;;
|
||||
kubernetes)
|
||||
deploy_kubernetes
|
||||
;;
|
||||
helm)
|
||||
deploy_helm
|
||||
;;
|
||||
*)
|
||||
echo "❌ 未知部署模式: $MODE"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
post_deploy
|
||||
}
|
||||
|
||||
# 执行主函数
|
||||
main
|
||||
14
go.mod
14
go.mod
@@ -8,6 +8,7 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.18.5
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.87.0
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.6.0
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
@@ -31,6 +32,8 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.37.1 // indirect
|
||||
github.com/aws/smithy-go v1.22.5 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
@@ -40,8 +43,15 @@ require (
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.66.1 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
)
|
||||
|
||||
44
go.sum
44
go.sum
@@ -36,12 +36,18 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.37.1 h1:ssCHKyNJqTnqRH4Vlf+jI0brtGQY
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.37.1/go.mod h1:JdeBDPgpJfuS6rU/hNglmOigKhyEZtBmbraLE4GK1J8=
|
||||
github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw=
|
||||
github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
@@ -56,27 +62,49 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
|
||||
Reference in New Issue
Block a user