CentOS7系统初始化systemctl详解


  • CentOS7系统启动流程
POST --> Boot Sequeue(BIOS) --> Bootloader(MBR) --> Kernel(ramdisk) --> rootfs --> /sbin/init-->systemd
  • systemd的处理流程
    • 根据 /etc/systemd/system/default.target的配置,执行systemd程序。
    • 此文件软链接到/lib/systemd/system/multi-user.target文件
    • 根据/lib/systemd/system/multi-user.target的配置进行
    • systemd查找以下两个目录
      • /etc/systemd/system/multi-user.target.wants/,此目录下放置用户本地设定载入的unit。
      •  usr/lib/systemd/system/multi-user.target.wants/,此目录下放置系统初始化需要载入的unit。

      • 然后根据 /usr/lib/systemd/system/multi-user.target配置文件中的设定,发现需要basic.target这个脚本先启动。
      • 然后查看/usr/lib/systemd/system/basic.target配置文件的设定,发现需要sysinit.target脚本。
          • /usr/lib/systemd/system/basic.target.wants/,系统初始化的脚本。
          • /etc/systemd/system/multi-user.target.wants/,本地初始化的脚本。
          • 由此可见basic.target的启动,又需要上述这些服务脚本的启动。
          • 使用命令systemctl list-dependencies multi-user.target,可以查看multi-user.target相关的服务脚本。
          • 这种层层嵌套,连锁启动的模式,就是sytemd初始化系统的流程。
          • 如果我们分析完sysinit.target的相关启动脚本。可以大致列出centos7的systemd初始化流程:
            • local-fs.target + swap.target:挂载本机/etc/fstab配置文件中所列的文件系统与挂载点。
            • sysinit.target,侦测硬件,载入所需的核心模组。
            • basic.target,载入周边硬件程序,启用防火墙。
            • multi-user.target,一般系统的服务,网络服务的载入。
            • 启动终端shell。
        • systemd执行sysinit.target初始化系统
          • 挂载设备
          • 挂载文件系统
          • 开机信息传递与动画执行
          • 载入额外的核心模组 /etc/sysctl.conf
          • 启动随机数生成器
        • systemd执行basic.target
          • 载入声卡驱动
          • 载入 firewalld防火墙
          • 载入cpu微指令功能
          • 启用SElinux
          • 把到目前的开机信息写入 /var/log/dmesg
          • 载入管理员指定的模组 /etc/sysconfig/modules/*.modules
        • systemd执行multi-user.target
          • 启动网络服务
          • 启动终端服务
          • 启动登陆服务
          • 启动以下文件夹中的服务脚本
            • 用户自己定义的服务脚本/etc/systemd/system /multi-user.target.wants/
              • 用于开机启动的脚本,只需要在此目录下创建软连接文件即可。
                • 方法就是先自己编写服务脚本文件放在 /etc/systemd/system目录下
                • 然后运行 systemctl enable srcname.service即可。
            • 系统初始化脚本/usr/lib/systemd/system/multi-user.target.wants/
        • 与旧版本系统 systemV 相容的rc-local.service
          • Centos5系统对于放置在 /etc/rc.d/rc.local目录中的脚本,自动会开机启动。新版的ststemd也是支持这项功能的,rc-local.service服务脚本就是用于这个目的。这个服务不需要启动他,他会判断rc.local是否具有可执行权限来判断服务是否开启。
        [root@bogon ~]# ll /etc/rc.d/rc.local
        -rw-r--r--. 1 root root 473 Apr 15 12:25 /etc/rc.d/rc.local
        [root@bogon ~]# systemctl status rc-local.service
        ● rc-local.service - /etc/rc.d/rc.local Compatibility
           Loaded: loaded (/usr/lib/systemd/system/rc-local.service; static; vendor preset: disabled)
           Active: inactive (dead)
        [root@bogon ~]# systemctl list-dependencies multi-user.target | grep rc-local
        • 直接修改rc.local目录的可执行权限
        • 通过下面的方法,每次开机的时候,都会读取/etc/rc.d/rc.local目录中的文件了。
        [root@bogon ~]# chmod a+x /etc/rc.d/rc.local; ll /etc/rc.d/rc.local
        -rwxr-xr-x. 1 root root 473 Apr 15 12:25 /etc/rc.d/rc.local
        [root@bogon ~]# systemctl daemon-reload
        [root@bogon ~]#  systemctl list-dependencies multi-user.target | grep rc-local
        ● ├─rc-local.service
        • systemd提供tty界面与登陆服务
          • 启动getty.target提供操作界面
          • 启动 systemd-logind.service, systemd-user-sessions.service提供登陆服务
        • Systemd的新特性:
        系统引导时实现服务并行启动; 按需激活进程;(在进程被第一次访问之前,进程不会启动。) 系统状态快照; 基于依赖关系定义服务控制逻辑;
        • 核心概念:unit
        系统初始化需要做的事情非常多。需要启动后台服务,比如启动 SSHD 服务;需要做配置工作,比如挂载文件系统。这个过程中的每一步都被 systemd 抽象为一个配置单元,即 unit。可以认为一个服务是一个配置单元;一个挂载点是一个配置单元;一个交换分区的配置是一个配置单元;等等。systemd 将配置单元归纳为以下一些不同的类型。然而,systemd 正在快速发展,新功能不断增加。所以配置单元类型可能在不久的将来继续增加。
        • unit的常见类型:
        Service unit:文件扩展名为.service,用于定义系统服务; Target unit:文件扩展为.target,用于模拟实现“运行级别”。此类配置单元为其他配置单元进行逻辑分组。它们本身实际上并不做什么,只是引用其他配置单元而已。这样便可以对配置单元做一个统一的控制。这样就可以实现大家都已经非常熟悉的运行级别概念。比如想让系统进入图形化模式,需要运行许多服务和配置命令,这些操作都由一个个的配置单元表示,将所有这些配置单元组合为一个目标(target),就表示需要将这些配置单元全部执行一遍以便进入目标所代表的系统运行状态。 (例如:multi-user.target 相当于在传统使用 SysV 的系统中运行级别 5); Device unit: .device,用于定义内核识别的设备; Mount unit: .mount,定义文件系统挂载点; Socket unit: .socket,用于标识进程间通信用到的socket文件; Snapshot unit: .snapshot, 管理系统快照; Swap unit: .swap, 用于标识swap设备; Automount unit: .automount,文件系统自动点设备; Path unit: .path, 用于定义文件系统中的一文件或目录;
        • unit的配置文件
        每个配置单元都有一个对应的配置文件,系统管理员的任务就是编写和维护这些不同的配置文件,比如一个 MySQL 服务对应一个 mysql.service 文件。这种配置文件的语法非常简单,用户不需要再编写和维护复杂的系统 5 脚本了。 每个配置单元unit由其相关配置文件进行标识、识别和配置;文件中主要包含了系统服务、监听的socket、保存的快照以及其它与init相关的信息; 这些配置文件主要保存在: /usr/lib/systemd/system /run/systemd/system /etc/systemd/system 关键特性: 基于socket的激活机制:socket与程序分离; 基于bus的激活机制; 基于device的激活机制; 基于Path的激活机制; 系统快照:保存各unit的当前状态信息于持久存储设备中; 向后兼容sysv init脚本; /etc/init.d/ 不兼容: systemctl的命令是固定不变的; 非由systemd启动的服务,systemctl无法与之通信; 管理系统服务: CentOS 7: service类型的unit文件;
        • /etc/systemd/system/目录下的.wants结尾的目录文件
        在/etc/systemd/system 目录下还可以看到诸如*.wants 的目录,放在该目录下的配置单元文件等同于在[Unit]小节中的 wants 关键字,即本单元启动时,还需要启动这些单元。比如您可以简单地把您自己写的 foo.service 文件放入 multi-user.target.wants 目录下,这样每次都会被默认启动了。 比如:在/etc/systemd/system/multi-user.target.wants/目录下放着以下文件 也就是说,在启动multi-user.target单元的时候,会同时启动上述列出的服务文件。这些服务文件软连接至/usr/lib/systemd/system/目录中的服务文件。
        • syscemctl命令:
        命令作用: 控制systemd系统以及服务管理工具,Control the systemd system and service manager 命令格式:systemctl  [OPTIONS...]  COMMAND  [NAME...]
        • systemctl service,控制系统服务
        启动: service  NAME  start  ==>  systemctl  start  NAME.service 停止: service  NAME  stop  ==> systemctl  stop  NAME.service 重启: service  NAME  restart  ==>  systemctl  restart  NAME.service 状态: service  NAME  status  ==>  systemctl  status  NAME.service 条件式重启:service  NAME  condrestart  ==>  systemctl  try-restart  NAME.service 重载或重启服务: systemctl  reload-or-restart  NAME.servcie 重载或条件式重启服务:systemctl  reload-or-try-restart  NAME.service 查看某服务当前激活与否的状态: systemctl  is-active  NAME.service 查看所有已激活的服务:systemctl  list-units  --type  service 查看所有服务(已激活及未激活): chkconfig --lsit  ==>  systemctl  list-units  -t  service  --all 设置服务开机自启: chkconfig  NAME  on  ==>  systemctl  enable  NAME.service 禁止服务开机自启: chkconfig  NAME  off  ==>  systemctl  disable  NAME.service 查看某服务是否能开机自启: chkconfig  --list  NAME  ==>  systemctl  is-enabled  NAME.service 禁止某服务设定为开机自启: systemctl  mask  NAME.service 取消此禁止: systemctl  unmask  NAME.servcie 查看服务的依赖关系:systemctl  list-dependencies  NAME.service 管理target units: 运行级别: 0  ==>  runlevel0.target,  poweroff.target关机 1  ==>  runlevel1.target,  rescue.target救援模式 2  ==>  runlevel2.tartet,  multi-user.target多用户模式 3  ==>  runlevel3.tartet,  multi-user.target多用户模式 4  ==>  runlevel4.tartet,  multi-user.target多用户模式 5  ==>  runlevel5.target,  graphical.target图形界面模式 6  ==>  runlevel6.target,  reboot.target重启模式 级别切换: init  N  ==>  systemctl  isolate  NAME.target 查看级别: runlevel  ==>  systemctl  list-units  --type  target 查看所有级别: systemctl  list-units  -t  target  -a 获取默认运行级别:systemctl  get-default   修改默认运行级别: systemctl  set-default   NAME.target 切换至紧急救援模式: systemctl  rescue(仅执行系统初始化) 切换至emergency模式: systemctl  emergency(系统初始化都不执行,也就是没有安装驱动。)
        • 其它常用命令:
        关机: systemctl  halt,  systemctl  poweroff 重启: systemctl  reboot 挂起: systemctl  suspend(就是暂停) 快照: systemctl  hibernate (休眠) 快照并挂起: systemctl  hybrid-sleep(混合睡眠)
        • 配置文件,service unit file:
        vim /usr/lib/systemd/system/sshd.service
        [Unit]
        Description=OpenSSH server daemon 
        Documentation=man:sshd(8) man:sshd_config(5)
        After=network.target sshd-keygen.service
        Wants=sshd-keygen.service
        [Service]
        Type=notify
        EnvironmentFile=/etc/sysconfig/sshd
        ExecStart=/usr/sbin/sshd -D $OPTIONS
        ExecReload=/bin/kill -HUP $MAINPID
        KillMode=process
        Restart=on-failure
        RestartSec=42s
        [Install]
        #此处WantedBy,表明sshd服务被multi-user.target所需要。
        WantedBy=multi-user.target
        文件通常由三部分组成: [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等; [Service]:与特定类型相关的专用选项;此处为Service类型; [Install]:定义由“systemctl  enable”以及"systemctl  disable“命令在实现服务启用或禁用时用到的一些选项; Unit段的常用选项: Description:描述信息; 意义性描述; After:定义unit的启动次序;表示当前unit应该晚于哪些unit启动;其功能与Before相反; Requies:依赖到的其它units;强依赖,被依赖的units无法激活时,当前unit即无法激活; Wants:依赖到的其它units;弱依赖; Conflicts:定义units间的冲突关系; Service段的常用选项: Type:用于定义影响ExecStart及相关参数的功能的unit进程启动类型; 类型: simple:表示execstart启动的进程就是主进程 forking:表示execstart启动的进程生成的子进程就是主进程 oneshot: dbus: notify: idle: EnvironmentFile:环境配置文件;此文件在ExecStart之前读取,提供一些变量。 ExecStart:指明启动unit要运行命令或脚本;  ExecStartPre:表示启动运行命令之前运行的命令或者脚本。 ExecStartPost:表示启动运行命令之后要运行的命令或者脚本。 ExecStop:指明停止unit要运行的命令或脚本; Restart: Install段的常用选项: Alias:当前unit的别名。 RequiredBy:被哪些units所依赖; WantedBy:被哪些units所依赖; 注意:对于新创建的unit文件或,修改了的unit文件,要通知systemd重载此配置文件; # systemctl  daemon-reload 示例:自定义service文件 1.创建可运行的shell脚本,修改脚本文件的可执行权限。
        #!/bin/bash
        echo "hello world!!"
        ping 192.168.60.135
        2.创建sevice文件 在/etc/systemd/system目录下,创建myunit.service文件。 输入文件代码
        [Unit]
        Description=print hello world
        After=sshd.service
        Requies=sshd.service
        [Service]
        #EnvironmentFile=-/etc/sysconfig/firewalld
        ExecStart=/tmp/test/hello.sh
        Type=simple
        [Install]
        WantedBy=multi-user.target
        3.启用service文件 systemctl enable srcname.service 4.通知systemd重载此配置文件 # systemctl  daemon-reload 5.查看服务是否添加成功。 systemctl list-dependencies multi-user.target |grep "myunit" 6.查看服务状态。 systemctl status myunit.service