今天被LTN问了一下怎么看一个知乎问题:

服务器操作系统应该选择 Debian/Ubuntu 还是CentOS?

其实我觉得他的大部分说法都没有错。如果你需要装一个服务器,确实首选是RH系的。

但是。。。

选用RH系的主要理由

其实你把回复从头看到尾,主要论点就一点:

哪个发行版,可以在长达7-10年的时间里,始终保持硬件稳定性的同时,又持续的升级补丁?

结论当然是RH!这是RH的主要卖点。

我们真的需要长达7年的硬件稳定性支持?

咳咳,今年上半年,蔽厂的运维碰到了这么一件尴尬事。

他们进货,去机房装系统,配置网络结构,加入运维管理系统,添加监控,交付。除去采购外,整个一套流程大概是一周。

我们在机房里面原本大约有10个机柜,那么一般扩充的时候,一次扩充一个机柜。

结果今年上半年的某一段时间,一周一个机柜的事情持续了两个月。运维同学辛辛苦苦装好一个机柜,周末打算轻松一下。被老大通知,又来客户了,机柜又不够用了,下周继续。

是的,我们现在20个机柜不止。机房有多少机柜我不知道,不过照这个趋势来看,我们快把机房包下来了。现在我们的带宽已经没有限制了,每个月月底按照合同秋后算账。

我们有一些有三年历史的服务器,台数不多。现在来看,性能已经远远不够。CPU不够快,也没有SSD,硬盘读写次数也太多。这些机器的下场,多数会被换下来折旧卖掉,或者作为测试服务器,搬去测试机房。而现在机房里面大半机器,都是两年以下历史的。而且至少一半服务器历史不超过半年(。。。)。从现状上看,把老服务器留在机房,其性价比并不合算。因为机房有机架密度问题,限制着我们的单机房极限,这相当于变相的租金。

如果考虑到这点,我们的线上服务器生命周期大概也就三年。最多。很多时候甚至还不到。

比我们更极端的是页游。他们的一组服务器生命周期一般是半年。半年内,要赚钱的也赚完了,不赚钱的也死完了。所以他们甚至不会新采购硬件服务器,而是直接使用虚拟机。

当然,虚拟机内的系统,支持时间是一年还是十年,对他们一点意义都没有。

为什么我们不喜欢三年以上的系统?

RH系的提供10年级别的维护性,我换个说法,也就是最近的软件在RH的官方库里面找不到。当然,装最新的RH是有的,但是在安装了三年的一个系统上?肯定没戏。

怎么办?编译呗。

这大概就是国内谈到RH必编译的由来。

可是,我引用文内的一段话。

如果我今天告诉大家,我要做一个 http 的服务器,我不用 apache 不用 nginx,
为了性能我要用 xxx 为基础重写一套出来。我相信绝大多数人会问同样的问题,
“你觉得你写的能比 ng 好么?”
再回头看看那时候你们自己吧。

同样,自己编译的软件,补丁维护速度,能和新系统比么?而且我们还得扔一个人下去搞补丁维护。

所以,正解是什么?

装一套新的,把数据导过去用呗。

我们的”数据“,都是装载在磁盘上的。而换”系统“并不需要更新这些数据,只要把系统盘擦掉重部署一遍,然后配置好deploy系统就OK。在开发之初,”环境“,”程序“和”数据“分离,就是一项基本原则。而且即使是”数据“,丢掉一台机器上的所有”数据“也不会构成问题。这应当是运维基础中的基础。只有少数几台服务器,既不能直接更换也不能停机。这些机器我们做特别的管理。

为什么蔽厂使用Ubuntu?

很简单。因为最初的开发希望在Linux上进行。直接在Linux上开发和测试,对于startup的快速开发是非常重要的。而开发用什么版本,服务器跟什么版本,这是最省事和好办的。如果你硬要和我争,说开发在Mac上,跑在Linux上一点事都没有。或者说开发一个发行,服务器一个发行也OK。

我至少得说这对于golang和python都不是事实。除非不用cgo,也不用python的C扩展。

先不提Mac下和Linux下的差异。我们今年在升14.04的时候就发现,12.04和14.04的编译互不通行。所以现在12.04的编译可以程序员自己编译了本地测,14.04的就必须在测试环境里干。一帮程序员远程tcpdump出结果,拷回本地wireshark一把。。。

看看就蛋疼。

当然,这也有个问题。就是上面”我们不喜欢三年以上的系统“。所以呢。明年我们的系统大概会轮换重装,14.04。。。

也很蛋疼。

Debian系的补丁不靠谱么?

那要看和谁比。这里有HeartBleed事件的统计。虽然不普遍,但是我觉得这种大漏洞比较有代表性。

CVE-2014-0160 - OpenSSL安全漏洞的非技術事件

我引用他的重点整理:

RedHat 修復的速度比 OpenSSL 官方還快。
RedHat 派系的修復時間,除了 RedHat 外都算慢,如 Fedora 及 CentOS、Scentific,
他們都比 RedHat 慢 16 小時以上。
Debian 派系的修復時間,如 Debian 及 Ubuntu,都比 RedHat 慢上至少 12 小時以上。
Scentific 是列表中修復最慢的。
若以資安黃金 6 小時來說,Fedora、CentOS、OpenSUSE、Gentoo
及 Scentific 都不及格。

如果和RH比,Debian的修复速度是不及格,但是和CentOS比。。。怎么说呢?6个小时对10个小时,有种五十步笑百步的味道?

换你你愿意走几步?

另外,我也不知道原文说的升级一大包是怎么回事。我在Debian stable上查询ssl:

$ dpkg -s libssl1.0.0
Version: 1.0.1e-2+deb7u12
Depends: libc6 (>= 2.7), zlib1g (>= 1:1.1.4), debconf (>= 0.5) | debconf-2.0

但是同时。

$ dpkg -l | grep libc6
ii  libc6:i386                           2.13-38+deb7u3                i386         Embedded GNU C Library: Shared libraries

libc的依赖早就满足到不能再满足了。直到今天为止,openssl在debian上的升级还不需要你强制跟随升级libc6。而kernel根本没有依赖。

纠正原文的一点理解错误

Debian 是由社区维护、贡献的发行版本,其从选包、打包、都是由社区组织,分散行动的。
Debian 是没有真正意义的 release 概念的。Debian 有众多仓库,stable,testing,
unstable ,experimental. Debian 组织系统的方式是,一个软件先进入 experimental, 
放一段时间,有 bug 修 bug,没 bug 了,过段时间挪入 unstable,
如此循环最终挪到 stable 里面。
所以在这种情况下,Debian 的系统中,是没有一个稳定版本的概念。
今天你用 kernel 3.2.1-87 , 明天就给你更新到 kernel 3.3.2-5 。

Debian是由社区维护,这没错。但是选包并不是社区组织。Debian中,如果没有特定理由(例如dsfg)阻止你打一个包,那么只要有maintainer,就可以打包。哪怕这个包的用户其实不是很多(很多包甚至统计上只有1X个用户),这也是Debian那么一大堆包的原因。

Debian包的管理方式是,先进入unstable(是的,除了少数情况,一般不是进入experimental)。在一周后,看看没问题,就进入testing。没问题的指标是,这个包和依赖的包没有RC bug,就是致命性bug。

所以很多在unstable里面有的东西,testing里面反而没有。因为unstable里面的某个基础依赖包的RC bug并没有被修复。而且testing修漏洞的速度是最慢的。因为一出问题,unstable会直接引入新的版本。而stable会要求maintainer修复。可怜的testing只能等一个礼拜。。。

那什么时候进入stable?他不会随着你的循环进入stable。而是每1.5-2年(预期1.5年,但是RC冻结周期往往会超标,根据历史数据统计,一般两年)做一次发布,这个发布会冻结所有新包,并修正RC bug。等大家觉得差不多稳定了,OK,原本的testing就成为stable,而原本的unstable就fork出新的unstable和testing。

所以现在的testing代号就会成为下一个stable代号,而每次fork的时候,我们都是决定testing代号——就是下个发行的发行代号。

所以你看BTS的追踪,会发现每1.5年有一段时间,RC bug的数量会锐减,而新包的数量也锐减。这不是大家都冬眠了,只是新发行周期而已。

作为证据,下面是我的Packages overview。大家可以看到,python-snappy(这是我唯一维护的包了,python-formalchemy已经RFA了)在stable里面是0.4,而新的两个里面是0.5。我没有明确理由把stable里面的版本升级到0.5。

那debian怎么修bug?

这个看maintainer。一般的原则是,如果不是无法保持版本,一般直接打补丁升级。这也是原文的一点理解错误。如果用的真的是Debian stable,没有特殊理由的话,内核是不会升级到3.3的。作为证据,大家可以看一下现在stable的官配内核版本号。目前是linux-image-amd64 (3.2+46),依赖应该是linux-image-3.2.0-4-amd64 (3.2.60-1+deb7u3)。也就是说,版本号应该是3.2.60-1+deb7u3。而3.2在kernel.org上的longterm对应版本号是62。

原作者这个理解,怎么说呢。我怀疑他要么没仔细用过debian,要么用的是testing。

但是如果新老版本差异太大,老版本又拒绝提供补丁,那么逼不得已的情况下,需要评估是不是能升。例如某一段时间,mysql的版本号是5.0XXreal5.5XXX(这个是听本厂DD说的)。至于原本的兼容性问题,我也不知道他们是怎么想的,大概是认为mysql server没啥依赖性问题吧。

但是这种情况下,RH一般也没办法吧——除非他们自己出程序员给老版本做一遍补丁。不过如果这样的话,oracle一般会merge back回去,debian就跟着沾光了。

Ubuntu的误解

Ubuntu 8.04 LTS April 24, 2008
Ubuntu 8.04.4 LTS January 28, 2010
1年9个月
你说好的 LTS 呢???
Ubuntu 10.04 LTS April 29, 2010
Ubuntu 10.04.4 LTS February 16, 2012
说好的 LTS 呢?
说 End of the Date 是3年整就是一个笑话,
只要下个 release 一出,上个 release 收到的更新数量就可怜。

作者大概是RH用多了,没搞明白Ubuntu“维护”的本质。

Debian和Debian基础的系统,主要的发行方式是网络。光盘只是给你个安装的机会。这点debian更加明显——他有种光盘叫做netinst。里面只有基础包的安装包。在不联网的情况下,你只能装出一个用于联网升级的系统。没有gui,没有openssh,啥都没有。

所以,LTS归LTS,修改不够多是不够打新光盘的。

谁会持续5年,一年给你弄张新光盘出来啊——尤其是里面没几个包改了。

而LTS的维护怎么样?我们来看usn的维护情况。

在2014年6-7月,总共有26个USN涉及ubuntu lucid。

所以装好ubuntu,第一件事是去repository上面打一遍安全补丁!

”维护“的本质问题

上面说了半天,根本问题是,”维护“是个什么东西?

主要就是bug修复。尤其是一类特殊bug修复——安全补丁。

一旦一个程序基本成型,就一定会形成”接口“。API是接口,调用的程序,参数,顺序,环境变量,一样是接口。有接口就有接口兼容性。如果不考虑兼容性,一律使用最新版本的话。。。

bang。不知哪天程序就跑不动了。因为作者改了接口。

不要以为这很扯,我在实际里多次碰到这种问题。python-mongo多次修改接口,sqlalchemy0.6时写的程序,经我反复修改终于上到了0.7,却死也上不到0.8。至于docker,也是个版本号刚刚过1.0的家伙。在1.0前面,我们就作大死的做了二次开发。结果惨不忍睹。

所以我们用一种被称为“发行”的方案。即一段时间,将稳定的代码固定下来,形成某个版本的发行。例如linux-kernel-3.2.0。而后新功能在3.3上面渐进,原本使用3.2的并不受到干扰。

这本来挺完美,可惜有一个问题。bug并不一定出在最新版上面,他有可能在14年前就已经存在了。这样会使得bug横跨多个版本。而这个bug又不能不修的时候——例如安全漏洞。

这时候就蛋疼了。

上游会修多少个发行的漏洞?如果上游不修,这个发行的漏洞怎么办?大部分漏洞只是几行就可以完成修正,但是有些发行甚至要动架构,怎么办?

没有研发力量,是不能保证修复的。

在代码里面,主要有三件事情,功能发展性,接口稳定性,代码安全性。

如果我们可以去掉一件事情,那么世界很完美。

  1. 去掉接口稳定性,每次都用最新的就好了,bug肯定修光的。
  2. 去掉功能发展性,软件不再推进就好了,就修修bug。
  3. 去掉代码安全性,单纯发行就好了,发了就不用管了。

可惜,三者一般都需要。有些很古典的程序已经进入了2的情况,例如TeX。至于大部分互联网公司线上系统,则比较偏向1。但是大部分发行版内的包,可是要三者都满足的。

RH和Debian的开发差异

其实还是很大的。RH的开发是真的开发。Debian的"Developer",其实只管开发debian打包用脚本,维护版本,补丁,仓库。而RH的开发,别的不说,你就看内核补丁贡献数吧。

这也是社区和公司不同取向的差别。社区不管商业能处理的一些问题,而且他们也管不了。先不提RH有多少人,Debian社区有多少人。我就吐槽一下中国DD数量吧。我查询了一下,总共8个(db)。其中我认识5个,超过一半。某次emfox来开会,lidaobing和zigo也在。我们开玩笑说,这次会议集中了中国近一半的DD。。。其实整个会场里面人数都没超过20。。。

也只有RH这种级别的公司,才有大量人力去折腾内核,驱动之类的事情。因为debian就算想折腾,也折腾不动啊。从某种意义上说,所有linux发行的蓬勃发展,都得益于RH的大量收入。

所以真想支持开源的,不全买,买一套RHEL也好啊。别老叫着CentOS免费,免费还说个JB的支持开源。

什么情况下用RH,什么情况下不一定

虽然在上面数了原作者的一堆问题,但是我得说,他的结论没啥错误。

除非你明白自己在干什么,否则RHEL一定是你的第一选择。

这是废话。出钱让人帮你解决问题,和你自己解决问题,哪个更专业?

凡是你干了这活,打算三五年内就上去升级升级安全补丁,此外啥都不想干的。用RHEL准没错。

如果上面这种情况会让你失业的,换Gentoo准没错。

至于什么叫做“明白自己在干什么”,其实没一个统一的标准。很多时候选择开发版有点“如人饮水,冷暖自知”。例如我们选Ubuntu,解决了发布同环境问题,却引入了运维滚动升级问题。但是经过权衡,发布和调试环境不同会导致研发效率的大幅下降,而我们的研发是不能靠花钱招的(广告:长期招聘靠谱golang研发),但是我们的运维是可以靠花钱招的。这个时候痛苦也得滚动着上了。当然,也许若干年后,发现其实我们错了。可是错的理由我们现在看不到也想不到。当然,像我们,或者页游这种奇葩公司,也不总是出现。所以大部分情况下,用RHEL都是对的(当然,原作者说的太绝对化了一点)。

用Debian用什么

Debian是非常强调dsfg的,具有非常强的开源原教旨主义的味道。

传统的开源认为,如果只有商业公司掌握发行,那么他们就会扼住我们的命脉,并以此作恶。

不得不说,老外对垄断和权威的恶和理解一点都不比我们差。

所以debian的衍生发行一点都不比RH逊色(Linux发行版列表)。最大的就是得益于dsfg规定,凡是允许进入debian的,不能仅仅授权给debian——而是必须授权给整个公有领域。因此对debian的衍生是非常安全而没有法律风险的——DD们在这个领域的专业程度非常高。

而且,由于强调自由,因此debian内所有非核心包,都具有非二进制定制性。简单来说,就是除了核心包和打包参数,其他大部分结构都是可以更改而且应当是自己更改配置的。

想用lxde换掉gnome,可以。搭配着kde的软件使?也可以。上面用什么输入法?自己配。

这是debian的强大和灵活所在,也是debian非常高的一个门槛。相比起来,Ubuntu更强调“开箱即用”。所以里面的随附配置是最完备的。但是要用lxde,推荐就是Lubuntu了。

CentOS不是RH

我上面提到的RH,大部分指的都是RHEL。至于Cent——他也是社区系统,只是背靠RH,胳膊更粗一些而已。这不代表Cent因此就靠谱了。

例如这个维基页面CentOS,里面提到说。

In July 2009, it was reported[by whom?] that CentOS's founder,
Lance Davis, had disappeared in 2008. Davis had ceased contribution
to the project, but continued to hold the registration for
the CentOS domain and PayPal account. In August 2009,
the CentOS team reportedly made contact with Davis and
obtained the centos.info and centos.org domains.[12]

那哥们直接失踪了近一年,而且捏着域名和PayPal账户不放。我记得当年这事直接导致CentOS的其他开发者出来放话,再不出来把你丫按照失踪申报。

这也直接导致我上家公司的基系统选择从CentOS改成了Scentific(是的,就是上面修复最慢的那家)。

其次,CentOS是不签合同的,所以出了事是运维自己兜着。

CentOS出了问题你能和领导交代么?这得看你们领导的SB程度。反正要是有人告诉我,他用CentOS出了事。我的第一反应都是,RHEL是不是可以避免。可以的,那就是决定用的人自己找事。

如果用RH,至少应该用RHEL,并且买订阅

我们没有用RHEL,都买了RH的订阅。RH的订阅非常有指导意义。