Files
devops-ai-stack/TROUBLESHOOTING.md

15 KiB

DevOps AI Stack 故障排查指南

📋 目录

  1. 快速诊断
  2. 常见问题
  3. 服务特定问题
  4. 性能问题
  5. 安全和认证
  6. 高级调试

🔍 快速诊断

健康检查脚本

#!/bin/bash
# 快速诊断脚本

echo "=== 系统诊断 ==="
echo "Docker 状态:"
docker ps --format "table {{.Names}}\t{{.Status}}"

echo -e "\n=== 关键服务检查 ==="
echo "Traefik:"
curl -sk https://traefik.dev.lan/ping || echo "❌ 不可用"

echo "Gitea:"
curl -sk https://git.dev.lan/api/healthz || echo "❌ 不可用"

echo "Grafana:"
curl -sk https://grafana.dev.lan/api/health || echo "❌ 不可用"

echo -e "\n=== 资源使用 ==="
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

echo -e "\n=== 磁盘空间 ==="
df -h / | tail -1

echo -e "\n=== 最近日志错误 ==="
docker compose logs --tail=20 | grep -i "error" || echo "✅ 无错误"

快速救援命令

# 1. 停止所有服务 (安全重启)
bash infra/scripts/cleanup-dev.sh

# 2. 清理 Docker 资源
docker system prune -a -f

# 3. 重新启动
bash infra/scripts/init-dev.sh

# 4. 查看详细日志
tail -100 logs/init-dev-*.log

🆘 常见问题

问题 1: HTTPS 证书信任警告

症状:

  • 浏览器显示 "Your connection is not private"
  • 无法访问任何 .dev.lan 域名

根本原因:

  • mkcert 生成的自签名证书未安装到系统信任库
  • 或 mkcert 没有正确配置

诊断:

# 1. 检查证书文件是否存在
ls -la infra/traefik/certs/

# 2. 检查证书有效期
openssl x509 -in infra/traefik/certs/cert.pem -noout -dates

# 3. 验证 Traefik 是否加载了证书
docker compose -f infra/compose/core.yml logs traefik | grep -i "cert\|tls"

解决方案:

方案 A: 重新生成证书 (推荐)

# 1. 删除旧证书
rm -f infra/traefik/certs/*.pem

# 2. 重新生成
bash infra/scripts/mkcert-init.sh

# 3. 重启 Traefik
docker compose -f infra/compose/core.yml restart traefik

# 4. 等待 30 秒后重新访问
sleep 30
curl -sk https://traefik.dev.lan/ping

方案 B: 在 macOS 中手动信任证书

# 打开钥匙串应用,导入 cert.pem
# 或使用命令行:
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain \
  infra/traefik/certs/cert.pem

# 清除 Safari 缓存
rm -rf ~/Library/Safari/*

方案 C: 使用 curl 跳过证书验证 (仅用于测试)

# 所有 curl 命令添加 -k 或 --insecure
curl -k https://traefik.dev.lan/ping

问题 2: 港口冲突 (Port Already in Use)

症状:

Error response from daemon: driver failed programming external
connectivity on endpoint traefik:
Bind for 0.0.0.0:80 failed: port is already allocated

诊断:

# 1. 查找占用端口的进程
lsof -i :80
lsof -i :443
lsof -i :3000

# 2. 查看 Docker 网络配置
docker network ls
docker network inspect devops-ai

# 3. 检查 Compose 配置中的端口映射
grep -n "ports:" infra/compose/core.yml

解决方案:

方案 A: 停止占用服务

# 找到进程 ID (PID),然后停止
kill -9 <PID>

# 或如果是另一个 Docker 容器:
docker ps -a
docker stop <container_name>
docker rm <container_name>

方案 B: 改变端口映射

# 编辑 infra/compose/core.yml
# 将 0.0.0.0:80 改为 0.0.0.0:8080
# 将 0.0.0.0:443 改为 0.0.0.0:8443

# 然后在 /etc/hosts 中测试
curl -k https://127.0.0.1:8443/ping

方案 C: 重启 Docker Desktop

# 有时候 Docker 守护进程状态不一致
# 通过系统菜单: Docker Desktop > Restart
# 或命令行:
osascript -e 'tell application "Docker" to quit'
sleep 5
open -a Docker

问题 3: 服务无法启动或频繁重启

症状:

container restart policy set to always
container exited with code 1

诊断:

# 1. 查看容器日志
docker compose -f infra/compose/core.yml logs gitea -n 50

# 2. 检查容器健康状态
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.State}}"

# 3. 查看资源限制
docker stats --no-stream <container_name>

# 4. 检查依赖容器状态
docker network inspect core

解决方案:

方案 A: 查看详细错误日志

# 针对 Gitea
docker compose -f infra/compose/core.yml logs gitea | tail -100

# 针对 PostgreSQL
docker compose -f infra/compose/ai-visual.yml logs postgres

# 针对 LiteLLM
docker compose -f infra/compose/ai.yml logs litellm

方案 B: 清理并重新启动

# 1. 停止所有容器
docker compose -f infra/compose/core.yml down

# 2. 删除问题容器的数据卷 (谨慎!)
docker volume ls
docker volume rm gitea  # 如果 Gitea 有问题

# 3. 重新启动
docker compose -f infra/compose/core.yml up -d

# 4. 监控日志
docker compose -f infra/compose/core.yml logs -f

方案 C: 增加资源限制

# 编辑 infra/compose/core.yml 或其他 compose 文件
# 添加资源限制 (如果当前内存不足):

services:
  gitea:
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 2G
        reservations:
          cpus: '0.5'
          memory: 1G

问题 4: 磁盘空间不足

症状:

No space left on device
docker: Error response from daemon: write /var/lib/docker/...: no space left on device

诊断:

# 1. 检查磁盘使用
df -h /
du -sh ~/.*docker*

# 2. 检查 Docker 镜像和卷大小
docker system df

# 3. 查找大的镜像或卷
docker images --format "table {{.Repository}}\t{{.Size}}"
docker volume ls -q | xargs -I {} bash -c "echo {} && docker volume inspect {} | grep Mountpoint | cut -d'\"' -f4 | xargs du -sh"

# 4. 查看镜像层详情
docker image history <image_name>

解决方案:

方案 A: 清理 Docker 资源 (推荐)

# 1. 删除未使用的容器
docker container prune -f

# 2. 删除未使用的镜像
docker image prune -a -f

# 3. 删除未使用的卷 (谨慎! 会删除数据)
docker volume prune -f

# 4. 清理全部
docker system prune -a -f --volumes

# 检查回收空间
docker system df

方案 B: 扩展磁盘空间

# 如果使用 Docker Desktop for Mac:
# 1. 打开 Docker > Preferences > Resources
# 2. 增加 "Disk image size"
# 3. Apply & Restart

# 命令行检查:
docker system info | grep -i "Storage Driver\|Runtimes"

方案 C: 定期备份后删除旧数据

# 1. 创建备份
bash infra/scripts/backup-manager.sh backup

# 2. 删除 30 天前的备份
bash infra/scripts/backup-manager.sh --cleanup 30

# 3. 清理 Docker 日志
# 在 /etc/docker/daemon.json 添加:
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

🛠️ 服务特定问题

Gitea 问题

Gitea 无法连接到数据库

错误信息:

Error: database connect failed

解决方案:

# 1. 检查 SQLite 文件权限
ls -la data/gitea/gitea.db

# 2. 修复权限
sudo chown 1000:1000 data/gitea/
sudo chmod 700 data/gitea/

# 3. 删除损坏的数据库
rm data/gitea/gitea.db

# 4. 重启 Gitea
docker compose -f infra/compose/core.yml restart gitea

# 5. 等待初始化完成
sleep 30
curl -sk https://git.dev.lan/

无法推送到 Gitea (SSH 问题)

错误信息:

Permission denied (publickey)

解决方案:

# 1. 检查 SSH 密钥配置
ssh-keygen -t ed25519 -f ~/.ssh/gitea -C "gitea@dev.lan"

# 2. 添加公钥到 Gitea (Web UI)
# Settings > SSH / GPG Keys > Add Key

# 3. 配置 SSH config
cat >> ~/.ssh/config << EOF
Host git.dev.lan
  HostName git.dev.lan
  Port 222
  User git
  IdentityFile ~/.ssh/gitea
  StrictHostKeyChecking no
EOF

# 4. 测试连接
ssh -v git@git.dev.lan

# 5. 测试 Git 操作
git clone ssh://git@git.dev.lan:222/username/repo.git

Prometheus 和 Grafana 问题

Prometheus 无法采集指标

错误:

context deadline exceeded
job not scraping

诊断:

# 1. 检查 Prometheus 配置
docker compose -f infra/compose/observability.yml logs prometheus | grep -i "error\|scrape"

# 2. 访问 Prometheus 目标页面
# https://prometheus:9090/targets

# 3. 检查网络连接
docker exec prometheus \
  wget --spider http://gitea:3000/api/healthz

解决方案:

# 1. 验证目标服务在线
docker ps | grep -E "gitea|traefik|grafana"

# 2. 检查 Prometheus 配置文件语法
docker compose -f infra/compose/observability.yml \
  run --rm prometheus \
  promtool check config /etc/prometheus/prometheus.yml

# 3. 重启 Prometheus
docker compose -f infra/compose/observability.yml restart prometheus

# 4. 查看指标
curl http://localhost:9090/api/v1/query?query=up

LiteLLM 问题

LiteLLM 无法访问外部 API

错误:

OpenAI API key invalid
API rate limit exceeded

诊断:

# 1. 检查 API 密钥配置
docker compose -f infra/compose/ai.yml logs litellm | grep -i "key\|api"

# 2. 测试 API 连接
curl -X POST https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

# 3. 查看 LiteLLM 配置
cat infra/compose/ai/litellm-config.yaml

解决方案:

# 1. 更新 API 密钥
# 编辑 secrets/.env.ai
OPENAI_API_KEY=sk-your_new_key

# 2. 重启 LiteLLM
docker compose -f infra/compose/ai.yml restart litellm

# 3. 验证配置
curl -sk https://ai.dev.lan/v1/models \
  -H "Authorization: Bearer dev_local_key"

Ollama 模型无法加载

错误:

model not found
out of memory

诊断:

# 1. 检查 Ollama 服务状态
docker compose -f infra/compose/ai.yml logs ollama

# 2. 列出已加载的模型
curl http://localhost:11434/api/tags

# 3. 检查磁盘空间
docker exec ollama df -h

# 4. 查看内存使用
docker stats ollama --no-stream

解决方案:

# 1. 拉取模型
docker exec ollama ollama pull llama2

# 2. 如果内存不足,删除其他模型
docker exec ollama ollama rm mistral

# 3. 或增加 Ollama 容器的内存限制
# 编辑 infra/compose/ai.yml
services:
  ollama:
    deploy:
      resources:
        limits:
          memory: 8G

# 4. 重启
docker compose -f infra/compose/ai.yml restart ollama

📈 性能问题

响应时间缓慢

诊断:

# 1. 测试响应时间
time curl -sk https://git.dev.lan/

# 2. 查看各服务的响应时间
for service in traefik.dev.lan git.dev.lan grafana.dev.lan; do
  echo "测试 $service..."
  time curl -sk https://$service/ > /dev/null
done

# 3. 检查 Traefik 性能
curl http://localhost:8080/metrics | grep traefik_request_duration

# 4. 查看 CPU 和内存使用
docker stats --no-stream

优化方案:

# 1. 优化 Traefik 配置
# 增加缓存时间:
# infra/traefik/traefik.yml
[api]
  dashboard = true
  debug = false  # 禁用调试模式

[entryPoints.http]
  [entryPoints.http.forwardedHeaders]
    trusted = ["*"]
  address = ":80"

# 2. 增加容器资源限制
# infra/compose/core.yml
services:
  traefik:
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 1G

# 3. 启用 Traefik 缓存
# 在路由配置中添加缓存头

# 4. 查看慢查询
# Gitea: 查看数据库日志
docker compose -f infra/compose/core.yml logs gitea | grep -i "slow"

内存泄漏

诊断:

# 1. 长期监控内存使用
watch -n 5 'docker stats --no-stream'

# 2. 查找占用内存最多的容器
docker stats --no-stream --format \
  "table {{.Container}}\t{{.MemUsage}}\t{{.MemPerc}}" | \
  sort -k3 -rh

# 3. 检查容器内部内存使用
docker exec <container> ps aux --sort=-%mem | head -10

解决方案:

# 1. 重启泄漏的容器
docker compose -f infra/compose/<service>.yml restart <container>

# 2. 检查日志中的内存分配
docker compose -f infra/compose/<service>.yml logs <container> | grep -i "alloc\|memory\|heap"

# 3. 增加容器内存限制 (暂时措施)
# infra/compose/<service>.yml
services:
  <container>:
    deploy:
      resources:
        limits:
          memory: 4G

# 4. 升级应用版本 (永久解决)
# 更新 infra/compose/<service>.yml 中的镜像版本

🔐 安全和认证

Gitea 登录失败

错误:

Invalid username or password

解决方案:

# 1. 重置管理员密码
# 进入 Gitea 容器
docker exec -it gitea bash

# 在容器内运行:
gitea admin user change-password -u admin -p newpassword

# 2. 或使用 Web UI 重置
# https://git.dev.lan/user/forgot_password

# 3. 清除会话缓存
rm -rf data/gitea/sessions/
docker compose -f infra/compose/core.yml restart gitea

API 认证问题

LiteLLM API 密钥无效

错误:

Invalid API key
Unauthorized: 401

诊断:

# 1. 检查 API 密钥配置
echo $LITELLM_MASTER_KEY

# 2. 测试 API
curl -X POST https://ai.dev.lan/v1/chat/completions \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "hi"}]}'

# 3. 查看 LiteLLM 日志
docker compose -f infra/compose/ai.yml logs litellm | grep -i "auth\|key"

解决方案:

# 1. 更新 API 密钥
# 编辑 secrets/.env.ai
LITELLM_MASTER_KEY=new_secure_key_$(openssl rand -base64 24)

# 2. 重启 LiteLLM
docker compose -f infra/compose/ai.yml restart litellm

# 3. 再次测试
curl -X POST https://ai.dev.lan/v1/chat/completions \
  -H "Authorization: Bearer new_secure_key" \
  -H "Content-Type: application/json" \
  -d '{"model": "llama2", "messages": [{"role": "user", "content": "hi"}]}'

🐛 高级调试

启用详细日志

# 1. 修改 Docker Compose 中的日志级别
# infra/compose/<service>.yml

services:
  <service>:
    environment:
      - LOG_LEVEL=DEBUG
      - VERBOSE=true

# 2. 重启服务
docker compose -f infra/compose/<service>.yml restart <service>

# 3. 收集日志
docker compose -f infra/compose/<service>.yml logs -f <service>

# 4. 收集到文件
docker compose -f infra/compose/<service>.yml logs <service> > debug.log 2>&1

网络诊断

# 1. 进入容器进行网络测试
docker exec -it <container> bash

# 2. 在容器内测试连接
# 安装 curl (如果需要)
apt-get update && apt-get install -y curl

# 3. 测试其他容器连接
curl http://gitea:3000/
curl http://prometheus:9090/
curl http://redis:6379

# 4. 查看 DNS 解析
nslookup gitea
ping gitea

数据库连接测试

# 1. PostgreSQL 连接
docker exec postgres psql -U langfuse -d langfuse -c "SELECT 1;"

# 2. Redis 连接
docker exec redis redis-cli ping

# 3. SQLite 查询 (Gitea)
docker exec gitea sqlite3 /data/gitea/gitea.db ".tables"

📞 获取进一步帮助

如果以上方案未能解决问题:

  1. 收集诊断信息

    # 生成诊断报告
    bash infra/scripts/init-dev.sh > diagnostics.log 2>&1
    docker system df >> diagnostics.log
    docker ps -a >> diagnostics.log
    docker stats --no-stream >> diagnostics.log
    
  2. 查看相关文档

    • IMPLEMENTATION_GUIDE.md - 详细配置说明
    • DEPLOYMENT_CHECKLIST.md - 部署验证清单
    • 各服务官方文档
  3. 社区支持


最后更新: 2024 年 11 月 版本: 1.0.0