systemd服务详解

一、init进程演变

  1. init的发展
    开发Systemd的主要目的就是减少系统引导时间和计算开销。Systemd(系统管理守护进程),最开始以GNU GPL协议授权开发,现在已转为使用GNU LGPL协议,它是如今讨论最热烈的引导和服务管理程序。如果你的Linux系统配置为使用Systemd引导程序,它取替传统的SysV init,启动过程将交给systemd处理。
    CentOS5:SysV init,串行 CentOS6:Upstart,并行,借鉴ubantu CentOS7:Systemd,并行,借鉴MAC

  2. Systemd新特性:
    (1)系统引导时实现服务并行启动:服务间无依赖关系会并行启动。
    (2)按需激活进程:若服务非立刻使用,不会立刻激活,处于半活动状态,占用端口用时启动服务。
    (3)系统状态快照:回滚到过去某一状态。
    (4)基于依赖关系定义服务控制逻辑。
二、unit单元服务
  1. unit相关配置文件:
    unit由其相关配置文件进行标识、识别和配置。文件中主要包含了系统服务、监听的socket、保存的快照以及其它与init相关的信息。
    unit配置文件的位置:
    /lib/systemd/system本地配置的系统单元 /run/systemd/system运行时配置的系统单元 /usr/lib/systemd/system第三方软件的系统单元(sshd,nginx..)

  2. unit常见类型:
    Serviceunit:文件扩展名为.service,用于定义系统服务; Targetunit:文件扩展为.target,用于模拟实现“运行级别”; Device unit=:文件扩展名为 .device,用于定义内核识别的设备; Mount unit:文件扩展名为.mount,定义文件系统挂载点; Socketunit:文件扩展名为 .socket,用于标识进程间通信用到的socket文件; Snapshotunit:文件扩展名为 .snapshot, 管理系统快照; Swapunit:文件扩展名为 .swap, 用于标识swap设备; Automountunit: 文件扩展名为.automount,文件系统自动点设备; Pathunit:文件扩展名为 .path, 用于定义文件系统中的一文件或目录;

  3. unit特性:
    1)基于socket的激活机制:socket与程序分离,将套接字先分配但时程序本身未启动 2)基于bus的激活机制:基于总线的请求来激活设备 3)基于device的激活机制:设备插入时候自动挂载激活设备,挂载点不存在自动创建 4)基于Path的激活机制:监控目录文件是否存在来激活服务或者进程 5)系统快照:保存各unit的当前状态信息于持久存储设备中; 6)向后兼容sysv init脚本;/etc/init.d/下的脚本也能兼容

三、syscemctl命令
  1. 启动/关闭类
    启动: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

  2. 查看服务类
    查看某服务当前激活与否的状态:systemctl is-active NAME.service 查看所有已激活的服务:systemctl list-units --type service 查看所有服务(已激活及未激活):chkconfig --lsit==>systemctl list-units -t service --all

  3. 开机设置类
    设置服务开机自启:chkconfig NAME on ==>systemctl enable NAME.service 禁止服务开机自启:chkconfig NAME off ==>systemctl disable NAME.service 查看某服务是否能开机自启:chkconfig --listNAME ==>systemctl is-enabled NAME.service 禁止某服务设定为开机自启:systemctl mask NAME.service 取消此禁止:systemctl unmask NAME.servcie 列出所有已安装的服务以及它们的状态:systemctl list-unit-files 列出开机启动失败的服务:systemctl --failed 列出某种类型(service, mount, device, socket, target)的服务:systemctl --type=mount 将一个shell脚本设置为开机启动:systemctl enable debug-shell.service

  4. 查看依赖关系类
    查看服务的依赖关系:systemctl list-dependencies NAME.service

  5. 管理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

  6. 其它常用命令:
    关机:systemctl halt, systemctl poweroff 重启:systemctl reboot 挂起:systemctl suspend 快照:systemctl hibernate 快照并挂起:systemctl hybrid-sleep

四、服务单元文件:service unit file
  1. /usr/lib/systemd/system和/etc/systemd/system关系
    /etc/systemd/system设定默认运行级别和启动时服务的运行关系,连接文件。
    一般管理员可在/etc/systemd/system下定义一些service unit file文件。
  2. service unit file文件格式
    [root@ss01 system]# cat firewalld.service [Unit] Description=firewalld - dynamic firewall daemon Before=network-pre.target Wants=network-pre.target After=dbus.service After=polkit.service Conflicts=iptables.service ip6tables.service ebtables.service ipset.service Documentation=man:firewalld(1)[Service] EnvironmentFile=-/etc/sysconfig/firewalld ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS ExecReload=/bin/kill -HUP $MAINPID # supress to log debug and error output also to /var/log/messages StandardOutput=null StandardError=null Type=dbus BusName=org.fedoraproject.FirewallD1 KillMode=mixed[Install] WantedBy=multi-user.target Alias=dbus-org.fedoraproject.FirewallD1.service

    [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等;
    [Service]:与特定类型相关的专用选项;此处为Service类型;
    [Install]:定义由"systemctlenable"以及"systemctldisable"命令在实现服务启用或禁用时用到选项;
    (1) Unit段的常用选项: Description:描述信息;意义性描述; After:定义unit的启动次序;表示当前unit应该晚于哪些unit启动;其功能与Before相反; Requies:依赖到的其它units;强依赖,被依赖的units无法激活时,当前unit即无法激活; Wants:依赖到的其它units;弱依赖; Conflicts:定义units间的冲突关系;(2)Service段的常用选项: Type:用于定义影响ExecStart及相关参数的功能的unit进程启动类型。类型有: simple:默认。由ExecStart指明的进程所启动起来进程为主进程 forking:由ExecStart所启动的进程生成的一个子进程为主,父进程退出 oneshot:一次性的启动,后续的unit进程启动后,该进程退出 dbus:仅在得到dbus之后才推出 notify:发送通知以后才能运行 idle:类似于simple EnvironmentFile:环境配置文件,为ExecStart提供一些变量; ExecStart:指明启动unit要运行命令或脚本;ExecStartPre, ExecStartPost ExecStop:指明停止unit要运行的命令或脚本; Restart:启动此项,意外终止会自动重启脚本(3)Install段的常用选项: Alias:当前unit的别名 RequiredBy:被哪些units所依赖; WantedBy:被哪些units所依赖;

    注意:对于新创建的unit文件或,修改了的unit文件,要通知systemd重载此配置文件;
    [root@ss01 system]# systemctl daemon-reload

  3. 编写unit文件,并注册到systemd服务中
    第一步:准备一个shell脚本 [root@ss01 system]# vim /root/name.sh #!/bin/bash echo `hostname`>/tmp/name.log第二步:创建unit文件 [root@ss01 system]# vim my.service [Unit] Description=this is my first unit file[Service] Type=oneshot ExecStart=/bin/bash /root/name.sh[Install] WantedBy=multi-user.target [root@ss01 system]# mv my.service /usr/lib/systemd/system第三步:将我的unit文件注册到systemd中 [root@ss01 system]# systemctl enable my.service第四步:查看该服务的状态 [root@ss01 system]# systemctl status my.service

五、journalctl日志:
  1. 常用命令:
    显示系统上所有日志,以及它的用户:journalctl --all 监视系统日志的变化:journalctl -f 显示系统启动以后的日志:journalctl -b 显示上一次(-b -1)系统启动前产生的内核日志:journalctl -k -b -1 显示系统启动后产生的“ERROR”日志:journalctl -b -p err 显示cron服务在某个时间段内打印出来的日志:journalctl -u cron.service --since='2022-01-06 07:00' --until='2022-01-06 08:23' 显示优先级别为2以内的日志:journalctl -p 2 --since=today 将二进制日志文件复制成文本文件并保存到当前目录:journalctl > testlog.log 查看某个路径的脚本的日志:journalctl /usr/bin/bash 显示日志占据的硬盘空间:journalctl --disk-usage 指定日志文件占据的最大空间:journalctl --vacuum-size=1G 指定日志文件保存多久:journalctl --vacuum-time=1years所有日志级别有: emerg (0), alert (1), crit (2), err (3), warning (4), notice (5), info (6), debug (7)

六、systemd-analyze分析系统启动过程:
  1. 利用systemd分析系统启动过程:
    显示本次启动系统过程中用户态和内核态所花的时间:systemd-analyze 显示每个启动项所花费的时间明细:systemd-analyze blame 按时间顺序打印UNIT树:systemd-analyze critical-chain 为开机启动过程生成向量图(需要安装graphviz软件包):systemd-analyze dot | dot -Tsvg > systemd.svg 产生开机启动过程的时间图表:systemd-analyze plot > bootplot.svg

七:grub2命令
  1. grub2的配置文件:/etc/default/grub
    [root@ss01 ~]# cat /etc/default/grub # 指定用户选择菜单超时时间 GRUB_TIMEOUT=5# 指定菜单中的描述名称 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"# GRUB指定哪个是默认的title # save表示会保存当前的配置,需要结合一个内置变量来使用 GRUB_DEFAULT=saved# 禁用子菜单 GRUB_DISABLE_SUBMENU=true# 指定将启动过程中的信息输出到终端 GRUB_TERMINAL_OUTPUT="console"# 在启动系统的时候,以命令行的方式向内核传递参数 GRUB_CMDLINE_LINUX="crashkernel=auto rhgb " # 指定是否显示启动过程信息 GRUB_DISABLE_RECOVERY="true"

  2. 定制grub2的配置文件
    第一步:备份原有的grub.cfg [root@ss01 ~]# cp /boot/grub2/grub.cfg{,.bak}第二步:修改/etc/default/grub第三步:重新生成grub.cfg [root@ss01 ~]# grub2-mkconfig>/boot/grub2/grub.cfg

八:单用户模式修改密码
  1. 进入紧急救援模式
    进入方式:在启动系统的时候,编辑内核选项,添加rd.break,然后按ctrl+x 进入救援模式后: a. 根在sysroot下 b. 当前是只读权限

  2. 【systemd服务详解】操作:
    # mount -o remount,rw /sysroot # chroot /sysroot # echo '******' | passwd --stdin root # exit # reboot

    推荐阅读