Systemctl là gì? Hướng dẫn sử dụng systemctl để quản lý dịch vụ systemd trên Linux

Systemctl là gì? Hướng dẫn sử dụng systemctl để quản lý dịch vụ systemd trên Linux

Systemd là hệ thống init và quản lý hệ thống tiên tiến, hiện đã trở thành tiêu chuẩn mới trên nhiều bản phân phối Linux. Với sự phổ biến rộng rãi này, việc làm quen với systemd là một khoản đầu tư thời gian đáng giá, vì nó giúp đơn giản hóa đáng kể công việc quản trị máy chủ. Khi hiểu và sử dụng thành thạo các công cụ và daemon cấu thành nên systemd, bạn sẽ nhanh chóng nhận ra sức mạnh, tính linh hoạt cũng như các khả năng ưu việt của nó – hoặc ít nhất là giúp cho công việc quản trị trở nên nhẹ nhàng hơn.

Trong hướng dẫn này, chúng ta sẽ tập trung khám phá lệnh systemctl – công cụ trung tâm để điều khiển hệ thống init. Bạn sẽ được hướng dẫn cách quản lý dịch vụ, kiểm tra trạng thái, thay đổi trạng thái hệ thống cũng như thao tác với các tệp cấu hình một cách hiệu quả.

Lưu ý rằng mặc dù systemd hiện là hệ thống init mặc định của rất nhiều bản phân phối Linux, nhưng không phải distro nào cũng triển khai nó theo cùng một cách. Nếu bạn nhận được thông báo lỗi “bash: systemctl is not installed” khi chạy lệnh trong terminal, điều đó có thể cho thấy máy của bạn đang sử dụng một hệ thống init khác.

Quản lý dịch vụ

Mục đích cơ bản của hệ thống init là khởi tạo các thành phần cần được bắt đầu sau khi Linux kernel khởi động (truyền thống được gọi là các thành phần “userland”). Hệ thống init cũng được dùng để quản lý các dịch vụ và daemon của máy chủ trong suốt thời gian hoạt động của hệ thống. Với điều này, chúng ta sẽ bắt đầu với một số thao tác quản lý dịch vụ cơ bản.

Trong systemd, mục tiêu của hầu hết các thao tác là “đơn vị” (unit), là các tài nguyên mà systemd biết cách quản lý. Các đơn vị được phân loại theo loại tài nguyên mà chúng đại diện và được định nghĩa thông qua các tệp cấu hình gọi là unit files. Loại của mỗi đơn vị có thể được suy ra từ hậu tố của tệp.

Đối với các tác vụ quản lý dịch vụ, mục tiêu sẽ là các đơn vị dịch vụ, có unit file với hậu tố .service. Tuy nhiên, đối với hầu hết các lệnh quản lý dịch vụ, bạn có thể bỏ qua hậu tố .service vì systemd tự động hiểu rằng bạn muốn thao tác trên một dịch vụ.

Khởi động và dừng dịch vụ

Để khởi động một dịch vụ systemd (thực thi các lệnh trong unit file của dịch vụ đó), dùng lệnh start. Nếu bạn không chạy với quyền root, hãy sử dụng sudo vì thao tác này ảnh hưởng đến trạng thái của hệ điều hành:

sudo systemctl start application.service

Như đã đề cập, systemd sẽ tìm các tệp .service cho các lệnh quản lý dịch vụ, vì vậy lệnh có thể được nhập như sau:

sudo systemctl start application

Mặc dù bạn có thể dùng cách trên cho quản trị chung, để rõ ràng hơn, chúng ta sẽ dùng hậu tố .service cho các lệnh còn lại, nhằm chỉ định rõ đối tượng cần thao tác.

Để dừng một dịch vụ đang chạy, sử dụng lệnh stop:

sudo systemctl stop application.service

Khởi động lại và tải lại cấu hình

Để khởi động lại một dịch vụ đang chạy, sử dụng lệnh restart:

sudo systemctl restart application.service

Nếu ứng dụng có khả năng tải lại tệp cấu hình (mà không cần khởi động lại hoàn toàn), bạn có thể dùng lệnh reload để kích hoạt quá trình đó:

sudo systemctl reload application.service

Nếu bạn không chắc chắn dịch vụ có hỗ trợ tải lại cấu hình hay không, bạn có thể dùng lệnh reload-or-restart. Lệnh này sẽ tải lại cấu hình nếu có thể; nếu không, nó sẽ khởi động lại dịch vụ để áp dụng cấu hình mới:

sudo systemctl reload-or-restart application.service

Kích hoạt và vô hiệu hóa dịch vụ

Các lệnh trên hữu ích để khởi động hoặc dừng dịch vụ trong phiên hiện tại. Để yêu cầu systemd tự động khởi động dịch vụ khi máy chủ khởi động, bạn phải kích hoạt dịch vụ đó.

Để kích hoạt một dịch vụ khởi động cùng hệ thống, dùng lệnh enable:

sudo systemctl enable application.service

Lệnh này sẽ tạo một symbolic link từ bản sao tệp dịch vụ của hệ thống (thường nằm trong /lib/systemd/system hoặc /etc/systemd/system) vào vị trí mà systemd tìm kiếm các tệp autostart (thường là /etc/systemd/system/some_target.target.wants). (Chúng ta sẽ bàn về target sau.)

Để vô hiệu hóa dịch vụ khỏi việc tự động khởi động, dùng lệnh:

sudo systemctl disable application.service

Lệnh này sẽ xóa liên kết biểu tượng chỉ ra rằng dịch vụ nên được khởi động tự động.

Xin lưu ý rằng việc kích hoạt một dịch vụ không tự động khởi động nó trong phiên hiện tại. Nếu bạn muốn khởi động dịch vụ và kích hoạt nó cùng lúc, bạn cần chạy cả lệnh start và enable.

Kiểm tra trạng thái của dịch vụ

Để kiểm tra trạng thái của một dịch vụ trên hệ thống, dùng lệnh status:

systemctl status application.service

Lệnh này sẽ cung cấp cho bạn trạng thái dịch vụ, cấu trúc cgroup, và vài dòng nhật ký đầu tiên. Ví dụ, khi kiểm tra trạng thái của một máy chủ Nginx, bạn có thể thấy output như sau:

output

● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 Main PID: 495 (nginx)
   CGroup: /system.slice/nginx.service
           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
           └─496 nginx: worker process
Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

Output này cung cấp một cái nhìn tổng quan về trạng thái hiện tại của ứng dụng, báo cho bạn biết nếu có sự cố và các hành động cần thực hiện.

Kiểm tra trạng thái cụ thể

Có một số phương pháp để kiểm tra trạng thái cụ thể của một đơn vị. Ví dụ, để kiểm tra xem một đơn vị có đang hoạt động (running) hay không, dùng lệnh is-active:

systemctl is-active application.service

Lệnh này sẽ trả về trạng thái hiện tại của đơn vị (thường là active hoặc inactive). Mã exit sẽ là “0” nếu đơn vị đang active, giúp kết quả dễ kiểm tra trong shell scripts.

Để kiểm tra xem đơn vị có được kích hoạt (enabled) hay không, dùng lệnh is-enabled:

systemctl is-enabled application.service

Lệnh này sẽ xuất ra trạng thái của dịch vụ (enabled hoặc disabled) và mã exit sẽ là “0” hoặc “1” tùy theo kết quả.

Một kiểm tra thứ ba là kiểm tra xem đơn vị có bị lỗi (failed) hay không. Điều này cho biết đã có vấn đề khi khởi động đơn vị:

systemctl is-failed application.service

Lệnh này sẽ trả về active nếu hoạt động bình thường hoặc failed nếu có lỗi. Nếu đơn vị đã bị dừng theo chủ ý, có thể trả về unknown hoặc inactive. Mã exit “0” chỉ ra có lỗi xảy ra và “1” cho các trạng thái khác.

Tổng quan trạng thái hệ thống

Những lệnh trên hữu ích để quản lý dịch vụ đơn lẻ, nhưng không giúp bạn khám phá trạng thái tổng quát của hệ thống. Có một số lệnh systemctl khác cung cấp thông tin này.

Liệt kê các đơn vị hiện hoạt

Để xem danh sách tất cả các đơn vị (units) đang hoạt động mà systemd biết, dùng lệnh list-units:

systemctl list-units

Lệnh này sẽ hiển thị danh sách các đơn vị hiện đang được systemd kích hoạt trên hệ thống. Output sẽ có dạng như sau:

output

UNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
atd.service                               loaded active running ATD daemon
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
dbus.service                              loaded active running D-Bus System Message Bus
dcron.service                             loaded active running Periodic Command Scheduler
dkms.service                              loaded active exited  Dynamic Kernel Modules System
getty@tty1.service                        loaded active running Getty on tty1
. . .

Các cột hiển thị bao gồm:

  • UNIT: Tên đơn vị của systemd.
  • LOAD: Cho biết cấu hình của đơn vị đã được systemd phân tích chưa.
  • ACTIVE: Tóm tắt trạng thái đơn vị (thường cho biết liệu đơn vị có khởi động thành công hay không).
  • SUB: Trạng thái chi tiết hơn của đơn vị, tùy thuộc vào loại và cách thức hoạt động của nó.
  • DESCRIPTION: Mô tả ngắn gọn về đơn vị.

Lệnh list-units chỉ hiển thị các đơn vị đang active theo mặc định. Bạn cũng có thể gọi lệnh systemctl không có đối số để có cùng kết quả:

systemctl

Để xem tất cả các đơn vị mà systemd đã tải (bao gồm cả các đơn vị không active), dùng thêm tham số –all:

systemctl list-units --all

Bạn có thể dùng thêm tham số –state= để chỉ định trạng thái LOAD, ACTIVE, hoặc SUB mà bạn muốn hiển thị. Hãy giữ tham số –all để hiển thị các đơn vị không active:

systemctl list-units --all --state=inactive

Một bộ lọc khác là tham số –type=. Ví dụ, để chỉ hiển thị các đơn vị dịch vụ active, dùng:

systemctl list-units --type=service

Liệt kê tất cả các tệp đơn vị

Lệnh list-units chỉ hiển thị các đơn vị mà systemd đã tải vào bộ nhớ. Để xem tất cả các tệp unit có sẵn trên hệ thống (bao gồm cả những tệp chưa được systemd tải), dùng lệnh list-unit-files:

systemctl list-unit-files

Output sẽ có hai cột: tên tệp unit và trạng thái của nó.

output

UNIT FILE                                  STATE
proc-sys-fs-binfmt_misc.automount          static
dev-hugepages.mount                        static
dev-mqueue.mount                           static
proc-fs-nfsd.mount                         static
proc-sys-fs-binfmt_misc.mount              static
sys-fs-fuse-connections.mount              static
sys-kernel-config.mount                    static
sys-kernel-debug.mount                     static
tmp.mount                                  static
var-lib-nfs-rpc_pipefs.mount               static
org.cups.cupsd.path                        enabled
. . .

Trạng thái thường là enabled, disabled, static, hoặc masked. Ở đây, static có nghĩa là tệp unit không chứa phần install (vì vậy không thể kích hoạt). Điều này thường có nghĩa là đơn vị chỉ thực hiện một hành động một lần hoặc chỉ dùng làm phụ thuộc của đơn vị khác và không được chạy độc lập.

Quản lý đơn vị

Chúng ta đã làm việc với dịch vụ và hiển thị thông tin về các đơn vị và tệp unit mà systemd biết đến. Tuy nhiên, bạn cũng có thể tìm hiểu thêm thông tin chi tiết về các đơn vị bằng một số lệnh khác.

Hiển thị tệp đơn vị

Để hiển thị tệp đơn vị mà systemd đã tải vào bộ nhớ, bạn có thể dùng lệnh cat (được thêm vào từ systemd phiên bản 209). Ví dụ, để xem tệp đơn vị của daemon atd, chạy:

systemctl cat atd.service

Ouput

[Unit]
Description=ATD daemon
[Service]
Type=forking
ExecStart=/usr/bin/atd
[Install]
WantedBy=multi-user.target

Tệp output trên là tệp unit như được systemd nạp vào bộ nhớ. Điều này quan trọng nếu bạn vừa mới chỉnh sửa tệp unit hoặc ghi đè một số tùy chọn trong phần cấu hình bổ sung (chúng ta sẽ bàn về điều này sau).

Hiển thị các phụ thuộc của đơn vị

Để xem cây phụ thuộc của một đơn vị, bạn có thể dùng lệnh list-dependencies. Ví dụ, để xem các phụ thuộc của sshd.service:

systemctl list-dependencies sshd.service

Lệnh này sẽ hiển thị một cấu trúc cây của các đơn vị mà đơn vị được chỉ định phụ thuộc vào để có thể khởi động. Các phụ thuộc bao gồm các đơn vị được yêu cầu hoặc được mong muốn bởi các đơn vị ở trên.

Ouput

sshd.service
├─system.slice
└─basic.target
  ├─microcode.service
  ├─rhel-autorelabel-mark.service
  ├─rhel-autorelabel.service
  ├─rhel-configure.service
  ├─rhel-dmesg.service
  ├─rhel-loadmodules.service
  ├─paths.target
  ├─slices.target
. . .

Các phụ thuộc đệ quy chỉ được hiển thị đối với các đơn vị có hậu tố .target, biểu thị trạng thái của hệ thống. Để liệt kê đệ quy tất cả các phụ thuộc, bạn có thể thêm tham số –all.

Để hiển thị các phụ thuộc ngược (các đơn vị phụ thuộc vào đơn vị được chỉ định), thêm tham số –reverse. Các tham số –before và –after cũng hữu ích để hiển thị các đơn vị phụ thuộc vào đơn vị được chỉ định theo thứ tự trước và sau.

Kiểm tra thuộc tính của đơn vị

Để xem các thuộc tính chi tiết của một đơn vị, bạn có thể dùng lệnh show. Lệnh này hiển thị danh sách các thuộc tính của đơn vị theo định dạng key=value:

systemctl show sshd.service

Output

Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .

Nếu bạn chỉ muốn hiển thị một thuộc tính cụ thể, dùng tham số -p với tên thuộc tính. Ví dụ, để xem các thuộc tính xung đột của sshd.service, chạy:

systemctl show sshd.service -p Conflicts

Output

Conflicts=shutdown.target

Ẩn/Hiện đơn vị (Masking và Unmasking)

Chúng ta đã thấy trong phần quản lý dịch vụ cách dừng hoặc vô hiệu hóa một dịch vụ. Tuy nhiên, systemd còn có khả năng đánh dấu một đơn vị là không thể khởi động (một cách tự động hoặc thủ công) bằng cách liên kết nó với /dev/null. Điều này gọi là “masking” đơn vị và được thực hiện bằng lệnh mask:

sudo systemctl mask nginx.service

Lệnh này sẽ ngăn chặn dịch vụ Nginx khởi động, dù tự động hay thủ công, trong thời gian nó bị đánh dấu. Nếu bạn liệt kê tệp đơn vị, bạn sẽ thấy dịch vụ được liệt kê với trạng thái masked:

systemctl list-unit-files

output

. . .
kmod-static-nodes.service              static
ldconfig.service                       static
mandb.service                          static
messagebus.service                     static
nginx.service                          masked
quotaon.service                        static
rc-local.service                       static
rdisc.service                          disabled
rescue.service                         static
. . .

Nếu bạn cố gắng khởi động dịch vụ, bạn sẽ nhận được thông báo:

sudo systemctl start nginx.service

output

Failed to start nginx.service: Unit nginx.service is masked.

Để bỏ mask (unmask) một đơn vị, dùng lệnh:

sudo systemctl unmask nginx.service

Lệnh này sẽ khôi phục trạng thái của đơn vị, cho phép nó được khởi động hoặc kích hoạt.

Chỉnh sửa tệp đơn vị

Mặc dù định dạng cụ thể của tệp đơn vị nằm ngoài phạm vi hướng dẫn này, systemctl cung cấp các cơ chế tích hợp để chỉnh sửa và thay đổi tệp đơn vị nếu bạn cần điều chỉnh. Tính năng này được thêm vào từ systemd phiên bản 218.

Lệnh edit, theo mặc định, sẽ mở một đoạn tệp cấu hình (snippet) cho đơn vị được chỉ định:

sudo systemctl edit nginx.service

Lệnh này sẽ mở một tệp trống dùng để ghi đè hoặc thêm chỉ thị vào định nghĩa của đơn vị. Một thư mục sẽ được tạo trong /etc/systemd/system với tên của đơn vị có hậu tố .d (ví dụ: với nginx.service, thư mục nginx.service.d sẽ được tạo).

Bên trong thư mục này, một tệp snippet tên là override.conf sẽ được tạo. Khi đơn vị được nạp, systemd sẽ hợp nhất nội dung của override.conf với tệp đơn vị gốc, và các chỉ thị trong snippet sẽ có ưu tiên cao hơn.

Nếu bạn muốn chỉnh sửa toàn bộ tệp đơn vị thay vì tạo snippet, bạn có thể dùng tham số –full:

sudo systemctl edit --full nginx.service

Lệnh này sẽ nạp tệp đơn vị hiện tại vào trình soạn thảo để bạn chỉnh sửa. Khi trình soạn thảo thoát, tệp đã thay đổi sẽ được ghi vào /etc/systemd/system, và nó sẽ có ưu tiên so với định nghĩa gốc của hệ thống (thường nằm trong /lib/systemd/system).

Để xóa bất kỳ thay đổi nào bạn đã thực hiện, bạn có thể xóa thư mục cấu hình .d của đơn vị hoặc xóa tệp dịch vụ đã chỉnh sửa khỏi /etc/systemd/system. Ví dụ, để xóa một snippet:

sudo rm -r /etc/systemd/system/nginx.service.d

Để xóa tệp dịch vụ đã chỉnh sửa hoàn toàn:

sudo rm /etc/systemd/system/nginx.service

Sau khi xóa, hãy tải lại quy trình systemd để hệ thống không tham chiếu đến các tệp đã xóa và quay trở lại sử dụng tệp hệ thống:

sudo systemctl daemon-reload

Điều chỉnh trạng thái hệ thống (Runlevel) với targets

Targets là các tệp đơn vị đặc biệt mô tả một trạng thái hệ thống hoặc điểm đồng bộ. Giống như các đơn vị khác, các tệp định nghĩa target được nhận dạng qua hậu tố .target. Targets không thực hiện nhiều hành động tự thân, mà được sử dụng để nhóm các đơn vị khác lại với nhau.

Điều này cho phép bạn đưa hệ thống vào các trạng thái nhất định, giống như các runlevel trong hệ thống init khác. Targets được dùng làm tham chiếu cho các chức năng khi nào sẵn sàng, cho phép bạn chỉ định trạng thái mong muốn thay vì liệt kê các đơn vị riêng lẻ cần thiết.

Ví dụ, có target swap.target được dùng để chỉ ra rằng swap đã sẵn sàng. Các đơn vị liên quan sẽ đồng bộ với target này bằng cách sử dụng các chỉ thị WantedBy= hoặc RequiredBy=. Các đơn vị yêu cầu swap có thể chỉ định điều kiện này bằng các chỉ thị Wants=, Requires=, và After=.

Lấy và thiết lập target mặc định

Quy trình systemd có một target mặc định được sử dụng khi khởi động hệ thống. Việc thỏa mãn chuỗi phụ thuộc từ target đó sẽ đưa hệ thống vào trạng thái mong muốn. Để tìm target mặc định của hệ thống, chạy:

systemctl get-default

output

multi-user.target

Nếu bạn muốn thiết lập target mặc định khác, dùng lệnh set-default. Ví dụ, nếu bạn cài đặt giao diện đồ họa và muốn hệ thống khởi động vào giao diện đồ họa theo mặc định, chạy:

sudo systemctl set-default graphical.target

Liệt kê các target có sẵn

Để xem danh sách các target có sẵn trên hệ thống, chạy:

systemctl list-unit-files --type=target

Khác với runlevels, nhiều target có thể được kích hoạt cùng lúc. Một target active cho biết systemd đã cố gắng khởi động tất cả các đơn vị liên quan và không hủy chúng. Để xem tất cả target active, chạy:

systemctl list-units --type=target

Isolating Targets

Bạn có thể khởi động tất cả các đơn vị liên quan tới một target và dừng tất cả các đơn vị không thuộc cây phụ thuộc đó. Lệnh để thực hiện điều này là isolate – tương tự như thay đổi runlevel trong các hệ thống init khác.

Ví dụ, nếu hệ thống đang ở chế độ đồ họa với target graphical.target active, bạn có thể tắt giao diện đồ họa và đưa hệ thống vào trạng thái đa người dùng (multi-user) bằng cách cô lập multi-user.target. Vì graphical.target phụ thuộc vào multi-user.target nhưng không ngược lại, nên tất cả các đơn vị đồ họa sẽ bị dừng lại.

Trước khi thực hiện, hãy xem phụ thuộc của target cần cô lập để đảm bảo bạn không dừng nhầm các dịch vụ quan trọng:

systemctl list-dependencies multi-user.target

Khi đã hài lòng với các đơn vị sẽ được giữ lại, cô lập target bằng lệnh:

sudo systemctl isolate multi-user.target

Sử dụng phím tắt cho các sự kiện quan trọng

Có các target được định nghĩa cho các sự kiện quan trọng như tắt nguồn hoặc khởi động lại. Tuy nhiên, systemctl cũng có các phím tắt bổ sung.

Ví dụ, để đưa hệ thống vào chế độ rescue (single-user), bạn có thể dùng lệnh rescue thay vì isolate rescue.target:

sudo systemctl rescue

Lệnh này sẽ thông báo cho tất cả người dùng đang đăng nhập biết rằng sự kiện đang xảy ra.

Để dừng hệ thống, dùng lệnh:

sudo systemctl halt

Để tắt hoàn toàn hệ thống, dùng lệnh:

sudo systemctl poweroff

Để khởi động lại hệ thống, dùng lệnh:

sudo systemctl reboot

Những lệnh này sẽ thông báo cho tất cả người dùng biết rằng sự kiện đang xảy ra, điều mà việc chỉ chạy hoặc cô lập target không làm được. Lưu ý rằng hầu hết các máy sẽ liên kết các lệnh ngắn gọn truyền thống này để chúng hoạt động chính xác với systemd. Ví dụ, để khởi động lại, bạn thường chỉ cần gõ:

sudo reboot

Kết luận

Bây giờ, bạn đã nắm bắt được những chức năng cơ bản của lệnh systemctl, cho phép bạn tương tác và kiểm soát instance systemd một cách hiệu quả. Systemctl chính là công cụ giao tiếp cốt lõi để quản lý dịch vụ và trạng thái hệ thống.

Mặc dù systemctl tập trung chủ yếu vào việc điều khiển quá trình cốt lõi của systemd, hệ sinh thái systemd còn bao gồm nhiều thành phần khác được quản lý thông qua các tiện ích chuyên biệt. Ví dụ, quản lý nhật ký hệ thống và phiên người dùng được đảm nhận bởi các daemon và công cụ riêng như journald/journalctl và logind/loginctl. Đầu tư thời gian làm quen với các công cụ này sẽ giúp bạn nâng cao khả năng quản trị hệ thống, tối ưu hóa hiệu quả làm việc và đảm bảo hệ thống vận hành trơn tru.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *