Nautilus 中的新功能:崩溃转储遥测

sage

当 Ceph 守护进程遇到软件错误、意外状态、断言失败或其他异常情况时,它们会将堆栈跟踪和最近的内部日志活动转储到 /var/log/ceph 中的日志文件中。在现代系统中,systemd 将重新启动守护进程,生活将继续——通常集群管理员甚至没有意识到发生了问题。这在一定程度上是好事(Ceph 对故障具有鲁棒性!),也是坏事(问题经常被忽视)。

Nautilus 通过添加一个崩溃转储概念来改进这种情况,该概念总结了有关故障的所有相关信息,集中跟踪故障,以便管理员可以轻松查看集群中发生的所有崩溃,并将崩溃转储与遥测功能结合起来,以便(如果管理员选择加入)故障可以自动报告给 Ceph 开发人员。

崩溃转储

软件故障仍然会导致堆栈跟踪和其他信息附加到守护进程的日志中。此外,在 /var/log/ceph/crash 中创建一个新的子目录,其中包含崩溃的唯一标识符,并在其中记录有关故障的相关信息。其中包括

  • 唯一的崩溃标识符
  • 守护进程名称和类型
  • Ceph 版本
  • 内核版本和 Linux 发行版
  • 完整的堆栈跟踪
  • 有关失败断言的元数据(文件名、函数名、行号、失败条件),如果适用
  • 有关 IO 错误的元数据(设备名称、失败的 IO 操作类型、已知时偏移量和长度),如果适用
  • 最近调试日志条目的转储

一个名为 ceph-crash 的辅助工具会定期在安装了 Ceph 守护进程的任何主机上运行(默认情况下,每 10 分钟),并将任何新的崩溃报告报告回集群。

可以使用新的 ceph crash lsceph crash info 命令查询报告的崩溃。例如,以下是我们测试 Nautilus 候选版本时遇到的一些崩溃

$ ceph crash ls ... 2019-03-15_21:19:19.614860Z_8d2a8acb-694d-4a5b-a8d1-c9f3ce2bd90a osd.144 2019-03-15_21:19:37.584082Z_253ece02-e4fe-4af4-ae1e-f273bf30fcee osd.144 2019-03-15_21:25:19.262250Z_16dbfbd1-6811-4754-95ca-983a2896981a osd.144 2019-03-15_21:26:44.778675Z_e4ac09ae-e080-46a0-80d9-8427aeebb90b osd.144 $ ceph crash info 2019-03-15_21:26:44.778675Z_e4ac09ae-e080-46a0-80d9-8427aeebb90b { "crash_id": "2019-03-15_21:26:44.778675Z_e4ac09ae-e080-46a0-80d9-8427aeebb90b", "timestamp": "2019-03-15 21:26:44.778675Z", "process_name": "ceph-osd", "entity_name": "osd.144", "ceph_version": "14.1.1-185-ga144a88", "utsname_hostname": "reesi006.front.sepia.ceph.com", "utsname_sysname": "Linux", "utsname_release": "4.4.0-112-generic", "utsname_version": "#135-Ubuntu SMP Fri Jan 19 11:48:36 UTC 2018", "utsname_machine": "x86_64", "os_name": "Ubuntu", "os_id": "ubuntu", "os_version_id": "16.04", "os_version": "16.04.4 LTS (Xenial Xerus)", "assert_condition": "info.history.same_interval_since != 0", "assert_func": "void PG::start_peering_interval(OSDMapRef, const std::vector&, int, const std::vector&, int, ObjectStore::Transaction*)", "assert_file": "/build/ceph-14.1.1-185-ga144a88/src/osd/PG.cc", "assert_line": 6222, "assert_thread_name": "tp_osd_tp", "assert_msg": "/build/ceph-14.1.1-185-ga144a88/src/osd/PG.cc: In function 'void PG::start_peering_interval(OSDMapRef, const std::vector&, int, const std::vector&, int, ObjectStore::Transaction*)' thread 7f9907e66700 time 2019-03-15 21:26:44.762873\n/build/ceph-14.1.1-185-ga144a88/src/osd/PG.cc: 6222: FAILED ceph_assert(info.history.same_interval_since != 0)\n", "backtrace": [ "(()+0x11390) [0x7f9928728390]", "(gsignal()+0x38) [0x7f9927c53428]", "(abort()+0x16a) [0x7f9927c5502a]", "(ceph::__ceph_assert_fail(char const*, char const*, int, char const*)+0x1a3) [0x84fced]", "(ceph::__ceph_assertf_fail(char const*, char const*, int, char const*, char const*, ...)+0) [0x84fe77]", "(PG::start_peering_interval(std::shared_ptr, std::vector<int, std::allocator > const&, int, std::vector<int, std::allocator > const&, int, ObjectStore::Transaction*)+0x1607) [0xa48997]", "(PG::RecoveryState::Reset::react(PG::AdvMap const&)+0x1bb) [0xa4c2cb]", "(boost::statechart::simple_state<PG::RecoveryState::Reset, PG::RecoveryState::RecoveryMachine, boost::mpl::list<mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, (boost::statechart::history_mode)0>::react_impl(boost::statechart::event_base const&, void const*)+0x140) [0xaaf150]", "(boost::statechart::state_machine<PG::RecoveryState::RecoveryMachine, PG::RecoveryState::Initial, std::allocator, boost::statechart::null_exception_translator>::process_queued_events()+0xb3) [0xa81a13]", "(PG::handle_advance_map(std::shared_ptr, std::shared_ptr, std::vector<int, std::allocator >&, int, std::vector<int, std::allocator >&, int, PG::RecoveryCtx*)+0x27b) [0xa4b49b]", "(OSD::advance_pg(unsigned int, PG*, ThreadPool::TPHandle&, PG::RecoveryCtx*)+0x2d1) [0x9aa6f1]", "(OSD::dequeue_peering_evt(OSDShard*, PG*, std::shared_ptr, ThreadPool::TPHandle&)+0xa6) [0x9ac046]", "(PGPeeringItem::run(OSD*, OSDShard*, boost::intrusive_ptr&, ThreadPool::TPHandle&)+0x50) [0xc2e420]", "(OSD::ShardedOpWQ::_process(unsigned int, ceph::heartbeat_handle_d*)+0xbed) [0x9a028d]", "(ShardedThreadPool::shardedthreadpool_worker(unsigned int)+0x4ac) [0xfc0dfc]", "(ShardedThreadPool::WorkThreadSharded::entry()+0x10) [0xfc3fb0]", "(()+0x76ba) [0x7f992871e6ba]", "(clone()+0x6d) [0x7f9927d2541d]" ] }

生成崩溃转储的故障包括

  • 失败的开发人员断言,表明代码遇到意外或异常情况,如上例所示
  • 段错误,通常表明软件错误,或者偶尔由有故障的硬件引起的内存损坏
  • 无法由软件透明地掩盖的读取或写入存储设备时发生的未处理 IO 错误

遥测

在 Mimic 版本中引入了选择加入向 Ceph 开发人员共享 Ceph 集群的高级、匿名遥测信息的功能。在 Nautilus 中,我们对该功能进行了多项改进,并将遥测扩展到包括集群中的崩溃报告。此功能允许开发人员在崩溃发生时获得及时且自动的反馈,以及重要的信息,例如堆栈跟踪、构建版本和操作系统详细信息。

崩溃转储会完整报告(如上例所示),但 utsname_hostname 字段除外,该字段会被删除以保护隐私 截至 14.2.1(并且正在从服务器侧删除传入的报告)。

我们强烈建议 Ceph 用户启用此功能,因为此信息对开发人员社区非常有价值。它将帮助我们尽早发现问题,而无需依赖用户提交错误报告,并提供有关问题发生频率的信息,以便更好地确定错误的优先级。

要查看遥测模块共享的信息(无需实际启用该功能),

$ ceph mgr module telemetry $ ceph mgr telemetry show

如果您对没有共享敏感信息感到满意,可以使用以下命令启用自动遥测报告:

$ ceph telemetry on

您可以选择在报告中包含其他信息,例如集群描述和联系信息

$ ceph config set mgr mgr/telemetry/contact 'Sage Weil sage@newdream.net' $ ceph config set mgr mgr/telemetry/description 'My test cluster' $ ceph config set mgr mgr/telemetry/organization 'ceph.io'

可以使用以下命令查看遥测模块的当前状态,包括是否已启用以及报告提交的频率:

$ ceph telemetry status { "url": "https://telemetry.ceph.com/report", "enabled": true, "leaderboard": false, "description": "My test cluster", "contact": "Sage Weil sage@newdream.net", "organization": "ceph.io", "proxy": null, "interval": 72 }

后续步骤

目前,遥测和崩溃报告正在转储到 ElasticSearch 数据库中。我们正在设置一些基本的报告和查询基础设施,以便具有访问权限的 Ceph 开发人员可以浏览和查询报告。我们希望很快能够识别多个崩溃报告中的常见故障,并将它们链接到 跟踪器中的错误,并轻松查看相关信息,例如不同 Ceph 版本中的崩溃频率。