- 添加 Harbor 快速恢复脚本 (harbor-quick-restore.sh) - 添加完整恢复指南 (HARBOR-RESTORE-GUIDE.md) - 添加版本信息文件 (VERSION.md) - 更新 .gitignore 排除敏感数据 - 配置 harbor git remote - 修复 Cloudflare Tunnel 配置 系统重装后可通过以下命令快速恢复: git clone http://192.168.1.83:33000/gao/ljwx-harbor.git cd ljwx-harbor ./harbor-quick-restore.sh
885 lines
22 KiB
Bash
Executable File
885 lines
22 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
#==============================================================================
|
||
# AI Context Optimizer - 智能上下文优化器
|
||
# 根据使用场景生成最优的 AI 上下文
|
||
#==============================================================================
|
||
|
||
set -euo pipefail
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
CYAN='\033[0;36m'
|
||
NC='\033[0m'
|
||
|
||
# 配置
|
||
BASE_DIR="/Users/brunogao/work/codes/tools/macos"
|
||
OUTPUT_DIR="$BASE_DIR/contexts"
|
||
TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
|
||
|
||
# 创建输出目录
|
||
mkdir -p "$OUTPUT_DIR"
|
||
|
||
#==============================================================================
|
||
# 显示使用说明
|
||
#==============================================================================
|
||
|
||
show_usage() {
|
||
cat << EOF
|
||
${BLUE}🤖 AI Context Optimizer - 智能上下文生成器${NC}
|
||
|
||
${GREEN}使用方法:${NC}
|
||
$0 [选项] [场景]
|
||
|
||
${GREEN}场景类型:${NC}
|
||
${CYAN}core${NC} - 核心上下文(最小化,~5KB)
|
||
${CYAN}dev${NC} - 开发场景(包含工具和服务)
|
||
${CYAN}deploy${NC} - 部署场景(K8s、Harbor、镜像)
|
||
${CYAN}debug${NC} - 故障排查(日志、状态、健康检查)
|
||
${CYAN}full${NC} - 完整上下文(所有信息)
|
||
${CYAN}auto${NC} - 智能推荐(根据最近操作)
|
||
|
||
${GREEN}选项:${NC}
|
||
-o, --output FILE 指定输出文件
|
||
-f, --format TYPE 输出格式 (markdown|json|yaml)
|
||
-s, --secure 安全模式(过滤敏感信息)
|
||
-c, --compress 压缩模式(移除详细列表)
|
||
-h, --help 显示此帮助信息
|
||
|
||
${GREEN}示例:${NC}
|
||
# 生成核心上下文
|
||
$0 core
|
||
|
||
# 生成开发场景上下文(安全模式)
|
||
$0 dev --secure
|
||
|
||
# 生成故障排查上下文(JSON格式)
|
||
$0 debug --format json
|
||
|
||
# 智能推荐上下文
|
||
$0 auto
|
||
|
||
${GREEN}输出位置:${NC}
|
||
$OUTPUT_DIR/
|
||
|
||
EOF
|
||
}
|
||
|
||
#==============================================================================
|
||
# 工具函数
|
||
#==============================================================================
|
||
|
||
log_info() {
|
||
echo -e "${BLUE}ℹ${NC} $1"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}✓${NC} $1"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}⚠${NC} $1"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}✗${NC} $1"
|
||
}
|
||
|
||
check_command() {
|
||
command -v "$1" >/dev/null 2>&1
|
||
}
|
||
|
||
get_service_status() {
|
||
local service=$1
|
||
if docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${service}$"; then
|
||
echo "running"
|
||
else
|
||
echo "stopped"
|
||
fi
|
||
}
|
||
|
||
#==============================================================================
|
||
# 安全过滤
|
||
#==============================================================================
|
||
|
||
filter_sensitive_info() {
|
||
local content="$1"
|
||
|
||
# 过滤密码
|
||
content=$(echo "$content" | sed 's/password[[:space:]]*=[[:space:]]*[^[:space:]]*/password=***FILTERED***/gi')
|
||
content=$(echo "$content" | sed 's/PASSWORD:[[:space:]]*[^[:space:]]*/PASSWORD: ***FILTERED***/gi')
|
||
|
||
# 过滤 API 密钥
|
||
content=$(echo "$content" | sed 's/api[_-]key[[:space:]]*=[[:space:]]*[^[:space:]]*/api_key=***FILTERED***/gi')
|
||
|
||
# 过滤 Token
|
||
content=$(echo "$content" | sed 's/token[[:space:]]*=[[:space:]]*[^[:space:]]*/token=***FILTERED***/gi')
|
||
|
||
# 过滤凭据字段但保留结构
|
||
content=$(echo "$content" | sed 's/\(admin\/\)[^[:space:]]*/\1***FILTERED***/g')
|
||
|
||
echo "$content"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 获取智能推荐场景
|
||
#==============================================================================
|
||
|
||
get_smart_scenario() {
|
||
local scenario="dev" # 默认
|
||
|
||
# 检查最近的 kubectl 操作
|
||
if history 50 2>/dev/null | grep -q "kubectl.*\(apply\|create\|run\)"; then
|
||
scenario="deploy"
|
||
fi
|
||
|
||
# 检查最近的故障排查操作
|
||
if history 50 2>/dev/null | grep -qE "kubectl.*(describe|logs|get.*-o.*yaml)"; then
|
||
scenario="debug"
|
||
fi
|
||
|
||
# 检查最近的开发操作
|
||
if history 50 2>/dev/null | grep -qE "(docker build|npm|python|go build)"; then
|
||
scenario="dev"
|
||
fi
|
||
|
||
echo "$scenario"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 核心上下文生成(最小化)
|
||
#==============================================================================
|
||
|
||
generate_core_context() {
|
||
local output_file="$1"
|
||
|
||
log_info "生成核心上下文..."
|
||
|
||
cat > "$output_file" << EOF
|
||
# AI Development Core Context
|
||
> 生成时间: $TIMESTAMP | 类型: 核心上下文
|
||
|
||
## 系统概况
|
||
- **主机**: $(hostname) ($(uname -m))
|
||
- **IP**: $(ipconfig getifaddr en0 2>/dev/null || echo "N/A")
|
||
- **OS**: $(sw_vers -productName) $(sw_vers -productVersion)
|
||
|
||
## 关键服务
|
||
EOF
|
||
|
||
# Harbor 状态
|
||
if [ "$(get_service_status 'harbor-core')" = "running" ]; then
|
||
cat >> "$output_file" << EOF
|
||
- **Harbor**: ✅ http://$(ipconfig getifaddr en0):8080 (admin/admin123)
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- **Harbor**: ❌ 未运行
|
||
EOF
|
||
fi
|
||
|
||
# Gitea 状态
|
||
if [ "$(get_service_status 'gitea')" = "running" ]; then
|
||
cat >> "$output_file" << EOF
|
||
- **Gitea**: ✅ http://$(ipconfig getifaddr en0):33000
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- **Gitea**: ❌ 未运行
|
||
EOF
|
||
fi
|
||
|
||
# K8s 状态
|
||
if check_command kubectl && kubectl cluster-info >/dev/null 2>&1; then
|
||
cat >> "$output_file" << EOF
|
||
- **Kubernetes**: ✅ $(kubectl get nodes --no-headers | wc -l | xargs) 节点, $(kubectl get pods -A --no-headers 2>/dev/null | wc -l | xargs) Pods
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- **Kubernetes**: ❌ 未连接
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
## 快速命令
|
||
\`\`\`bash
|
||
# 查看服务
|
||
docker ps --format "{{.Names}}: {{.Status}}"
|
||
|
||
# K8s 状态
|
||
kubectl get pods -A
|
||
|
||
# 镜像缓存
|
||
cd $BASE_DIR/k8s && ./cache-image.sh <image>
|
||
\`\`\`
|
||
EOF
|
||
|
||
log_success "核心上下文已生成 → $output_file"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 开发场景上下文
|
||
#==============================================================================
|
||
|
||
generate_dev_context() {
|
||
local output_file="$1"
|
||
|
||
log_info "生成开发场景上下文..."
|
||
|
||
cat > "$output_file" << EOF
|
||
# AI Development Context - Development Scenario
|
||
> 生成时间: $TIMESTAMP | 场景: 开发环境
|
||
|
||
## 开发工具链
|
||
|
||
### 容器和编排
|
||
$(if check_command docker; then
|
||
echo "- **Docker**: $(docker --version | awk '{print $3}' | tr -d ',')"
|
||
echo " - 镜像: $(docker images -q | wc -l | xargs) 个"
|
||
echo " - 容器: $(docker ps -q | wc -l | xargs) 运行中 / $(docker ps -aq | wc -l | xargs) 总数"
|
||
fi)
|
||
|
||
$(if check_command kubectl; then
|
||
echo "- **Kubernetes**: $(kubectl version --client --short 2>/dev/null | head -n1 || echo "已安装")"
|
||
if kubectl cluster-info >/dev/null 2>&1; then
|
||
echo " - 集群: $(kubectl config current-context)"
|
||
echo " - 命名空间: $(kubectl get ns --no-headers | wc -l | xargs) 个"
|
||
fi
|
||
fi)
|
||
|
||
$(if check_command helm; then
|
||
echo "- **Helm**: $(helm version --short 2>/dev/null)"
|
||
echo " - Releases: $(helm list -A 2>/dev/null | tail -n +2 | wc -l | xargs) 个"
|
||
fi)
|
||
|
||
### 编程语言
|
||
$(if check_command python3; then
|
||
echo "- **Python**: $(python3 --version | awk '{print $2}')"
|
||
fi)
|
||
|
||
$(if check_command node; then
|
||
echo "- **Node.js**: $(node --version)"
|
||
echo " - npm: v$(npm --version)"
|
||
fi)
|
||
|
||
$(if check_command go; then
|
||
echo "- **Go**: $(go version | awk '{print $3}')"
|
||
fi)
|
||
|
||
### AI 工具
|
||
$(if check_command ollama && pgrep -x ollama >/dev/null; then
|
||
echo "- **Ollama**: 🟢 运行中"
|
||
echo " - 端点: http://localhost:11434"
|
||
echo " - 模型数: $(ollama list 2>/dev/null | tail -n +2 | wc -l | xargs)"
|
||
else
|
||
echo "- **Ollama**: 🔴 未运行"
|
||
fi)
|
||
|
||
## 开发服务
|
||
|
||
### Gitea (代码托管)
|
||
EOF
|
||
|
||
if [ "$(get_service_status 'gitea')" = "running" ]; then
|
||
cat >> "$output_file" << EOF
|
||
- **状态**: ✅ 运行中
|
||
- **访问**: http://$(ipconfig getifaddr en0):33000
|
||
- **Git SSH**: git@$(ipconfig getifaddr en0):32222/user/repo.git
|
||
- **管理**:
|
||
\`\`\`bash
|
||
cd ~/ops/gitea
|
||
./gitea-data-protection.sh [start|stop|health]
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- **状态**: ❌ 未运行
|
||
- **启动**: \`cd ~/ops/gitea && ./gitea-data-protection.sh start\`
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
### Harbor (镜像仓库)
|
||
EOF
|
||
|
||
if [ "$(get_service_status 'harbor-core')" = "running" ]; then
|
||
cat >> "$output_file" << EOF
|
||
- **状态**: ✅ 运行中
|
||
- **访问**: http://$(ipconfig getifaddr en0):8080
|
||
- **推送镜像**:
|
||
\`\`\`bash
|
||
docker tag myimage:tag harbor.omniverseai.net:8080/library/myimage:tag
|
||
docker push harbor.omniverseai.net:8080/library/myimage:tag
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- **状态**: ❌ 未运行
|
||
- **启动**: \`cd ~/ops/harbor && ./harbor-data-protection.sh start\`
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
## 开发工作流
|
||
|
||
### 1. 本地开发
|
||
\`\`\`bash
|
||
# 启动开发环境
|
||
docker-compose up -d
|
||
|
||
# 运行测试
|
||
pytest / npm test / go test
|
||
|
||
# 构建镜像
|
||
docker build -t myapp:latest .
|
||
\`\`\`
|
||
|
||
### 2. 推送到仓库
|
||
\`\`\`bash
|
||
# Git 推送
|
||
git push origin main
|
||
|
||
# 镜像推送
|
||
docker tag myapp:latest harbor.omniverseai.net:8080/library/myapp:latest
|
||
docker push harbor.omniverseai.net:8080/library/myapp:latest
|
||
\`\`\`
|
||
|
||
### 3. 部署到 K8s
|
||
\`\`\`bash
|
||
# 应用配置
|
||
kubectl apply -f deployment.yaml
|
||
|
||
# 查看状态
|
||
kubectl get pods
|
||
kubectl logs -f <pod-name>
|
||
\`\`\`
|
||
|
||
## 常用路径
|
||
- **项目根目录**: $BASE_DIR
|
||
- **脚本目录**: $BASE_DIR/scripts
|
||
- **K8s 工具**: $BASE_DIR/k8s
|
||
- **数据目录**: ~/ops/data
|
||
- **备份目录**: ~/ops/backups
|
||
EOF
|
||
|
||
log_success "开发场景上下文已生成 → $output_file"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 部署场景上下文
|
||
#==============================================================================
|
||
|
||
generate_deploy_context() {
|
||
local output_file="$1"
|
||
|
||
log_info "生成部署场景上下文..."
|
||
|
||
cat > "$output_file" << EOF
|
||
# AI Development Context - Deployment Scenario
|
||
> 生成时间: $TIMESTAMP | 场景: 部署运维
|
||
|
||
## Kubernetes 集群
|
||
|
||
### 集群信息
|
||
EOF
|
||
|
||
if check_command kubectl && kubectl cluster-info >/dev/null 2>&1; then
|
||
cat >> "$output_file" << EOF
|
||
- **上下文**: $(kubectl config current-context)
|
||
- **API Server**: $(kubectl cluster-info 2>/dev/null | head -n1 | grep -oE 'https?://[^ ]+')
|
||
- **节点数**: $(kubectl get nodes --no-headers | wc -l | xargs)
|
||
|
||
### 命名空间
|
||
\`\`\`
|
||
$(kubectl get ns --no-headers | awk '{print $1}' | head -20)
|
||
\`\`\`
|
||
|
||
### 异常 Pod(需要关注)
|
||
EOF
|
||
|
||
local unhealthy=$(kubectl get pods -A --field-selector=status.phase!=Running 2>/dev/null | tail -n +2)
|
||
if [ -n "$unhealthy" ]; then
|
||
cat >> "$output_file" << EOF
|
||
\`\`\`
|
||
$(echo "$unhealthy" | head -10)
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
✅ 所有 Pod 运行正常
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
### Helm Releases
|
||
\`\`\`
|
||
$(helm list -A 2>/dev/null | head -15)
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
⚠️ Kubernetes 集群未连接
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
## Harbor 镜像仓库
|
||
EOF
|
||
|
||
if [ "$(get_service_status 'harbor-core')" = "running" ]; then
|
||
cat >> "$output_file" << EOF
|
||
- **状态**: ✅ 运行中
|
||
- **地址**: harbor.omniverseai.net:8080
|
||
- **Projects**: library (默认)
|
||
|
||
### 镜像缓存工具
|
||
\`\`\`bash
|
||
cd $BASE_DIR/k8s
|
||
|
||
# 自动修复 ImagePullBackOff
|
||
./cache-image.sh --update-deployment <namespace>/<deployment>
|
||
|
||
# 手动缓存镜像
|
||
./cache-image.sh nginx:alpine redis:7 mysql:8.0
|
||
|
||
# 批量缓存
|
||
./cache-image.sh -f images.txt
|
||
\`\`\`
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
## 部署流程
|
||
|
||
### 1. 准备镜像
|
||
\`\`\`bash
|
||
# 方式1: 本地构建
|
||
docker build -t myapp:v1.0 .
|
||
docker tag myapp:v1.0 harbor.omniverseai.net:8080/library/myapp:v1.0
|
||
docker push harbor.omniverseai.net:8080/library/myapp:v1.0
|
||
|
||
# 方式2: 缓存公共镜像
|
||
cd $BASE_DIR/k8s
|
||
./cache-image.sh nginx:alpine
|
||
# 使用: harbor.omniverseai.net:8080/library/nginx:alpine
|
||
\`\`\`
|
||
|
||
### 2. 创建部署配置
|
||
\`\`\`yaml
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: myapp
|
||
namespace: default
|
||
spec:
|
||
replicas: 2
|
||
selector:
|
||
matchLabels:
|
||
app: myapp
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: myapp
|
||
spec:
|
||
containers:
|
||
- name: myapp
|
||
image: harbor.omniverseai.net:8080/library/myapp:v1.0
|
||
ports:
|
||
- containerPort: 8080
|
||
\`\`\`
|
||
|
||
### 3. 部署和验证
|
||
\`\`\`bash
|
||
# 应用配置
|
||
kubectl apply -f deployment.yaml
|
||
|
||
# 查看状态
|
||
kubectl get pods -w
|
||
|
||
# 查看日志
|
||
kubectl logs -f deployment/myapp
|
||
|
||
# 查看详情
|
||
kubectl describe pod <pod-name>
|
||
\`\`\`
|
||
|
||
### 4. 故障排查
|
||
\`\`\`bash
|
||
# ImagePullBackOff 修复
|
||
cd $BASE_DIR/k8s
|
||
./cache-image.sh --update-deployment default/myapp
|
||
|
||
# 手动检查
|
||
kubectl describe pod <pod-name>
|
||
kubectl logs <pod-name>
|
||
kubectl get events --sort-by='.lastTimestamp'
|
||
\`\`\`
|
||
|
||
## 快速参考
|
||
|
||
### 常用部署命令
|
||
| 操作 | 命令 |
|
||
|------|------|
|
||
| 应用配置 | \`kubectl apply -f file.yaml\` |
|
||
| 查看 Pod | \`kubectl get pods -A\` |
|
||
| 查看日志 | \`kubectl logs -f <pod>\` |
|
||
| 进入容器 | \`kubectl exec -it <pod> -- /bin/bash\` |
|
||
| 删除部署 | \`kubectl delete deployment <name>\` |
|
||
| 扩缩容 | \`kubectl scale deployment <name> --replicas=3\` |
|
||
| 滚动更新 | \`kubectl set image deployment/<name> <container>=<image>\` |
|
||
|
||
### 镜像缓存快捷方式
|
||
\`\`\`bash
|
||
# 添加到 ~/.zshrc
|
||
alias cache-img='cd $BASE_DIR/k8s && ./cache-image.sh'
|
||
alias fix-pod='cd $BASE_DIR/k8s && ./cache-image.sh --update-deployment'
|
||
|
||
# 使用
|
||
cache-img nginx:alpine
|
||
fix-pod default/myapp
|
||
\`\`\`
|
||
EOF
|
||
|
||
log_success "部署场景上下文已生成 → $output_file"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 故障排查场景上下文
|
||
#==============================================================================
|
||
|
||
generate_debug_context() {
|
||
local output_file="$1"
|
||
|
||
log_info "生成故障排查场景上下文..."
|
||
|
||
cat > "$output_file" << EOF
|
||
# AI Development Context - Debug Scenario
|
||
> 生成时间: $TIMESTAMP | 场景: 故障排查
|
||
|
||
## 系统健康状态
|
||
|
||
### Docker 服务
|
||
EOF
|
||
|
||
if check_command docker && docker ps >/dev/null 2>&1; then
|
||
local total_containers=$(docker ps -aq | wc -l | xargs)
|
||
local running_containers=$(docker ps -q | wc -l | xargs)
|
||
local stopped_containers=$((total_containers - running_containers))
|
||
|
||
cat >> "$output_file" << EOF
|
||
- ✅ Docker 运行正常
|
||
- 容器: $running_containers 运行中, $stopped_containers 停止
|
||
|
||
#### 近期重启的容器
|
||
\`\`\`
|
||
$(docker ps -a --format "{{.Names}}: {{.Status}}" | grep -i restart | head -10 || echo "无")
|
||
\`\`\`
|
||
|
||
#### Unhealthy 容器
|
||
\`\`\`
|
||
$(docker ps --filter "health=unhealthy" --format "{{.Names}}: {{.Status}}" || echo "无")
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- ❌ Docker 未运行或无权限
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
### Kubernetes 集群
|
||
EOF
|
||
|
||
if check_command kubectl && kubectl cluster-info >/dev/null 2>&1; then
|
||
cat >> "$output_file" << EOF
|
||
- ✅ 集群连接正常
|
||
|
||
#### 异常 Pod
|
||
\`\`\`
|
||
$(kubectl get pods -A --field-selector=status.phase!=Running 2>/dev/null | head -20 || echo "所有 Pod 正常")
|
||
\`\`\`
|
||
|
||
#### 最近的事件
|
||
\`\`\`
|
||
$(kubectl get events -A --sort-by='.lastTimestamp' | tail -20)
|
||
\`\`\`
|
||
|
||
#### 资源使用异常的 Pod
|
||
\`\`\`bash
|
||
# 检查 CPU/内存使用(需要 metrics-server)
|
||
kubectl top pods -A --sort-by=cpu 2>/dev/null | head -10 || echo "metrics-server 未安装"
|
||
\`\`\`
|
||
EOF
|
||
else
|
||
cat >> "$output_file" << EOF
|
||
- ❌ Kubernetes 未连接
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
### 资源使用
|
||
- **磁盘**: $(df -h / | awk 'NR==2 {print $5 " 已使用(" $4 " 可用)"}')
|
||
- **内存**: $(vm_stat | awk '/Pages free/ {free=$3} /Pages active/ {active=$3} END {printf "%.1f%% 空闲\n", (free/(free+active))*100}')
|
||
EOF
|
||
|
||
# 检查磁盘使用警告
|
||
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
|
||
if [ "$disk_usage" -gt 80 ]; then
|
||
cat >> "$output_file" << EOF
|
||
- ⚠️ **警告**: 磁盘使用率超过 80%,建议清理
|
||
EOF
|
||
fi
|
||
|
||
cat >> "$output_file" << EOF
|
||
|
||
## 常见问题诊断
|
||
|
||
### 1. ImagePullBackOff / ErrImagePull
|
||
\`\`\`bash
|
||
# 查看 Pod 详情
|
||
kubectl describe pod <pod-name> -n <namespace>
|
||
|
||
# 自动修复(推荐)
|
||
cd $BASE_DIR/k8s
|
||
./cache-image.sh --update-deployment <namespace>/<deployment>
|
||
|
||
# 手动缓存镜像
|
||
./cache-image.sh <image-name>
|
||
\`\`\`
|
||
|
||
### 2. CrashLoopBackOff
|
||
\`\`\`bash
|
||
# 查看日志
|
||
kubectl logs <pod-name> -n <namespace>
|
||
kubectl logs <pod-name> -n <namespace> --previous # 查看上一次的日志
|
||
|
||
# 查看事件
|
||
kubectl describe pod <pod-name> -n <namespace>
|
||
|
||
# 进入容器调试
|
||
kubectl exec -it <pod-name> -n <namespace> -- /bin/sh
|
||
\`\`\`
|
||
|
||
### 3. 服务无法访问
|
||
\`\`\`bash
|
||
# 检查 Service
|
||
kubectl get svc -n <namespace>
|
||
kubectl describe svc <service-name> -n <namespace>
|
||
|
||
# 检查 Endpoints
|
||
kubectl get endpoints <service-name> -n <namespace>
|
||
|
||
# 端口转发测试
|
||
kubectl port-forward svc/<service-name> 8080:80 -n <namespace>
|
||
\`\`\`
|
||
|
||
### 4. Pending 状态
|
||
\`\`\`bash
|
||
# 查看原因
|
||
kubectl describe pod <pod-name> -n <namespace>
|
||
|
||
# 检查节点资源
|
||
kubectl describe nodes
|
||
|
||
# 查看 PVC 状态
|
||
kubectl get pvc -A
|
||
\`\`\`
|
||
|
||
### 5. Docker 容器问题
|
||
\`\`\`bash
|
||
# 查看日志
|
||
docker logs -f <container-name>
|
||
docker logs --tail 100 <container-name>
|
||
|
||
# 进入容器
|
||
docker exec -it <container-name> /bin/bash
|
||
|
||
# 重启容器
|
||
docker restart <container-name>
|
||
|
||
# 查看资源使用
|
||
docker stats <container-name>
|
||
\`\`\`
|
||
|
||
## 日志位置
|
||
|
||
### 服务日志
|
||
- **Gitea**: \`docker logs gitea\`
|
||
- **Harbor**: \`docker logs harbor-core\`
|
||
- **系统日志**: ~/ops/logs/
|
||
|
||
### 查看日志命令
|
||
\`\`\`bash
|
||
# Docker 服务日志
|
||
docker logs -f <service-name> --tail 100
|
||
|
||
# K8s Pod 日志
|
||
kubectl logs -f <pod-name> -n <namespace>
|
||
|
||
# K8s 所有容器日志
|
||
kubectl logs <pod-name> -n <namespace> --all-containers=true
|
||
|
||
# 查看系统日志
|
||
tail -f ~/ops/logs/*.log
|
||
\`\`\`
|
||
|
||
## 性能诊断
|
||
|
||
### 检查资源瓶颈
|
||
\`\`\`bash
|
||
# Docker 资源使用
|
||
docker stats --no-stream
|
||
|
||
# K8s 资源使用
|
||
kubectl top nodes
|
||
kubectl top pods -A
|
||
|
||
# 磁盘 I/O
|
||
iostat -x 1 5
|
||
|
||
# 网络连接
|
||
netstat -an | grep ESTABLISHED | wc -l
|
||
\`\`\`
|
||
|
||
### 清理资源
|
||
\`\`\`bash
|
||
# 清理 Docker
|
||
docker system prune -a # 清理所有未使用的资源
|
||
docker volume prune # 清理未使用的卷
|
||
docker image prune -a # 清理未使用的镜像
|
||
|
||
# 清理 K8s
|
||
kubectl delete pods --field-selector=status.phase==Failed -A
|
||
kubectl delete pods --field-selector=status.phase==Succeeded -A
|
||
\`\`\`
|
||
|
||
## 快速检查清单
|
||
|
||
- [ ] Docker 守护进程运行正常: \`docker ps\`
|
||
- [ ] K8s 集群连接正常: \`kubectl cluster-info\`
|
||
- [ ] 所有关键服务运行: \`docker ps | grep -E "(harbor|gitea)"\`
|
||
- [ ] 磁盘空间充足: \`df -h /\`
|
||
- [ ] 没有异常 Pod: \`kubectl get pods -A --field-selector=status.phase!=Running\`
|
||
- [ ] 最近无严重事件: \`kubectl get events -A --sort-by='.lastTimestamp' | tail -20\`
|
||
EOF
|
||
|
||
log_success "故障排查场景上下文已生成 → $output_file"
|
||
}
|
||
|
||
#==============================================================================
|
||
# 主函数
|
||
#==============================================================================
|
||
|
||
main() {
|
||
local scenario="core"
|
||
local output_file=""
|
||
local format="markdown"
|
||
local secure_mode=false
|
||
local compress_mode=false
|
||
|
||
# 解析参数
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
-h|--help)
|
||
show_usage
|
||
exit 0
|
||
;;
|
||
-o|--output)
|
||
output_file="$2"
|
||
shift 2
|
||
;;
|
||
-f|--format)
|
||
format="$2"
|
||
shift 2
|
||
;;
|
||
-s|--secure)
|
||
secure_mode=true
|
||
shift
|
||
;;
|
||
-c|--compress)
|
||
compress_mode=true
|
||
shift
|
||
;;
|
||
core|dev|deploy|debug|full|auto)
|
||
scenario="$1"
|
||
shift
|
||
;;
|
||
*)
|
||
log_error "未知参数: $1"
|
||
show_usage
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# 智能推荐场景
|
||
if [ "$scenario" = "auto" ]; then
|
||
scenario=$(get_smart_scenario)
|
||
log_info "智能推荐场景: ${CYAN}$scenario${NC}"
|
||
fi
|
||
|
||
# 设置默认输出文件
|
||
if [ -z "$output_file" ]; then
|
||
output_file="$OUTPUT_DIR/ai-context-${scenario}.md"
|
||
fi
|
||
|
||
# 生成对应场景的上下文
|
||
case $scenario in
|
||
core)
|
||
generate_core_context "$output_file"
|
||
;;
|
||
dev)
|
||
generate_dev_context "$output_file"
|
||
;;
|
||
deploy)
|
||
generate_deploy_context "$output_file"
|
||
;;
|
||
debug)
|
||
generate_debug_context "$output_file"
|
||
;;
|
||
full)
|
||
log_info "生成完整上下文..."
|
||
bash "$BASE_DIR/scripts/generate-ai-context.sh" "$output_file"
|
||
;;
|
||
*)
|
||
log_error "未知场景: $scenario"
|
||
exit 1
|
||
;;
|
||
esac
|
||
|
||
# 安全过滤
|
||
if [ "$secure_mode" = true ]; then
|
||
log_info "应用安全过滤..."
|
||
local temp_file=$(mktemp)
|
||
filter_sensitive_info "$(cat "$output_file")" > "$temp_file"
|
||
mv "$temp_file" "$output_file"
|
||
log_success "已过滤敏感信息"
|
||
fi
|
||
|
||
# 显示文件信息
|
||
echo
|
||
log_success "上下文已生成"
|
||
echo -e "${CYAN}场景${NC}: $scenario"
|
||
echo -e "${CYAN}文件${NC}: $output_file"
|
||
echo -e "${CYAN}大小${NC}: $(du -h "$output_file" | awk '{print $1}')"
|
||
echo -e "${CYAN}行数${NC}: $(wc -l < "$output_file")"
|
||
|
||
# 使用建议
|
||
echo
|
||
echo -e "${YELLOW}💡 使用建议:${NC}"
|
||
echo -e " 在 Claude Code 中说: ${GREEN}请阅读 $output_file${NC}"
|
||
}
|
||
|
||
main "$@"
|