Linux – Systemd Unit Files

Loading

以前會把需要在開機後執行的指令寫在 /etc/rc.local ,但在 CentOS7 / CentOS 8 會發現系統不會去執行該檔案的內容.需要設定後才會去執行,詳細方式請參考 https://benjr.tw/102545

另外一個方式就是自己寫 Systemd Unit Files. 參考文章 – https://www.redhat.com/sysadmin/replacing-rclocal-systemd

測試環境 CentOS 8 x86_64 (虛擬機)

先編輯要執行的程式,以下範例使用 .sh (Bash) 檔案,裡面指令為新增一筆 Routing Table (正統的作法是新增網卡的 Routing 檔案 /etc/sysconfig/network-scripts/route-ifname ,詳細方式請參考 – https://benjr.tw/102607 ).

[root@localhost ~]# vi /usr/local/bin/route.sh
#!/bin/bash
route add -net 172.16.0.0 netmask 255.255.255.0 gw 192.168.111.161

需修改其執行權限 chmod a+x (Execute)

[root@localhost ~]# chmod a+x /usr/local/bin/route.sh
[root@localhost ~]# ll /usr/local/bin/route.sh
-rwxr-xr-x 1 root root 76 Feb  7 19:24 /usr/local/bin/route.sh

可以先確定一下執行沒有問題.

[root@localhost ~]# /usr/local/bin/route.sh
[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    100    0        0 ens33
172.16.0.0      localhost.local 255.255.255.0   UG    0      0        0 ens33
192.168.111.0   0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

編輯 Systemd Unit Files.

[root@localhost ~]# vi /usr/lib/systemd/system/route.service
[Unit]
Description=Runs /usr/local/bin/route.sh
Requires=network-online.target
After=network-online.target

[Service]
Type=forking
ExecStart=/usr/local/bin/route.sh

[Install]
WantedBy=multi-user.target

只簡單設定3個區塊

  1. [unit]
    Description=Runs /usr/local/bin/route.sh
    Requires=network-online.target
    After=network-online.target
    

    Description 敘述該 Systemd Unit Files 目的與其運行的先後順序.
    先來看一下 Wants 與 Requires 的差別如下:

    • Wants
      unit1 敘述中有 Wants=unit2 時,表示運行 unit1 時,也會同時運行 unit2 , 但是 unit2 是否成功啟動並不會影響 unit1 的成功運行.
    • Requires
      unit1 敘述中有 Requires=unit2 時,表示運行 unit1 時,也會同時運行 unit2 , 但如果 unit2 不成功,則 unit1 也將被停用 (無論 unit1 是否正常運行)

    在來看一下 After 與 Before 的差別如下:

    • After
      unit1 敘述中有 After=unit2 時,表示會先運行 unit2 完成後才會運行 unit1 .
    • Before
      unit1 敘述中有 Before=unit2 ,表示會先運行 unit1 完成後才會運行 unit2 .

    透過下面的指令可以查出其 Unit 的 After 與 Before.

    [root@localhost ~]# systemctl list-dependencies --before network-online.target
    network-online.target
    ● ├─dnf-makecache.service
    ● ├─kdump.service
    ● ├─nfs-mountd.service
    ● ├─nfs-server.service
    ● ├─route.service
    ● ├─rpc-statd-notify.service
    ● ├─rpc-statd.service
    ● ├─rsyslog.service
    ● └─shutdown.target
    
  2. [Service]
    Type=forking
    ExecStart=/usr/local/bin/route.sh
    

    Type=forking – The process started with ExecStart spawns a child process that becomes the main process of the service.
    ExecStart – 指定執行程式.

  3. [Install] WantedBy 指定哪一個 runlevel 執行,或是在哪一個 unit 服務後執行.
    WantedBy=multi-user.target
    

其他更多設定請參考 – https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/assembly_working-with-systemd-unit-files_configuring-basic-system-settings#tabl-systemd-Unit_Sec_Options

編輯設定檔後就可以直接執行 #systemctl enable (開機時啟動), start (立即啟動) route ,更多關於 systemctl 請參考 – https://benjr.tw/94315 .

[root@localhost ~]# systemctl enable route
Created symlink /etc/systemd/system/multi-user.target.wants/route.service → /usr/lib/systemd/system/route.service.
[root@localhost ~]# systemctl start route
[root@localhost ~]# systemctl status route
● route.service - Runs /usr/local/bin/route.sh
   Loaded: loaded (/usr/lib/systemd/system/route.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Fri 2020-02-07 19:30:11 CST; 2s ago
  Process: 2560 ExecStart=/usr/local/bin/route.sh (code=exited, status=0/SUCCESS)
 Main PID: 2560 (code=exited, status=0/SUCCESS)

Feb 07 19:30:11 localhost.localdomain systemd[1]: Started Runs /usr/local/bin/route.sh.

剛剛已經執行過 /usr/local/bin/route.sh 所以 Routing Table 一樣,下次重新開機注意一下,可以看到的確有多一筆 172.16.0.0 的 Routing Table.

[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         _gateway        0.0.0.0         UG    100    0        0 ens33
172.16.0.0      localhost.local 255.255.255.0   UG    0      0        0 ens33
192.168.111.0   0.0.0.0         255.255.255.0   U     100    0        0 ens33
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

常見問題

需注意 Systemd Unit Files 的 Requires 與 After 需設定為 network-online.target ,請參考前面的設定.

[root@localhost ~]# systemctl status route
● route.service - Runs /usr/local/bin/route.sh
   Loaded: loaded (/usr/lib/systemd/system/route.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Fri 2020-03-06 01:04:20 CST; 39s ago
  Process: 972 ExecStart=/usr/local/bin/route.sh (code=exited, status=7)

Mar 06 01:04:20 localhost.localdomain systemd[1]: Starting Runs /usr/local/bin/route.sh...
Mar 06 01:04:20 localhost.localdomain route.sh[972]: SIOCADDRT: Network is unreachable
Mar 06 01:04:20 localhost.localdomain systemd[1]: route.service: Control process exited, code=exited status=7
Mar 06 01:04:20 localhost.localdomain systemd[1]: route.service: Failed with result 'exit-code'.
Mar 06 01:04:20 localhost.localdomain systemd[1]: Failed to start Runs /usr/local/bin/route.sh.
沒有解決問題,試試搜尋本站其他內容

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料