如何看待gitlab的携程宕机事件件

Gitlab 官方对整个数据删除事件的详细说明 - 新闻
Gitlab 官方对整个数据删除事件的详细说明
昨天,我们(Gitlab)网站的一个数据库发生了严重事故。我们()丢失了 6 小时的数据库数据(问题,合并请求,用户,评论,片段等)。Git / wiki 存储库和自托管安装不受影响。丢失生产数据是不可接受的。未来几天内,我们将会发布此次事故发生的原因及一系列措施的落实情况。更新 18:14 UTC: 重新在线截至撰写本文时,我们正在从 6 小时前的数据库备份中恢复数据。这意味着在
再次生效的时候,17:20 UTC和 23:25
UTC 之间数据库丢失的任何数据都将恢复。Git数据(存储库和维基)和 GitLab的自托管实例不受影响。以下是本次事件的简要摘要,详细内容请事件一:在
18:00 UTC ,我们检测到垃圾邮件发送者通过创建片段来攻击数据库,使其不稳定。然后,我们开始了解发生了什么问题进行故障排除,以及如何防范。在 21:00 UTC,问题被升级导致在数据库上的写入锁定,这导致网站出现了一些时间段的宕机。措施:根据IP地址阻止了垃圾邮件发送者删除了使用存储库作为某种形式的CDN 导致 47 000 个IP 使用同一个帐户登录(导致高DB负载)的用户已移除用户发送垃圾邮件(通过创建代码段)事件二:在
22:00 UTC, - 我们被分页,因为 DB 复制滞后太远,导致不能有效地阻止。发生这种情况是因为在辅助数据库没有及时处理写入。措施:尝试修复 db2,此时丢失数据约4 GBdb2.cluster 拒绝复制,/var/opt/gitlab/postgresql/data 擦拭以保证复制db2.cluster 拒绝连接到 db1,max_wal_senders太低。此设置是用来限制数量 WAL (= replication)的客户端团队成员1调整max_wal_senders 到 32上db1,重启 PostgreSQL 。 PostgreSQL 因同时打开信号量太多而拒绝重启。团队成员1调整 max_connections 8000 到 2000。PostgreSQL 重启成功(尽管8000已经使用了近一年)db2.cluster 可以链接,但仍然复制失败,只是挂在那里没有执行任何的操作。今晚 23:00 左右(当地时间),团队成员1明确提到他要签字,并未想到会突然出现复制问题。事件三:在日23:00 左右 —团队成员1认为, pg_basebackup 拒绝执行是因为 PostgreSQL 的数据目录存在(尽管是空的),于是决定删除该目录。经过一两秒钟,他注意到他运行在 db1.,而不是 db2.。在日23:27 时,团队成员1 -终止删除操作,但为时已晚。大约 300 GB 左右的数据只剩下约4.5 GB我们不得不把
下线,并在 Twitter 上公布信息。我们正在执行紧急数据库维护, 将脱机< 状态(@gitlabstatus)遇到的问题默认情况下,LVM 快照每 24 小时采取一次。为了数据库的工作负载平衡,团队成员 1 在停电前 6小时手动操作过。定期备份似乎也只能每24小时执行一次,虽然团队成员1目前仍未能找出它们的存储位置。团队成员2表示 ,这些似乎没有奏效,产生的文件大小只有几个字节。团队成员3:看起来 pg_dump 可能会失败,因为 PostgreSQL 的 9.2 二进制文件正在运行,而不是 9.6 的二进制文件。这是因为 omnibus 只使用 Pg 9.6 ,如果 data / PG_VERSION 设置为 9.6,但在 workers 上这个文件不存在。因此,它默认为 9.2,静默失败。因此没有做出 SQL 转储。Fog gem 可能已清理旧备份。为Azure 服务器启用 Azure 中的磁盘快照,而不是 DB 服务器。同步过程在 Webhooks 数据同步到暂存后删除。我们只能从过去24小时的定期备份中提取内容,否则将丢失复制过程是超级脆弱,容易出错,依赖少数随机 shell 脚本并记录我们的备份到 S3 显然也不运行:bucket 是空的因此,换句话说,部署的 5 个备份/复制技术中没有一个可靠地运行或设置。我们最终还原了6 小时的备份。pg_basebackup 将等待主机启动复制进程,据另一个生产工程师称,这可能需要 10 分钟。这可能导致进程被卡住。使用 “strace” 运行进程没有提供的有用信息。恢复我们正在使用临时数据库中的数据库备份来立即恢复。我们不小心删除了生产数据,可能必须从备份中还原。谷歌文档与现场笔记 https://t.co/EVRbHzYlk8< 状态(@gitlabstatus)日00:36 -备份 db1. 数据日00:55 -在 db1. 安装 db1. 从分段复制数据 /var/opt/gitlab/postgresql/data/ 到生成 /var/opt/gitlab/postgresql/data/ 日01:05 - nfs-share01 服务器 征用临时存储/var/opt/gitlab/db-meltdown日01:18 - 复制剩余的生成数据,包括pg_xlog,升级为-db-meltodwn-backup.tar.gz下面的图表显示删除的时间和后续的数据复制。此外,我们要感谢在Twitter 和其他渠道通过#hugops获得的惊人支持编译自:
(文/开源中国)热门推荐:
  一转眼,已经是鸡年的第一个工作日了,祝各位看官开年大吉。
  就在两天前,《Gitlab误删300GB数据,备份失效后直播抢救》、《Gitlab不小心删除了数据库导致网站下线》霸屏了科技新闻的头条。
  整个事件的回顾,Gitlab 第一时间放到了 Google Doc 上,并在 Twitter 上对事件的处置状态进行实时更新,后来索性在 Youtube上 开了频道直播恢复进程,目前网站已经恢复了正常,不幸的是,gitlab 还是丢掉了差不多6个小时的数据。
  对于事件的前因后果,Gitlab 在 Google Doc 上面已经进行了详细说明,简单来说:
  Gitlab 遭受了恶意邮件发送者的 DDoS 攻击,导致数据库写入锁定,网站出现不稳定和宕机,在阻止了恶意邮件发送者之后,运维人员开始修复数据库不同步的问题,在修复过程中,错误的在生产环境上执行了数据库目录删除命令,导致300GB数据被删除,Gitlab 被迫下线。在试图进行数据恢复时,发现只有 db1.staging 的数据库可以用于恢复,其它五种备份机制均无效。db1.staging 是6小时前的数据,而且传输速率有限,导致恢复进程缓慢。
  作为一个信息系统审计师和信息安全顾问,笔者曾经对数十家企业的信息系统运维工作进行过审计,类似的事件屡见不鲜,其中也不乏国际知名的IT巨头和国内顶尖的科技公司,只是传播范围、影响力、事件透明度都没有这个事件这么大。这次事件,其实是一个非常典型的信息安全风险爆发、信息安全控制措施失效的案例,笔者将从 IT 审计的角度,进行一些简单分析和分享。
  1IT审计的逻辑是什么
  IT 审计是一种针对信息系统的审计方式,不同于财务审计对财务报告真实性、有效性、准确性的验证,IT 审计关注于对信息系统本身的稳定性、准确性、安全性的检查以及围绕信息系统运维管理活动有效性的检查。直白一点来说,除了要检查信息系统本身能否正确、稳定的进行信息处理,IT 审计还关注是否针对信息系统运维风险的设计了有效的控制措施,并有效执行。
  在 IT 审计中,审计的出发点叫做 WCGW (What Could Go Wrong),说白了就是要识别出哪些场景可以导致信息系统的不稳定、不准确的情况发生。这是一个基于过程的分析方式,用 Gitlab 事件举个例子,其中的一个 WCGW 就可以是『错误的将对备库操作在生产库上执行』。在大量的IT风险事件基础上,IT审计服务机构识别出了很多的WCGW,并进行归类和分析,并据此设计出一套方法论和控制措施检查清单。IT审计服务机构根据这一方法论和检查清单对企业执行IT审计,以判断是否有能力应对潜在的IT风险。
  审计执行过程一般分为两个阶段:
制度、流程、控制措施的设计有效性检查阶段
制度、流程、控制措施的执行有效性检查阶段
  首先,控制设计的有效性主要是检查企业是否建立了制度、流程,以对风险进行控制。
  笔者在实际检查过程中,经常发现不完善的企业的IT规则严重依赖信息系统管理、维护人员的个人能力和意识,信息系统的维护活动、操作执行对企业管理者来说是完全的黑盒。而正规一些的IT组织,则会建立完整的规则,且不论这些规则是否执行有效,至少在纸面上可以做到『有法可依』。在审计的逻辑里面,有法可依是第一步,如果连基本的管理要求都不存在,也就谈不上执行的有效性了。
  其次,控制执行有效性检查,是基于『控制设计是有效的』这一结论。
  一般来说,如果设计有效性评价为无效,是不会进行执行有效性检查的,因为那意味着『无法可依』或者『法律无效』。在Gitlab这个事件中,有评论分析说,管理员之所以执行了误操作,是因为『迷失在了N多个终端窗口当中』。这样的场景很常见,很多企业都制定了生产环境操作的规则以防止类似的事情发生,可实际上由于这些控制措施未被执行,还是会导致生产事故的发生。笔者曾听闻了多起类似的由于多窗口不同环境同时操作导致的生产事故,这种情况被称为控制措施执行的失效。
  2IT审计的三大重点
  如前所述,各家IT审计服务机构都有一套控制检查清单,其中,最为基础的被称为『一般性IT控制措施』,这当中包括了三大审计重点。就笔者实际服务经验来看,这三大重点往往涵盖了绝大多数的生产故障发生的原因。
  重点一:变更管理
  在Gitlab事件中,最为令人惊讶的(其实也没那么惊讶)是运维人员在事件处置过程中,可以不经任何授权、评估、测试,直接在生产环境上进行实验性的操作,而且执行的是删除目录这样高危的操作。在ITIL所描述的变更发布管理优秀实践中,变更管理往往会经过多个控制环节,以确保变更的成功,这些环节包括了变更申请、授权、评估(业务影响、风险、可行性)、测试(单元、集成、用户验收)、审批、发布执行、回滚计划、上线验证等等。之所以变更流程的优秀实践如此之复杂,是因为生产环境的变更实际上是信息系统安全性最大的隐忧。
  在IT审计中,变更管理的有效性,也是关注的第一大重点。作为审计师,我们会关注变更流程中是否有有效的审批授权(以确认变更操作不是个人的、非授权的行为)、是否进行了合理而充分的测试(以确认变更在上线前是否得到质量验证)、是否遵循了不相容职责分离的原则(申请与审批、开发与测试、开发与上线部署等)。在Gitlab事件中,我们明显的看到管理员对生产环境执行的变更操作未能遵循上述基本要求。
  虽然Gitlab作为一家创业型的科技企业,实际上无需遵守什么样特定的运维流程,但一些通用风险控制的管理方式也是可以借鉴的,毕竟这些控制点和实践是从大量的教训当中积累出来的。从审计的角度来说,所有的形式、文档、记录都是为了『证明我们确实这么做了』,但从目的来说,更重要的是『即使我们不需要证明什么,我们也会遵循一些要求来提高我们系统的安全性和稳定性』。
  重点二:访问控制
  在IT审计中的第二个重点是访问控制,访问控制一般会关注两大问题:
账号合理性的问题
权限合理性的问题
  直白一点来讲,第一个问题关注哪些人能开哪些门,第二个问题关注这些人进到屋子里面之后能干些什么。
  Gitlab事件当中,我们注意到了很多有趣、有价值的建议,例如生产运维账号权限限制以及自动化运维,这些建议其实都可以看作是访问控制的一种延伸。在对生产运维账号权限进行限制时,运维人员将无法直接对一些敏感、高危的操作直接执行,而必须额外的获得更高的权限执行操作,这些特异性的操作方式由于有别于开发、测试环境,将有利于运维人员获得操作危险性提示,这当然是对『人肉运维』的一种改良性的尝试。而自动化运维,则是更加彻底可以降低这一风险的运维技术发展趋势。除了应急情况下备用的管理员账号,信息系统当中只存在自动化运维工具的账号,这些运维工具被配置特定的权限、执行特定的操作,这将大大的降低『人肉运维』可能带来的风险。
  『人肉运维』仍然是绝大多数企业采用的操作方式,很多运维人员甚至认为使用root权限进行生产环境线上操作处理问题是能力高超的表现。单独依靠运维人员的个人能力进行运维,风险不光有人员能力的天花板,企业还不得不面对可能的(有些地方甚至是必然的)运维人员流动带给信息系统的巨大风险。
  重点三:备份和恢复测试
  笔者在为很多企业进行IT审计服务时,最常提出的风险发现之一就是『未执行备份的恢复测试,无法验证备份数据的有效性』,这也被业内人士自嘲式的称为『最没有营养的IT审计发现之一』,因为这一发现并不会在实质上影响审计结论。然而,在Gitlab事件中,我们看到了令人惊诧的一幕,多重备份机制竟然只有一个可以用于数据恢复。
  随着技术的飞速发展,已经有了越来越多的技术手段,帮助企业提高信息系统的可用性和连续性。我们看到了集群式高可用架构,异地多活数据中心,提供数据高完整性保障的云服务。然而在这纷繁缭乱的新技术中,回归到信息系统连续性管理的本源,我们是否对数据做了有效的备份,并且能够在突发情况下可以实际的实现数据的恢复?我们各种备份机制下,是否设定了合理的RPO,以满足我们对数据恢复时可以容忍的数据损失?我们是否真正的执行过演练,以验证我们设定的RTO,真的能够完成我们的服务恢复?
  对于备份和恢复管理,Gitlab事件堪称绝佳的案例,集中的体现出了备份有效性、RPO和RTO未得到验证的问题。这也是为什么,越来越多的领军企业开始关注信息系统的连续性管理和应急响应,越来越多的企业开始真刀真枪的开展数据中心的切换演练、数据恢复测试演练、应急预案演练。而演练过程中,也确确实实可以发现大量的不可预期的问题,例如交通耗时、备用的设施设备可用性、各类系统的版本和兼容性问题、读写速度和运营商带宽限制问题、介质有效性问题等等,而这些问题在缺少演练的情况下,是很难暴露出来的。
  文末小结
  1)前车之鉴,未雨绸缪
  就像互联网金融行业里面一直在讨论的『投资者教育』的问题,在发生实质性违约事件之前,总是有很多人无法理解『责任自担』的含义。
  不论是Gitlab事件,还是当年的携程宕机事件,都应当作为自我审视和优化的一个契机。审视一下自己公司的规则是否完备,审视一下规则是否有效的落实,把每一个别人的事故当成自我检查的标准,把每一个预案场景都实实在在的进行一下演练。安全稳定的系统环境,需要我们以前车之鉴,做未雨绸缪。
  2)『有风险意识的工程师文化』
  笔者在IT风险领域从业多年,尽管在从业过程中一再的强调管理导向的重要性,却也是坚定的工程师文化的追随者。作为技术公司,我们应当更多的相信技术而不是管理。
  安全的运维需要规则,但规则的落实要尽可能的依赖技术的力量,而非纸面上的制度、流程、管理活动。而我也相信,重规则、轻流程的技术导向型IT风险管理,可以让企业走的更高更远。
  本文作者:马寅龙(点融黑帮),点融网信息安全合规专家,2年IT审计和6年信息安全风险咨询服务经验,擅长信息科技战略规划、信息安全体系建设、IT风险管理与治理,崇尚以务实的方式践行企业的信息安全风险管理。
  本文由@点融黑帮(ID:DianrongMafia)原创发布于搜狐科技,未经许可,禁止转载。
请先登录再操作
请先登录再操作
微信扫一扫分享至朋友圈
点融黑帮――一个充满激情和梦想的技术团队,吸引了来自金融及...
知名IT评论人,曾就职于多家知名IT企业,现是科幻星系创建人
未来在这里发声。
新媒体的实践者、研究者和批判者。
立足终端领域,静观科技变化。深入思考,简单陈述。
智能硬件领域第一自媒体。基于 Gitlab Web Hook 的自动 Eslint 语法检查 - 推酷
基于 Gitlab Web Hook 的自动 Eslint 语法检查
, 一个插件化的 Javascript 语法检查工具, 如何将其结合 Gitlab 并应用于开发呢?
Gitlab Web Hook
提供如下事件的 Hook:
Push events
Tag push events
Issues events
Merge Request events
当对应事件发生时, 将触发预设的 URL (即 Web Hook), 并向其发送一个包含该事件详细信息的 POST 请求, 正是通过该 POST 请求从而对各个事件进行处理的.
例如 Merge Requests events:
//Request body:
"object_kind":"merge_request",
"name":"Administrator",
"username":"root",
"avatar_url":"/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
"object_attributes": {
"target_branch":"master",
"source_branch":"ms-viewport",
"source_project_id":14,
"author_id":51,
"assignee_id":6,
"title":"MS-Viewport",
"created_at":"T17:23:34Z",
"updated_at":"T17:23:34Z",
"st_commits":null,
"st_diffs":null,
"milestone_id":null,
"state":"opened",
"merge_status":"unchecked",
"target_project_id":14,
"description":"",
"source":{
"name":"Awesome Project",
"description":"Aut reprehenderit ut est.",
"web_url":"/awesome_space/awesome_project",
"avatar_url":null,
"git_ssh_url":":awesome_space/awesome_project.git",
"git_http_url":"/awesome_space/awesome_project.git",
"namespace":"Awesome Space",
"visibility_level":20,
"path_with_namespace":"awesome_space/awesome_project",
"default_branch":"master",
"homepage":"/awesome_space/awesome_project",
"url":"/awesome_space/awesome_project.git",
"ssh_url":":awesome_space/awesome_project.git",
"http_url":"/awesome_space/awesome_project.git"
"target": {
"name":"Awesome Project",
"description":"Aut reprehenderit ut est.",
"web_url":"/awesome_space/awesome_project",
"avatar_url":null,
"git_ssh_url":":awesome_space/awesome_project.git",
"git_http_url":"/awesome_space/awesome_project.git",
"namespace":"Awesome Space",
"visibility_level":20,
"path_with_namespace":"awesome_space/awesome_project",
"default_branch":"master",
"homepage":"/awesome_space/awesome_project",
"url":"/awesome_space/awesome_project.git",
"ssh_url":":awesome_space/awesome_project.git",
"http_url":"/awesome_space/awesome_project.git"
"last_commit": {
"id":"daf094c3e6c9efb5d27d7",
"message":"fixed readme",
"timestamp":"T23:36:29+02:00",
"url":"/awesome_space/awesome_project/commits/daf094c3e6c9efb5d27d7",
"author": {
"name":"GitLab dev user",
"email":"gitlabdev@dv6700.(none)"
"work_in_progress":false,
"url":"/diaspora/merge_requests/1",
"action":"open",
"assignee": {
"name":"User1",
"username":"user1",
"avatar_url":"/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
从这个请求体中可知该 Merge Request 的创建者, 分支, 源分支信息, 目标分支信息, 最近一次 Commit, 分配给哪个用户, 对应的状态等信息.
作为插件化的 lint 方案, 逐渐打败了原有的 JSLint 和 JSHint, 并’吞并’了 JSCS, 其最大的优势就是标榜的可插件化, 并且有各种插件可以扩展, 使得开发人员能够灵活的配置规则, 如果这还不满足你的需求, 你还能方便的开发针对自己需求的插件, 此外它还支持 Es6, Jsx 语法, 前端程序员真是一群追求’时尚’的猿, 你不能阻止一个前端使用新工具 ……
编写自己的 config/plugin npm package
第一种是类似于
的方式, 通过编写配置文件 npm package, 具体详见
第二种以插件形式, 类似于
, 通过编写独立的 Eslint 插件;
本文采用第二种方式, 不仅方便配置现有的 rules, 也方便未来添加自己的 rules:
importReactEslintfrom'eslint-plugin-react';
importReactNativeEslintfrom'eslint-plugin-react-native';
constreactRules = ReactEslint.
constreactNativeRules = ReactNativeEslint.
constReactNativeWacai = {
'split-platform-components': reactNativeRules['split-platform-components'],
'no-inline-styles': reactNativeRules['no-inline-styles'],
'no-did-mount-set-state': reactRules['no-did-mount-set-state'],
'no-did-update-set-state': reactRules['no-did-update-set-state']
configs: {
recommended: {
parserOptions: {
ecmaFeatures: {
'react-native-wacai/split-platform-components':2,
'react-native-wacai/no-inline-styles':2,
'react-native-wacai/no-did-mount-set-state':2,
'react-native-wacai/no-did-update-set-state':2
exportdefaultMyEslinP
假设你的插件叫做: eslint-react-wacai, 那么通过安装该插件(前提是你 npm publish了这个插件):
npm installeslint-react-wacaibabel-eslinteslint --save-dev
并在项目根目录配置如下 .eslintrc 文件即可:
"parser":"babel-eslint",
"plugins": [
"react-wacai",
"extends": ["plugin:react-wacai/recommended"]
使用 Node 编写 Gitlab Web Hook 接口
现在插件有了, 还是聊聊怎么实现自动化 Eslint 检查吧, 由于目前采用 Issue 方式开发, 当猿们最终写完功能, 需要合并到 master 分支时, 必须提一个 Merge Request, 此时通过监听拦截 Merge Request 事件, 对应的 Web Hook 需要完成以下任务:
判断 Merge Request 事件的触发动作, 若为 open 或者 reopen, 则执行 Eslint 检查
通过 POST 请求体获取对应事件的 git 地址, 分支等信息, 将对应仓库拉到本地
执行 Eslint 检查
如果通过 Eslint 检查, 则什么都不做, 否则将 Eslint 检查结果作为评论回复在该 Merge Request 页面, 并关闭该 Merge Request(当然, 你也可以发邮件给对应的开发人员);
关键代码如下:
check(mr) {
returnnewPromise((resolve, reject) =& {
// TODO fs.chmodSync(shellFilePath, 755);
returnexecFile(shellFilePath, [mr.author, mr.project_path, mr.source_branch, mr.repo], { cwd: rootPath }, (err, stdout, stderr) =& {
// 此处不处理 err, 因为 eslint 不通过也算一种 err......
resolve(stdout);
.then(async(ret) =& {
constprojectService =newProjectService();
awaitprojectService.createMrNotes(mr,`\`\`\`\n${ret}\`\`\`\n`);
awaitprojectService.updateMr(mr,'close');
returnPromise.resolve(false);
returnPromise.resolve(true);
其中用到的 shell 脚本内容如下:
#!/bin/bash
if [ ! -d eslint ]; then
mkdir eslint
if [ ! -d $1 ]; then
if [ ! -d $2 ]; then
git clone -b $3 $4 & /dev/null
git checkout $3 & /dev/null
git pull & /dev/null
../../.././node_modules/eslint/bin/eslint.js .
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致因误删数据宕机,目前已经恢复访问
国内时间1月31日晚上11点左右
平台因为其运维人员误删了数据导致整个网站下线()。根据最新消息,其整个数据恢复过程在2日凌晨一两点左右已经恢复,目前网站可以正常访问。恢复期间 Gitlab 在 Youtube 上直播了整个数据恢复过程(小编想说:Gitlab 心真大,可能其是为了挽回一点在技术人员心中的印象吧)。根据官方对整个事情的描述大概可以推断 Gitlab 使用的是故障发生前6个小时的备份数据。因此就算恢复了整个平台,这6个小时时间内的数据还是丢失了,目前已经确定了数据丢失的这个问题。故障过程可阅读。
GitLab 的详细介绍:
GitLab 的下载地址:
转载请注明:文章转载自 开源中国社区
本文标题:</ 因误删数据宕机,目前已经恢复访问
本文地址:
官方自己说的

我要回帖

更多关于 携程宕机事件 的文章

 

随机推荐