当前位置: 首页 > news >正文

Linux下Docker Compose里运行Jenkins数据故障诊断Shell脚本

#!/bin/bash# ============================================================# 脚本名称: jenkins_diagnose.sh# 描述: 基于哲学元认知优化的 Jenkins (Docker Compose) 故障诊断脚本# 融合整体论、奥卡姆剃刀、实用主义、辩证法、道家无为与本体论# 用法: bash jenkins_diagnose.sh [compose项目目录]# 若不提供目录,默认使用当前目录# ============================================================set-uopipefail# ------------------------------# 颜色定义 (让输出更易阅读)# ------------------------------RED='\033[0;31m'GREEN='\033[0;32m'YELLOW='\033[1;33m'BLUE='\033[0;34m'NC='\033[0m'# No Color# ------------------------------# 配置区 (可根据实际环境修改)# ------------------------------COMPOSE_DIR="${1:-.}"# Docker Compose 项目目录JENKINS_SERVICE_NAME="${2:-jenkins}"# compose 中的服务名JENKINS_HOME_HOST="${3:-/data/jenkins}"# Jenkins 数据卷在宿主机上的挂载路径# ------------------------------# 辅助函数# ------------------------------info(){echo-e"${GREEN}[INFO]${NC}$*";}warn(){echo-e"${YELLOW}[WARN]${NC}$*";}error(){echo-e"${RED}[ERROR]${NC}$*";}header(){echo-e"\n${BLUE}============================================================${NC}";echo-e"${BLUE}$*${NC}";echo-e"${BLUE}============================================================${NC}";}# 检查命令是否存在check_command(){command-v"$1">/dev/null2>&1||{error"命令$1未找到,请先安装。";return1;}}# ------------------------------# 预检:确保必要的命令可用# ------------------------------preflight(){header"0. 预检依赖命令"localmissing=0forcmdindockerfreedfdmesggrepawktailheadjournalctl xmllintstat;doif!check_command"$cmd";thenmissing=1fidoneif[$missing-eq1];thenerror"缺少必要命令,脚本退出。"exit1fiinfo"所有依赖命令检查通过。"}# ============================================================# 第一步:整体感知(整体论)# 目的:在点状排查前,先获取系统的全貌,识别涌现行为。# ============================================================step1_holistic_overview(){header"第一步:整体感知(整体论原则)"# 1.1 系统负载与运行时间echo">>> 1.1 系统负载与 uptime"uptime# 手工验证:在服务器上直接执行 `uptime`,观察负载是否超过 CPU 核心数。# 1.2 内存概况echo-e"\n>>> 1.2 内存使用概况"free-h# 手工验证:执行 `free -h`,关注 available 列是否接近 0,swap 是否大量使用。# 1.3 磁盘使用概况echo-e"\n>>> 1.3 磁盘使用概况"df-h|grep-E'^Filesystem|/$|/data'# 手工验证:执行 `df -h`,检查根分区及 Jenkins 数据卷所在分区的使用率是否达到 100%。# 1.4 关键系统日志中的严重错误(最近10分钟)echo-e"\n>>> 1.4 最近10分钟的系统严重错误"journalctl--since"10 min ago"-perr --no-pager2>/dev/null|tail-20||dmesg|tail-30# 手工验证:执行 `journalctl -xe` 或 `dmesg` 查看是否有 I/O 错误、文件系统只读等。# 1.5 Docker 守护进程状态echo-e"\n>>> 1.5 Docker 服务状态"systemctl is-activedocker2>/dev/null||servicedockerstatus2>/dev/null# 手工验证:`systemctl status docker`,确保 daemon 正常运行。}# ============================================================# 第二步:自愈状态速查(道家无为)# 目的:检查系统是否已自行恢复,避免不必要的人工介入。# ============================================================step2_self_healing_check(){header"第二步:自愈状态速查(道家无为原则)"cd"$COMPOSE_DIR"||{error"无法进入$COMPOSE_DIR";exit1;}echo">>> 2.1 容器列表与状态"dockercomposeps# 手工验证:在 compose 目录下执行 `docker compose ps`,查看 STATUS 列。# 提取 Jenkins 容器状态localstatusstatus=$(dockercomposeps-q"$JENKINS_SERVICE_NAME"|xargsdockerinspect-f'{{.State.Status}}'2>/dev/null||echo"unknown")echo-e"\n当前 Jenkins 容器状态:$status"# 根据状态判断自愈情况if["$status"="running"];theninfo"容器正在运行。检查健康检查日志是否显示近期自愈..."dockerinspect"$JENKINS_SERVICE_NAME"|grep-A5"Health"||true# 手工验证:`docker inspect <容器名> | jq .[0].State.Health` 查看健康检查历史。echo"如果服务已恢复且健康检查通过,则无需紧急干预,事后复盘即可。"elif["$status"="restarting"];thenwarn"容器正处于重启循环中,自愈未成功,需深入排查。"elif["$status"="exited"];thenwarn"容器已退出,自愈机制可能失效(或未配置 restart: always),需立即介入。"elsewarn"容器状态未知或已移除。"fi}# ============================================================# 第三步:奥卡姆剃刀决策分支# 目的:根据最直接的信号直击最常见根因,避免过度诊断。# ============================================================step3_occam_razor(){header"第三步:奥卡姆剃刀分支排查"cd"$COMPOSE_DIR"||exit1# 3.1 获取退出码localexit_codeexit_code=$(dockercomposeps-q"$JENKINS_SERVICE_NAME"|xargsdockerinspect-f'{{.State.ExitCode}}'2>/dev/null||echo"")echo">>> 3.1 退出码分析"if[-n"$exit_code"];thenecho"容器退出码:$exit_code"case"$exit_code"in137)error"退出码 137 表示进程被 SIGKILL 杀死,几乎肯定是 OOM (内存不足)。"echo"--- 立即检查 OOM 记录 ---"dmesg|grep-i"oom"|tail-20journalctl-k|grep-ioom|tail-20# 手工验证:执行 `dmesg | grep oom` 或 `grep -i oom /var/log/syslog`。echo"紧急恢复建议:"echo" 1. 临时提高 Docker 内存限制:修改 docker-compose.yml 中的 mem_limit 或 deploy.resources.limits.memory"echo" 2. 调整 JVM 堆大小:在 environment 中添加 JAVA_OPTS=-Xmx1g -Xms512m"echo" 3. 立即重启: docker compose up -d"return;;1)warn"退出码 1 通常为应用自身错误,查看容器日志可获得详细信息。";;0)warn"退出码 0 为正常退出,可能是入口脚本结束。检查启动命令或 entrypoint 是否正确。";;*)warn"未知退出码。";;esacfi# 3.2 快速检查磁盘空间 (奥卡姆剃刀第二大杀手)echo-e"\n>>> 3.2 磁盘空间快检"localuse_percentuse_percent=$(df-h"$JENKINS_HOME_HOST"|awk'NR==2 {print $5}'|tr-d'%')echo"Jenkins 数据卷所在分区使用率:${use_percent}%"if["$use_percent"-ge95];thenerror"磁盘空间即将耗尽,这是容器异常的常见原因。"echo"紧急清理建议:"echo" 1. 删除旧构建: find$JENKINS_HOME_HOST/jobs -type f -name '*.log' -mtime +30 -delete"echo" 2. 清理工作空间: rm -rf$JENKINS_HOME_HOST/workspace/*"echo" 3. 清理 Docker 系统缓存: docker system prune -f"# 手工验证:执行 `du -sh $JENKINS_HOME/*` 定位空间占用大户。returnfi# 3.3 若非以上两种,打印最近容器日志,交由下一步深入分析echo-e"\n>>> 3.3 未命中常见模式,打印容器最近日志"dockercompose logs--tail=50"$JENKINS_SERVICE_NAME"2>/dev/null||\dockerlogs--tail=50"$JENKINS_SERVICE_NAME"2>/dev/null# 手工验证:直接在目录下执行 `docker compose logs --tail=100 jenkins` 查看详细日志。}# ============================================================# 第四步:本体实体化排查(本体论)# 目的:按 Jenkins 核心实体(配置、作业、凭证、插件)分而治之。# ============================================================step4_ontology_check(){header"第四步:本体实体化排查(本体论原则)"[-d"$JENKINS_HOME_HOST"]||{error"Jenkins 数据卷目录$JENKINS_HOME_HOST不存在!";return;}cd"$JENKINS_HOME_HOST"||return# 4.1 实体:全局配置 config.xmlecho">>> 4.1 核心实体:全局配置文件 config.xml"if[-f"config.xml"];thenxmllint--nooutconfig.xml2>/dev/null&&info"config.xml 语法有效"||error"config.xml 存在 XML 语法错误!"# 手工验证:`xmllint --noout $JENKINS_HOME_HOST/config.xml` 检查完整性。若损坏可尝试从备份恢复。elseerror"config.xml 丢失!Jenkins 将无法启动。"fi# 4.2 实体:凭证echo-e"\n>>> 4.2 安全实体:凭证文件 credentials.xml"if[-f"credentials.xml"];thenxmllint--nooutcredentials.xml2>/dev/null&&info"credentials.xml 有效"||error"credentials.xml 损坏"elsewarn"credentials.xml 不存在,可能是全新安装或未使用基于文件的凭证。"fi# 4.3 实体:作业定义echo-e"\n>>> 4.3 作业实体:检查 jobs 目录"if[-d"jobs"];thenlocaljob_count=0job_count=$(findjobs-maxdepth2-name"config.xml"|wc-l)echo"发现$job_count个作业定义文件。"# 随机抽查几个作业的 config.xmlforjob_xmlin$(findjobs-maxdepth2-name"config.xml"|head-5);doxmllint--noout"$job_xml"2>/dev/null||error"作业$job_xml存在 XML 错误。"done# 手工验证:`xmllint --noout jobs/*/config.xml` 批量检查。若某个作业损坏,可暂时移走其目录让 Jenkins 启动。elsewarn"jobs 目录不存在,所有流水线将不可见。"fi# 4.4 实体:插件echo-e"\n>>> 4.4 插件实体:plugins 目录"if[-d"plugins"];thenlocalplugin_countplugin_count=$(lsplugins/*.jpi2>/dev/null|wc-l)echo"已安装插件数量:$plugin_count"# 检查是否存在 .pinned 或 .disabled 文件(可能影响加载)iflsplugins/*.pinned plugins/*.disabled2>/dev/null|grep-q.;thenwarn"发现被固定或禁用的插件,可能与版本冲突有关。"fi# 手工验证:查看 `docker compose logs jenkins | grep -i "plugin"` 中的错误。fi# 4.5 权限本体:用户与文件属主echo-e"\n>>> 4.5 数据卷权限"localownerowner=$(stat-c'%u:%g'"$JENKINS_HOME_HOST"2>/dev/null)echo"数据卷$JENKINS_HOME_HOST属主为:$owner(期望 1000:1000)"if["$owner"!="1000:1000"];thenerror"权限不正确!Jenkins 容器用户 (uid 1000) 无法写入。"echo"修复命令: sudo chown -R 1000:1000$JENKINS_HOME_HOST"fi# 手工验证:`ls -la $JENKINS_HOME_HOST` 查看文件属主,确认是否为 1000。}# ============================================================# 第五步:编排与资源辩证调优# 目的:检查 Compose 配置中的资源限制与策略矛盾,做出最佳权衡。# ============================================================step5_compose_dialectic(){header"第五步:编排配置辩证分析"cd"$COMPOSE_DIR"||exit1localcompose_file="docker-compose.yml"if[!-f"$compose_file"];thenwarn"未找到 docker-compose.yml,跳过编排检查。"returnfiecho">>> 5.1 重启策略"grep-A2"restart:""$compose_file"||echo"未显式设置 restart,可能导致进程退出后容器不会自动恢复。"echo-e"\n>>> 5.2 资源限制"grep-E"mem_limit|mem_reservation|memory|deploy:""$compose_file"||echo"未设置内存限制,容器可能耗尽宿主机内存触发 OOM。"echo-e"\n>>> 5.3 卷挂载"grep-A1"volumes:""$compose_file"|grep-v"^--"||true# 手工验证:对比 compose 文件中的卷映射与宿主机实际路径,确保一致性。echo-e"\n>>> 5.4 JVM 参数"grep-E"JAVA_OPTS|JENKINS_OPTS""$compose_file"||echo"未设置 JVM 堆大小,Jenkins 会默认使用 1/4 物理内存,可能导致内存压力。"# 辩证法提示:在内存限制与堆大小之间找到平衡。若限制了容器内存但未调整堆,可能导致频繁 GC。echo-e"\n推荐操作:"echo" - 添加 restart: unless-stopped 实现自愈。"echo" - 设置合理内存限制,如 deploy.resources.limits.memory: 2g。"echo" - 同时配置 JAVA_OPTS: -Xmx1g -Xms512m 避免 JVM 超过容器限制。"}# ============================================================# 第六步:系统与内核兜底# 目的:排查更深层次的系统级故障。# ============================================================step6_system_kernel(){header"第六步:系统与内核深层排查"echo">>> 6.1 文件系统与 I/O 错误"dmesg|grep-i-E"error|fail|read-only"|tail-15# 手工验证:`mount | grep "ro,"` 检查是否有分区只读挂载。echo-e"\n>>> 6.2 SELinux/AppArmor 审计"ifcommand-vausearch&>/dev/null;thenausearch-mavc--startrecent2>/dev/null|grepjenkins|tail-10||truefiifcommand-vsestatus&>/dev/null;thensestatus|grep"SELinux status"fi# 手工验证:`ausearch -m avc | grep jenkins` 或查看 /var/log/audit/audit.log。echo-e"\n>>> 6.3 文件描述符限制"localcontainer_idcontainer_id=$(dockercomposeps-q"$JENKINS_SERVICE_NAME"2>/dev/null)if[-n"$container_id"];thenecho"当前容器内 PID 1 的限制:"dockerexec"$container_id"cat/proc/1/limits2>/dev/null|grep"open files"||truefiecho"宿主机限制: ulimit -n 当前值:$(ulimit-n)"# 手工验证:若容器无法启动,可临时以 `--ulimit nofile=65536` 启动测试。echo-e"\n>>> 6.4 系统时间与时钟同步"timedatectl status2>/dev/null|grep"System clock"||true# 时间不同步可能导致 SSL 证书、Kerberos 等认证失败。}# ============================================================# 总结与后续建议# ============================================================summary_and_recommendations(){header"故障排查总结"echo"以上各步已完成。请根据输出中的 [ERROR] 和 [WARN] 信息定位问题。"echo""echo"通用恢复流程(按需选择):"echo" 1. 紧急恢复: 修复明显错误后执行 'docker compose up -d'"echo" 2. 若配置错误: 修改 docker-compose.yml 后重建 'docker compose up -d --force-recreate'"echo" 3. 数据损坏: 从备份恢复关键 XML 文件,或暂时移除损坏作业目录"echo""echo"长期预防建议(哲学升华):"echo" - 整体论: 部署 Prometheus + Grafana + cAdvisor 全面监控。"echo" - 无为: 配置 healthcheck、restart 策略和资源限制实现自愈。"echo" - 奥卡姆剃刀: 清理未使用插件和旧构建,保持系统精简。"echo" - 本体论: 定期备份$JENKINS_HOME并验证 XML 完整性。"echo" - 实用主义: 建立故障手册,将本次诊断脚本加入 CI 自动巡检。"}# ============================================================# 主函数# ============================================================main(){echo"Jenkins 服务故障系统化排查脚本 (哲学增强版)"echo"开始时间:$(date)"echo"目标 Compose 目录:$COMPOSE_DIR"echo"Jenkins 数据卷:$JENKINS_HOME_HOST"echo""preflight step1_holistic_overview step2_self_healing_check step3_occam_razor step4_ontology_check step5_compose_dialectic step6_system_kernel summary_and_recommendations}main"$@"
http://www.cnnetsun.cn/news/3537540.html

相关文章:

  • Python大麦抢票自动化工具终极指南:5步轻松抢到心仪门票
  • WebDevsCom高级用法:如何创建个性化资源收藏和分类系统
  • aws-security-viz核心功能解析:从Graphviz到Web视图的完整方案
  • 多模态AI媒体创作:为智能代理赋能的专业媒体生成框架
  • Streamlit快速搭建Python数据看板实战指南
  • VDO.Ninja终极指南:如何免费搭建专业级远程视频制作系统
  • 基于Qt C++的系统资源监控工具开发实战:从原理到实现
  • Proteus仿真STM32按键检测:从环境搭建到代码调试完整指南
  • AI项目失败主因:90%死于问题定义不清
  • 空调遥控器电路设计中的模拟电子技术解析
  • 3步打造私有化AI编程环境:code-server深度集成实战指南
  • 用Sinh-Arcsinh分布建模Fantacalcio球员得分预测
  • Triangles社区贡献指南:如何参与开源项目开发 [特殊字符]
  • Python-基础-元组
  • DIAMOND技术报告解读:深入理解语音修复模型的创新与突破
  • vue-progressive-image自定义组件开发:扩展插件功能的高级技巧
  • 定制化不是越贵越好!用这4个反直觉指标重构评估体系:已帮37家企业节省平均41.6%定制预算
  • 2026 最新版 Codex 下载、安装及环境配置教程(超详细)
  • 深度解析rust-musl-cross工作原理:musl-libc与Rust工具链协同机制
  • 为什么你的定制AI总不达标?揭秘9大隐藏能力断层——基于172个真实交付项目的归因分析
  • 华北赛区走马观碑队伍成绩申诉书
  • 快速掌握GDScript编程:浏览器实战入门指南
  • 2026年耐高温PPS膜(聚苯硫醚薄膜)与PAEK膜(聚芳醚酮薄膜)厂家专业特性与应用优势全面解析(上海和盛新材料)
  • 终极指南:Visual C++运行时一键安装解决方案,彻底告别DLL缺失错误!
  • TMS320F280013x CAN驱动开发:从寄存器配置到实战代码
  • FLUX.1-dev FP8量化版:如何在8GB显卡上运行AI绘画模型
  • 如何在GTA5公开战局中安全畅玩:YimMenu终极防护指南
  • Ventoy终极指南:一劳永逸的多系统启动盘解决方案
  • 【2026年拼多多暑期实习/春招- 7月19日-研发岗-第一题- 多多的灰度发布】(题目+思路+JavaC++Python解析+在线测试)
  • Ubuntu软件安装指南:Snap与Tar.gz对比与实践