以前會把需要在開機後執行的指令寫在 /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個區塊
- [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
- Wants
- [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 – 指定執行程式. - [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.