分享

利用systemd来管理服务

 阿青哥Joe 2018-06-28
1.1 简介
   systemd是linux系统的系统和服务管理器,它兼容之前的SysV init脚本,并提供一系列的其他特色:启动时系统服务的并行启动、按需启动服务、支持系统状态快照、基于服务依赖的控制逻辑。
   systemd引入systemd units概念,这些units是通过一些配置文件代表的。以下列出所有的systemd units类型:
Unit Type            File Extension          Description
------------------------------------------------------------------
Service unit         .service               系统服务
Target unit          .target                一组systemd units
Automount unit  .automount              文件系统的自动挂载点
-------------------------------------------------------------------
Device unit          .device                由内核识别的设备文件
Mount unit          .mount                文件系统挂载点
Path unit              .path                 文件系统中的文件或者目录
-------------------------------------------------------------------
Scope unit          .scope                 外部创建的进程
Slice unit             .slice            一组管理系统进程的分级组织的units
Snapshot unit     .snapshot               存储的系统管理器状态
Socket unit         .socket                 进程间通信套接字
-------------------------------------------------------------------
Swap unit            .swap                 交换设备或者文件
Timer unit           .timer                systemd定时器
Systemd unit存储位置:
文件夹             描述
/usr/lib/systemd/system/ 利用RPM包安装的软件产生的Systemd unit
/run/systemd/system/   运行时产生的Systemd units,该文件夹优先于directory with installed service units
/etc/systemd/system/   系统管理员创造的systemd units,该文件夹优先于运行时units

1.1.1 主要特点
   也就是以上列出的系统支持的unit类型对应的启动特点。
1.1.2 兼容性
    systemd对于runlevels的支持是比较局限的。它仅提供一些target units文件,这些文件可以对应runlevels中的运行级别。但是,并不是所有的运行级别都能一一对应,因此尽管可以用runlevel命令,但并不建议这么做。
    systemctl工具并不支持定制命令,这在SysV int启动脚本中是可以的。systemctl工具并不能与非systemd启动的服务进行交流,当用systemd启动一个系统服务时,它会存储该服务主要进程的ID并跟踪,systemctl利用这个PID来管理这个服务,而当用户在命令行直接启动一个服务时,systemctl并不能判断该服务的状态也不能停止该服务。
    系统服务并不能从标准输入读取信息,当systemd启动一个服务,它会把该服务的标准输入连接到/dev/null来防止与用户直接交流。
    系统服务并不能从用户以及他们的对话中继承任何环境(包括HOME、PATH等环境变量),每一个服务都运行在新的执行环境中。
    所有针对服务的操作都遵守默认5min的超时,以防服务发生问题导致系统死机。

1.2 管理系统服务
    早期版本的RHEL采用SysV init或Upstart,利用/etc/rc.d/init.d/文件夹中的启动脚本,这些启动脚本通常是bash脚本,并且允许管理员控制服务的状态。在systemd控制的系统中,这些启动脚本被service units替代。
    以.service后缀的系统units与启动脚本完成相似的功能,为了view、start、stop、restart、enable、disable一项系统服务,可以用systemctl命令。当然之前的service和chkconfig命令也是可用的,但是不建议使用。
    为了清晰明了,该部分采用全名(带有.service后缀):
        systemctl stop bluetooth.service            
    当处理系统服务时,允许省略文件后缀:systemctl工具当面对一个没有后缀的unit时,会默认其为service unit,因此上一个命令与下面的等价
   systemctl stop bluetooth
   systemctl start name.service             启动服务
   systemctl stop name.service              关闭服务
   systemctl restart name.service            重启服务
   systemctl try-restart name.service         当系统运行状态则重启该服务
   systemctl reload name.service                重新加载配置
   systemctl status name.service                判断服务状态
   systemctl is-active name.servie                判断服务是否在运行
   systemctl list-units --type service --all    列出所有服务的状态
    
   systemctl enable name.service               开机自启一项服务
   systemctl disable name.service                关闭开机自启一项服务
   systemctl is-enabled name.service            判断该服务是否enabled
   systemctl list-unit-files --type service    列出所有的服务,并判断其是否enabled
   systemctl list-dependencies --after            列出特定unit启动之前需要启动的服务
   systemctl list-dependencies --before        列出特定unit启动之后才启动的服务
1.2.1 列出服务
    为了列出目前所有的service units,用以下命令:
    systemctl list-units --type service
    默认情况下,systemctl list-units命令示出活动的units,如果想要列出任何状态的units,用以下命令:
    systemctl list-units --type service --all
    列出所有安装的服务以及它们的enable状态
    systemctl list-unit-files --type service    
1.2.2 显示服务状态
    利用systemctl status name.service 会列出如下字段信息:
    Loaded         关于该系统服务unit是否已加载、unit文件的绝对路径、该unit是否时enabled状态
    Active        显示该服务是否在运行,并在其后有一个时间
    Main PID    相应系统服务的名字以及其PID
    Status         相应系统服务的额外信息
    Process        相应进程的额外信息
    CGroup        相关控制组(cgroups)的额外信息
1.2.3  启动一项服务
    systemctl start name.service
     |
     |
1.2.6  自启一项服务
    为了是Apache HTTP 服务器在开机时自启,可以用root用户运行如下命令
    systemctl enable httpd.service
    ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'    
1.2.7  取消服务开机自启
    systemctl disable name.service
    该命令会把/usr/lib/systemd/system/name.service在/etc/systemd/system/文件夹以及其子文件夹中的链接删除。此外,你还可以通过mask来掩蔽一项服务,从而使其不能自启或由其它服务启动:
    systemctl mask name.service
    该命令会把/etc/systemd/system/name.service这一文件替换为指向/dev/null的链接,若想取消:
   systemctl unmask name.service
    
1.3  Systemd targets
    systemd targets通过target units代表,其具有.target后缀,target存在的唯一目的就是通过一系列依赖性集合其它的systemd units。例如,graphical.target unit就是用来开启图形会话,启动诸如gdm.service,accounts-daemon.service的服务,且激活multi-user.target unit
    runlevel0.target,poweroff.target                  关机
    runlevel1.target,rescue.target                    拯救模式,单用户模式
    runlevel2.target,multi-user.target                字符界面多用户
    runlevel3.target,multi-user.target                字符界面多用户
    runlevel4.target,multi-user.target                字符界面多用户
    runlevel5.target,graphical.target                图形界面多用户
    runlevel6.target,reboot.target                    重启

1.3.1 查看默认target
    systemctl get-default
    该命令查看/etc/systemd/system/default.target这一链接指向。
1.3.2 查看目前target
    以下命令查看当前系统加载的target units:
    systemctl list-units --type target    
1.3.3 改变默认target
    systemctl set-default name.target
1.3.4 改变目前target
    systemctl isolate name.target
            这一命令会启动name.target需要的所有服务,并终止所有不需要的服务。
        1.3.5 改变到拯救模式
            systemctl rescue
            这一命令与systemctl isolate rescue.target基本相同,但是它会向目前登陆用户发送信息,要想阻止信息发送,可以用如下命令:
            systemctl --no-wall rescue
        1.3.6 改变到救急模式
            systemctl emergency
            与拯救模式类似,也会在进入前向登陆用户发送信息,也可以通过以下方式阻止信息发送:
            systemctl --no-wall emergency
    1.4  关机、休眠、睡眠
        systemctl halt            关机
        systemctl poweroff        关机断电
        systemctl reboot        重启
        systemctl suspend        挂起
        systemctl hibernate        休眠
        systemctl hybrid-sleep    休眠并挂起
    shutdown命令:
        为了在一个特定的时间关机并对机器断电,可以用如下格式的命令:
            shutdown --poweroff hh:mm (hh:mm为24小时制时间格式)
        当然也可以用:
            shutdown --poweroff +m     在m分钟后关机
        如果想要取消关机,可以用:
            shutdown -c    
    1.5  在远程设备上操控systemd
        除了可以在本机对systemd系统进行控制外,其还允许你通过SSH协议连接到远程电脑上进行操控。但是远程主机必须得运行sshd服务,你可以通过如下命令连接到该主机上:
            systemctl --host user_name@host_name command
        除了前面部分需要加上--host user_name@host_name外,command是相同的
    1.6  创建、修改Systemd unit文件
        Unit file具有如下形式:
            unit_name.type_extension
        文件结构: [Unit]        描述与unit类型无关的信息、对其它units的依赖
                   [unit type]   关于该unit类型的指引
                   [Install]     包含systemctl安装命令(enable/disable)
            [Unit] Section:
                Description      针对该unit的描述,该段文字会在systemctl status命令中显示
                Documentation     提供关于该unit的帮助文档URIs
                After             定义unit启动顺序,该unit会在该字段定义的unit启动后才启动
                Requires         配置依赖的服务,这里列出的unit会同时启动
                Wants             要求比Requires要若
                Conflicts         冲突的units
            [Service] Section:
                Type    
                    simple  默认值;
                    forking 该进程启动后会产生一个子程序并成为服务的主进程,父进程随之退出
                    oneshot    与simple相似,但是该进程会在后面的unit启动前关闭
                    dbus    
                    notify  随后的units仅会在sd_notify()发送通知信息后启动
                    idle
                ExecStart    指定unit启动后执行的命令或脚本
                ExecStop    指定unit结束后执行的命令或脚本
                ExecReload    指定unit重启后执行的命令或脚本
                Restart        当该项enabled,则当进程退出后会重启,当然通过systemctl命令停止并不会重启
                RemainAfterExit        如果为True,当它退出后仍会认为是活动的;默认值为false,该字段对Type=oneshot很有用
            [Install] Section
                Alias        提供该unit的别名,不同别名通过空格间隔
                RequiredBy    依赖该unit的units
                WantedBy    弱依赖units
                Also        指定会随同该unit安装或卸载的units                    
        1.6.2 创建自定义unit文件
            (1)准备一个可执行的自定义服务,可以是一个脚本也可以是一个可执行程序。如果必须的话,准备一个包含该服务PID的PID文件。也可能会需要environment文件来储存该服务用到的shell变量。并确认该脚本是可执行的(chmod a+x)并且是非交互的。
            (2)在/etc/systemd/system/文件夹下创建一个unit文件,并确认文件权限是正确的:
                    touch /etc/systemd/system/name.service
                    chmod 664 /etc/systemd/system/name.service
             (3) 打开该name.service文件并加入配置选项。下面是一个网络相关的服务的例子:
                    [Unit]
                    Description=service_description
                    After=network.target
                    
                    [Service]
                    ExecStart=path_to_executable
                    Type=forking
                    PIDFile=path_to_pidfile

                    [Install]
                    WantedBy=default.target
             (4) 通知systemd有一个新的name.service文件存在,运行如下命令:
                    systemctl daemon-reload
                    systemctl start name.service
        1.6.3 把SysV Init脚本转变为unit文件
            需要作复杂的变换:找到服务描述、服务依赖、默认target、服务所用到的文件,这些过程比较复杂,需要对启动脚本中的目的明确才行。
        1.6.4 修改现有的unit文件
            安装的服务的默认unit文件一般储存在/usr/lib/systemd/system/文件夹下,系统管理员不应该直接修改这些文件;任何自定义都要在/etc/systemd/system/文件夹下进行,根据所需要修改的程序,选择以下方法中的一种即可:
                > 在/etc/systemd/system/unit.d/下建立一个文件夹,这也是对大多数情况建议使用的方法。这种方法允许对默认配置增加额外的功能,而且能够保持原来的unit文件。
                > 在/etc/systemd/system下拷贝/usr/lib/systemd/system中初始的unit文件。这一拷贝将会覆盖初始配置,因此软件包更新的配置并不能自动更新进来。这种方法经常用在对配置需要做永久的改动,而不论软件包是否更新。
            如果想要复原默认配置,那么只需要删除以上创建的配置文件,而后重启系统或者运行如下命令即可:
                systemctl daemon-reload
            daemon-reload选项会重新加载所有的unit文件并重新生成依赖树,你也可以利用如下方法达到同样效果:
                init q
            同样,如果修改的unit文件属于一个正在运行的服务,那么服务必须重启才能接受新的设置:
                systemctl restart name.service
        · 拓展默认unit配置:
            为了对默认的unit文件增加一些额外的选项,首先需要在/etc/systemd/system/下创建配置文件夹:
                mkdir /etc/systemd/system/name.service.d
            在上面的目录中新建配置文件,记住文件后缀必须为.conf
                touch /etc/systemd/system/name.service.d/config_name.conf
            然后在该文件中在相应的字段中加入配置即可。为了是修改生效,需要执行:
                systemctl daemon-reload
                systemctl restart name.service
        · 重写默认unit配置:
            为了要对软件包的配置作持久的更改,需要把unit文件拷贝到/etc/systemd/system/目录下:
                cp /usr/lib/systemd/system/name.service /etc/systemd/system/name.service
            然后对拷贝的文件做出需要的修改。之后运行:
                systemctl daemon-reload
                systemctl restart name.service
                

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多