昔我往矣

诡异的gitlab排错经历

2015年04月9日

杭州春天

春天到了!
这个gitlab排错经历实在太有趣了,值得记一下!

缘起
周末迁移和升级了公司的gitlab,换到更稳定的服务器上面,顺带更新到最新版本。
周四的时候,有人报告说git认证需要输入密码,登到服务器上一看,~git/.ssh/authorized_keys文件被清空了,幸好迁移的时候保存了旧的备份,从备份恢复,以为天下太平了,可是2分钟之后,整个文件又被清空了。在心里面默念一万次fxxk之后,开始调查原因,最后发现,用户每次在gitlab上删除key,整个authorized_keys文件就会被清空,于是,从配置文件开始检查。

过程
首先确认了配置文件gitlabs/gitlab-shell/config.yml中没有问题。
然后google,是否是bug,或者有没有人遇到相同的问题,一无所获。
查找相关的代码,lib/gitlab_keys.rb文件也没有任何问题,ruby代码看起来真费劲.
然后测试了gitlab-shell的gitlab-keys命令行功能,无论是add-key,rm-key,clear参数用起来都没问题,而且,我们的现象是authorized_keys文件整个一行不剩,而如果是gitlab-keys的clear功能,会向authorized_keys文件中输入一行# Managed by gitlab-shell。一个上午的时间,想到的可能都查了,陷入僵局。

最后只得临时通知大家千万不要在gitlab上删除自己的key。然后,寻找一个会ruby的大神

解决
找到ruby大神之后,先给大神演示演示一遍现象,首先把authorized_keys文件备份到/tmp目录下,然后到gitlab上去删除自己的key,回来整个authorized_keys就被清空了,然后赶紧把/tmp下的备份恢复回来,就在这时,神奇的事情发生了。

$ cat /tmp/authorized_keys > ~git/.ssh/authorized_keys
No space left on device

失败了,提示原因是磁盘满了,df看,home分区的20G空间已经用掉了19G,某个19G的nohup.out文件就躺在另一个用户的家目录里面,于是干掉它:

# > ~somebody/nohup.out

然后成功恢复了authorized_keys,灵光一现,是不是由于home分区满了导致的authorized_keys被清空?于是,首先恢复authorized_keys,然后重新来一边删除操作,一切正常,删除一个key,authorized_keys就删除了这个测试的key,其余的100多个key还在authorized_keys文件里面,被震撼了,有木有!!!
反复测试之后,依旧正常,添加和删除都毫无问题!

答案
为什么之前使用root账号能恢复authorized_keys,而后来在给大神演示的时候,使用git用户就不能写入authorized_keys文件,而是说磁盘空间已满。导致的原因是什么呢?
多方查证之后,发现磁盘存在一个属性,叫做reserved-blocks-percentage,翻译成中文就是“保留块的百分比”。关于它的解释是:

Specify the percentage of the filesystem blocks reserved for the super-user. This avoids fragmentation, and allows root-owned daemons, such as syslogd(8), to continue to function correctly after non-privileged processes are prevented from writing to the filesystem. The default percentage is 5%.

翻译成中文就是

指定为超级用户保留的文件系统块百分比。在非特权用户进程已经不被允许向磁盘写入数据之后,保证root身份运行的守护进程,例如syslogd,能够继续正常工作。默认值是5% .

也就是说,默认情况下,磁盘空间还有5%剩余的时候,普通用户不可以再向分区中写入数据,而root用户却可以,从而保证root用户的进程能正常运行。
查看文件系统的block信息的命令是:

# tune2fs -l /dev/sda1 
...
Block count:              12499712
Reserved block count:     624985
Free blocks:              6366450

可以使用Reserved block count(保留块数)除以Block count(总块数),算出保留快的百分比,tune2fs也可以用来调整该数值.

# tune2fs -m 1 /dev/sda1 
tune2fs 1.42.9 (4-Feb-2014)
Setting reserved blocks percentage to 1% (124997 blocks)

# tune2fs -l /dev/sda1 
...
Block count:              12499712
Reserved block count:     124997
Free blocks:              6366450
...

调整之后,可以看到块限制已经变为1%了.除了使用-m指定保留块百分比,还可以是用-r指定保留块的个数,用法是:

# tune2fs -r 100000 /dev/sda1     # 保留10w个块

另外,df命令的显示,有时候明明有很大的空间,use段却显示100%或者比计算出来的数值要大,这是因为计算已使用用百分比的时候,在总量里面把保留块减去了,例如下面的df显示,保留块的百分比设置为最大值:50%,总大小是2G的/dev/sdb1,在写入1G的数据之后,显示使用量为100%,但是root用户依旧可以写入,普通用户已经不能向/dev/sdb1写入数据(可以touch空文件,但是不能写入数据):

# df -h /dev/sdb1 
Filesystem            Size  Used Avail Use% Mounted on
/dev/sdb1             2.0G  1.1G     0 100% /mnt

结论
由于gitlab是以git用户身份运行的,在删除某一个key的时候,对git用户来说磁盘已满,由于系统或者gitlab的删除方式问题,整个文件被无情的清空了,导致了这个困扰人半天的问题出现!
从对软件层的怀疑,最后回到系统层面的解决,也算辛苦和坎坷,最后总算圆满解决!

当前暂无评论 »

添加新评论 »