天天看点

Linux开机启动分析与系统配置

在业务运维中,经常需要做系统环境配置,环境配置要在当前运行环境中生效,也要持久化依然重启生效。

通常,大家都会想到在<code>/etc/rc.local</code>中去添加业务自定义代码,但是也会发现,有些配置重启无法生产生效。 而且rc.local中会出现大量的复杂的业务逻辑代码。修改系统配置、启动业务进程等逻辑都会存在这个文件中,调用关系复杂,维护很痛苦。

一些case :

曾经有幸看到过一些业务中看到rc.local中看到这样的代码:

在业务的发展中,文件中不断地增加代码。rc.local越来越臃肿且不可维护。

如何简化配置管理,更优雅的方式去支持业务,就需要关注下主机开机启动的细节,利用系统预留的接口达到目的。

有几个常用的关注点:

linux 服务启动方式

内核模块 启动方式

sysctl 配置生效

rc.local

主机启动过程:

主机加电,从mbr开始引导系统

启动内核

初始化系统配置

启动服务

启动用户终端

本次主要的关注点在 3、4 流程。

一个机器上可以安装多个内核。具体机器启动中使用引导哪个内核,是在 <code>/boot/grub/grub.conf</code> 文件中定义

比如一个机器grub文件举例

Linux开机启动分析与系统配置

<code>default</code> 参数是选择哪个内核作为默认启动项

<code>timeout</code> 参数是指开机启动时等待用户选择的时间

内核启动可以带多个参数,可以通过配置参数达到想要的启动结果。

内核引导完成之后,就开始初始化系统配置。

这个功能的实现其实是调用 <code>/etc/rc.sysinit</code> 脚本完成。

这个过程包括

阅读<code>rc.sysinit</code>的代码, 关注<code>内核模块的加载</code> 和 <code>sysctl配置</code>

关于内核模块的加载

Linux开机启动分析与系统配置

需要在<code>/etc/sysconfig/modules/</code> 创建<code>*.modules</code> 文件,并且具有可执行权限。在开机启动过程中,会自动的被执行。

关于sysctl配置

在 <code>/etc/rc.sysinit</code> 中有调用 <code>apply_sysctl</code>的函数。

Linux开机启动分析与系统配置

在<code>/etc/init.d/functions</code> 脚本中有大量的被调用方法,其中

Linux开机启动分析与系统配置

可以看到

使用 <code>sysctl -p /etc/sysctl.conf</code> 将默认的参数刷入系统

从 <code>/etc/sysctl.d/</code>目录下读取文件,如果文件是正常文件,就执行<code>sysctl -p $file</code> 的方式加载配置文件。

在系统参数配置完成之后,就可以启动系统进程了。

linux有个启动等级的概念。

在<code>/etc/inittab</code> 中有定义

Linux开机启动分析与系统配置

总共有 <code>0-6</code> 7个启动登记, 默认的启动启动登记是 <code>3</code>。每种启动登记分别代表不同的启动功能。

对于linux service,

<code>/etc/init.d/</code> 目录下存放具体执行的执行的服务命令 ,

<code>chkconfig</code> 命令管理着linux service的在各个启动等级下的是否启动的配置。

系统通过 <code>$service start</code> <code>$service stop</code> <code>$service status</code>的方式调用服务。

如何实现的呢?

系统启动的过程中, 通过执行 <code>/etc/rc.d/rc $runlevel</code> 的方式启动进程

在<code>/etc/rc.d/rc</code> 文件中。

Linux开机启动分析与系统配置

可以看到:

首先,循环执行 <code>/etc/rc$runlevel.d/k*</code>的所有文件都执行一遍 <code>$file stop</code>。

Linux开机启动分析与系统配置

接着,同上,循环执行<code>/etc/rc$runlevel.d/s*</code> 的所有文件都执行一遍 <code>$file start</code>

linux系统就这样管理器linux服务的启动。所有的文件名都是以 <code>[ks]+&lt;数字&gt;&lt;程序名&gt;</code>的方式命名,最终都软链到目标可执行文件。

现在那么很多问题都解释的清楚了。

(a) <code>chkconfig</code> 是怎么管理linux服务的?

(b) <code>s</code> <code>k</code>后面的数字是做什么的?

(c) linux的多个启动等级是如何实现的?

Linux开机启动分析与系统配置

线上部署的过程中,需要调整系统参数,参数包括各个方面,调整的方式也不同,需要找到合适的方式。

优雅的参数设置方式: 要易于设置,易于清理。 不能侵入系统文件.

所有的参数配置环境包括: 存量、增量、当前环境、重启环境

存量 : 已经在线上运行的主机,参数需要热修改。

增量 : 以后新部署的业务,保证参数配置正确。

当前环境 : 在当前机器的运行环境中,参数设置生效。

重启环境 : 设置配置,使机器重新启动后参数设置依然生效。

linux 存储设备的 默认io 调度策略是 <code>cfq</code> , 在db 场景下, 需要 调整成 <code>deadline</code> 模式,使每个io请求都能在deadline前得到满足。

当前环境 : <code>echo 'deadline' &gt; /sys/block/$disk/queue/scheduler</code>

重启环境 : <code>grubby --grub --update-kernel=all --args="elevator=deadline"</code>

通过给 echo 修改内核变量,修改当前运行环境的配置,通过grubby 命令修改 grub.conf,设置内核加载参数, 这样当机器重启的时候,自动的会把每个设备的 io schedular 变成 deadline 。

linux /etc/fstab文件中记录了每个分区被开机挂在的参数。

ext4文件系统挂载的时候,默认参数使用 <code>data=order</code>模式,可以通过 <code>cat /proc/mounts</code>来查看。

场景:postgresql 在用户请求的时候,会频繁的创建和释放临时文件,在请求量大的时候,机器的io会hang, 是因为ext4文件系统在记录文件的时候,需要多次硬盘io,为了保证数据的一致性,以同步的方式记录元数据/日志/数据,导致机器io跟不上,需要把挂在参数修改成 <code>data=writeback</code> 模式,可以异步记录文件的元数据、数据,提高性能。

存量 : 安装热修改的hotfix 。

增量 :

<code>umount /data</code>

<code>sed -i "s/noatime/noatime,data=writeback/" /etc/fstab</code> #修改fstab, 中设备的挂载参数

<code>mount -a</code>

__注__: 关于 ext4的参数的更多信息,请自行搜索

很多情况下都是需要修改系统参数,来调优系统. 很容易想到的是 <code>/etc/sysctl.conf</code>。 不管是 echo 或者sed 的方式都会破坏 <code>sysctl.conf</code>的可读性,入侵性太大,且需要求变更修改的时候,会很麻烦。根据<code>/etc/rc.sysinit</code>的脚本我们知道他的加载方式.可以采用这样的方式。

编写一个和<code>/etc/sysctl.conf</code>类似的 <code>mysysconf</code> 文件,其中定义了业务关心的,需要求改的参数列表.

<code>mkdir -p /etc/sysctl.d</code>

<code>cp mysysconf /etc/sysctl.d</code>

<code>sysctl -p /etc/sysctl.d/mysysconf</code>

增量/存量/当前环境/重启环境均可生效。

当时用iptable的时候, 默认<code>nf_conntrack_max</code>的配置值是 65536,当请求多的时候,机器上就会报 : <code>nf_conntrack: table full, dropping packet</code> 机器也会连不上,是由于nf_conntrack中的哈希表满了, 这种就需要放大 <code>nf_conntrack_max</code>的值。

如果直接修改sysctl, sysctl -p 的时候会提示:

<code>error: "net.nf_conntrack_max" is an unknown key</code>

所以需要先 <code>modprobe nf_conntrack</code>, 然后才能刷 系统参数.

推荐的方式:

编写 <code>my.modules</code>文件,内容:

modprobe nf_conntrack

<code>cp my.modules /etc/sysconfig/modules/&amp;&amp;chmod +x /etc/sysconfig/modules/my.modules</code> #参见 <code>/etc/rc.sysinit</code> 内核模块的加载方式。

<code>sh /etc/sysconfig/modules/my.modules</code> # 在当前环境中,加载内核模块

<code>cp mysysconf /etc/sysctl.d/</code> #系统配置参数其中定义了 <code>nf_conntrack_max</code> 为更大的值

<code>sysclt -p /etc/sysctl.d/mysysconf</code> 在当前系统中使配置生效

当机器上部署多个服务时,服务管理就是一个问题。

改造应用, 让应用以linux 标准服务方式,交给chkconfig 管理,还可以自定义开机器组件之间的启动顺序。

如何可以,尽量不用<code>rc.local</code>

继续阅读