专栏首页云服务与SRE架构师社区浅谈Linux系统配置和最佳实践

浅谈Linux系统配置和最佳实践

原文发布于微信公众号 - 云服务与SRE架构师社区(ai-cloud-ops)

1. 前言

最近在梳理Linux服务的基准配置,发现很多系统配置是多年流传下来的,可能不是非常合理。下面以几个点为例,介绍我理解的最佳实践,希望能起抛砖引玉的作用。

2. 主机名

有些业务的运维并不会去设置主机名,而是根据IP去区分,登上去之后shell命令提示符显示的都是同样的默认主机名,这有其原因--机器的数量实在太多了。但是设置主机名一个有明显的好处,我们可以把业务相关的信息放进去,一目了然的知道这台机器的用途,特别是有些时候在登录多台机器做操作的时候,不用反复通过ifconfig查看ip确定是哪台机器。但是话说回来,前些年开始流行去Console登录,如果已经做到了这个程度,那么主机名或许是可有可无了。但我始终觉得,偶尔还是会有终端登录的需求。

CentOS7设置主机名只需要运行systemctl set-hostname <FQDN>;CentOS6需要修改/etc/sysconfig/network/etc/hosts两个文件,然后执行hostname <FQDN>使新的主机名立即生效。

如果设置了主机名,还申请了dns,可以在/etc/resolv.conf 中加入domain参数用来快速查询。比如a.example.com要访问 b.example.com,设置domain example.com之后可以直接使用b作为主机名。

3. DNS

我厂的DNS很多,每个地域都有不一样的DNS服务器。DNS服务器一多,带来的一个问题就是,很多人会有意无意的在/etc/resolv.conf里面设置一大堆nameserver。这是有问题的,很多人没有注意到,GNU libc 只支持3个nameserver,第4个开始是不起作用的,如果前3个nameserver都挂了,配再多也没用。man resolv.conf中提到:

Internet address of a name server that the resolver should query, either an IPv4 address (in dot notation), or an IPv6 address in colon (and possibly dot) notation as per RFC 2373. Up to MAXNS (currently 3, see <resolv.h>) name servers may be listed, one per keyword.

这个问题很容易测试和验证。

4. 模块化配置

现代的软件大多提供了模块化的配置能力,以nginx为例,我们一般不直接编辑它的主配置文件/etc/nginx/nginx.conf,而是按需在/etc/nginx/conf.d目录中加入自己的配置文件。

在使用脚本进行自动配置的时候,模块化能够带来冥等性,某个配置文件要么在存在,要么不存在。假如要修改某个主配置文件的一个配置项,我常用的方式是,先用sed删掉这个配置项(因为这个配置项可能明文存在,也可能不存在因而使用了默认值),然后再用另一个sed把新的配置项和值加进去,有时候这个配置项的位置还不能随便加。

如果使用模块化的配置,直接在.d目录中写入一个配置文件就好,如果这个文件存在,说明这应该符合预期的配置;如果文件不存在,说明这大概不符合预期的配置。可是我们怎么知道是不是有人修改了这些配置文件?我的做法是把所有自定义的配置文件做成rpm包,一方面方便直接安装,另一方面,如果有人改了这里的内容,rpm -V便能够发现。

这里特别要注意主配置文件和.d配置文件的先后顺序,确定哪个文件的优先级更高。

4.1 sysctl

内核参数我们习惯配置在/etc/sysctl.conf中,然后通过sysctl -p加载。CentOS7中提供了/etc/sysctl.d目录,我们可以把自己的配置文件放到这个目录中,按照<两位数字>-<文件名>的格式命名,比如CentoS7默认放了一个99-sysctl.conf。这些文件前面的两位数字决定了配置文件的加载顺序,如果同一个配置项出现在多个配置中,后者的值会覆盖前者的。99-sysctl.conf这个文件其实是指向/etc/sysctl.conf的一个软链接,这大概也是想表明,/etc/sysctl.conf的优先级高于/etc/sysctl.d中的文件。

怎么加载这些配置项呢?systemctl restart systemd-sysctl,必须用restart。

4.2 limits

我们习惯在/etc/security/limits.conf中配置limits,但其实系统中也提供了/etc/security/limits.d的目录作为模块化的配置。这里的文件同样按照<两位数字>-<文件名>.conf的格式命名,比如自带的90-nproc.conf。同样,这些文件前面的两位数字决定了配置文件的加载顺序,如果同一个配置项出现在多个配置中,后者的值会覆盖前者的。但是跟sysctl不同的是,/etc/security/limits.d的优先级高于/etc/security/limits.conf。修改limits配置后,需要重新登录才能生效。

4.3 Shell Profile

Bash的全局变量我们习惯在/etc/profile中修改,但是系统同样提供了更好的/etc/profile.d。这里的文件没有严格的命名方式,比如vim.sh(对应的还有vim.csh,那是用于C Shell的)。/etc/profile中有一段代码专门用来加载这些配置:

for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null 2>&1
        fi
    fi
done

可以看到,它们的优先级顺序是由shell通配符展开顺序决定的,在Bash中,这是按照字母表顺序排序的,以下内容来自man bash:

Pathname Expansion After word splitting, unless the -f option has been set, bash scans each word for the characters *, ?, and [. If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.

同样,这些配置要重新登录后才能生效。

4.4 模块化配置小结

项目

优先级(从低到高)

如何生效

sysctl

/etc/sysctl.d/*.conf(按数字从小到大), /etc/sysctl.conf

systemctl restart systemd-sysctl

limits

/etc/security/limits.conf, /etc/security/limits.d/*.conf(按数字从小到大)

重新登录

profile

/etc/profile, /etc/profile.d/*.conf(按文件名排序)

重新登录

5. NTP

不知道为什么大家喜欢在crontab面配一个ntpdate来代替ntpd,我猜原因是服务器的硬件时钟很不准的时候,尤其是在虚拟机环境中,ntpd经常会同步失败。Red Hat有一篇Blog《Avoiding clock drift on VMs》描述了这些问题,并提供了对应的建议。

回过头来聊聊为什么不建议用ntpdate代替ntpd,ntpd对系统时间的修改是单调递增的。而在硬件时钟特别不准的情况下,通过crontab使用ntpdate每分钟更新一次的时候,系统时钟可能会出现一种这样的情况:

序号

服务器时间

ntp server 时间

说明

1

10:00:00

10:00:00

第一次ntpdate同步

2

10:01:00

10:00:59

服务器的硬件时钟时间跑得太快了

3

10:01:01

10.01:00

crontab马上要开始下一次时间同步

4

10:01:00

10:01:00

第二次ntpdate同步

这个例子只是为了展示这种情况,硬件时钟不太可能在1分钟之内就达到1秒钟的偏差。“正常”的范围可以参考NTP的文档:http://www.ntp.org/ntpfaq/NTP-s-sw-clocks-quality.htm#AEN1220

这里存在两个问题:

  1. 时间不再是单调递增的,第二次ntpdate导致了时间的回退
  2. 第2和第4个序号的服务器时间是一样的

有些数据库和分布式id生成算法会依赖系统时间的单调递增性,因为这种问题出bug的话,简直没法查原因。我不喜欢ntpdate的另一个原因是,在crontab里面调ndpate实在太不优雅了。

但是ntpd其实也是需要配合ntpdate来使用的,如果仅启用了ntpd,可能会由于主板电池没电,或者关机时没有写入硬件时钟等原因,导致机器重启后系统时间跟ntp server差距过大同步失败。系统中还有一个叫ntpdate的服务,这个服务会在启动时调用一次ntpdate把直接把系统时间同步到位,这样接下来启动ntpd就不会有问题了。

6. 故障服务重启

有些开发喜欢在crontab里面加一个定时任务去监控后台服务的状态,如果服务挂了就重新拉起来。这首先暴露了对程序质量的不自信,其次这未必是最好的做法。CentOS7里面可以用systemd实现类似的目标,只要在systemd的配置文件中加入Restart=always即可,如果程序故障退出,systemd会重启这个服务,例如:

[Unit]
Description=my service

[Service]
Type=simple
WorkingDirectory=/tmp
ExecStart=/path/to/myprog
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
User=root
Group=root

[Install]
WantedBy=multi-user.target

这样做的另一个好处是,如果因为某些原因我们需要停止这些进程,通过systemctl stop <service>即可。如果用crontab的方式,必须先注释掉crontab,然后kill掉对应的进程;相信我,这时候肯定会有人有忘记注释就直接kill进程,更不要说kill进程本身就是个高危操作。

CentOS6的sysvinit并没有提供类似的能力,或许可以考虑supervisord, pm2这些进程管理工具?

7. 开机自启项

RedHat系的linux提供了/etc/rc.local文件,用来设置把开机启动项。但是这个文件被滥用了,很多不该放到这里的东西都放到这里来了,随便举几个例子:

  • 配置内核参数
  • 配置网卡IP
  • 有人在这里启动后台服务
  • 还有人在这里配置iptables

这些东西其实都有更好的去处:

  • 内核参数配置,使用/etc/systcl.d/etc/systctl.conf
  • 网卡配置,使用/etc/sysconfig/network-scripts/ifcfg-<nic>
  • 后台服务,使用sysvinit或systemd
  • iptables,使用iptables-save并启用iptable服务

把这些东西放到rc.local的另一个问题是,假如我们修改了其中的配置,没有很好的办法去重新加载这些配置。比如修改了网络配置,我们可以通过systemctl restart network重新加载。但如果放到/etc/rc.local中的话,修改完之后bash /etc/rc.local?不仔细检查这个文件的话,我们不知道这会带来什么副作用,比如有人在这里写了个ntpdate,这会引起时间跳变,导致前面提到的问题。

那么什么东西是适合放到rc.local中的?我想是一些设置后就正常不会变动的配置,但是我也没想到哪些东西非放到这里不可。

关于作者

不怎么务正业的程序员,BUG制造者、CPU0杀手。从事过开发、运维、SRE、技术支持等多个岗位。原Oracle系统架构和性能服务团队成员,目前在腾讯从事运营系统开发。

本文分享自微信公众号 - 云服务与SRE架构师社区(ai-cloud-ops),作者:李勇

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SRE和DevOps的关系:把SRE看作是DevOps接口的实现

    译者注:近几年,包括Oracle、微软在内的全球主要的软件企业都在其云服务研发和运营部门推行DevOps或SRE。我所在的系统架构和性能服务部门也在2017年初...

    王录华
  • SpringBoot+Prometheus:微服务开发中自定义业务监控指标的几点经验

    从马楠的上一篇文章中,我们已经了解到Prometheus的一大优势,是可以在应用内定义自己的指标做监控。我们在 SpringBoot 做微服务的生产环境中,使用...

    王录华
  • 云上构建高可用实例——应用负载均衡

      作为云行业的新人,把在云上构建系统的一点一滴记录下来,有坑填坑,没坑挖坑再填平,同时也希望能给看到此文章的人提供一定的实操及经验指南。  下文中所有云中操作...

    王录华
  • 2016年虚拟现实会迎来希望的曙光,进而大爆发吗?

    镁客网
  • 在市场还没有成熟之前,增强现实/虚拟现实企业如何才能生存下去

    虚拟现实的市场很大,增强现实的市场可能会更大(可能时间也更长)。但是就像很多新技术发展的初期一样,发展将是曲折的,道路是漫长的。今年整个行业可能就只有几十亿美...

    点滴科技资讯
  • 让你用sublime写出最完美的python代码--windows环境

     至少很长一段时间内,我个人用的一直是pycharm,也感觉挺好用的,也没啥大毛病 但是pycharm确实有点笨重,啥功能都有,但是有很多可能这辈子我也不会用到...

    coders
  • 分享一个简单的 VS 插件及源码

    今天做了一个 VS 的插件,给大家分享下。暂时有以下三个功能: ? *添加文件头 在任意文本页面,点击该按钮,可添加文件头: ? 格式可以在插件对应目...

    用户1172223
  • 虚拟现实,下一个浪潮之巅!

    在过去的十年里,我们亲历并见证了一个伟大计算平台的崛起——移动互联网。作为一个苹果粉丝,脑海中经常浮现出乔帮主在2007年MacWorld大会上向大家展示第一代...

    华章科技
  • Apache Struts2 Remote Code Execution (S2-053)

    风流
  • python爬虫scrapy框架介绍

    Scrapy介绍 ? Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。 所...

    连胜

扫码关注云+社区

领取腾讯云代金券