Thứ sáu, 04/09/2015 | 00:00 GMT+7

Cách cấu hình dịch vụ Linux để khởi động tự động sau khi gặp sự cố hoặc khởi động lại - Phần 2: Tham khảo

Trong phần thứ hai này của hướng dẫn về cách khởi động các dịch vụ Linux tự động, ta sẽ lùi lại một bước và giải thích các quy trình init chi tiết hơn. Bạn nên hiểu rõ về cách chúng kiểm soát hành vi khởi động của daemon.

Trong phần đầu tiên của loạt bài hướng dẫn này, ta đã chia sẻ một số ví dụ thực tế sử dụng MySQL để biết cách bật dịch vụ Linux tự động khởi động sau khi gặp sự cố hoặc khởi động lại.

Ta đã thấy cách thực hiện việc này từ ba chế độ init khác nhau: System V, Upstart và systemd. Đọc hướng dẫn đầu tiên để biết thêm về bản phân phối sử dụng hệ thống init nào theo mặc định.

Trong hướng dẫn này, ta sẽ quay lại một bước và giải thích lý do tại sao ta chạy các lệnh và chỉnh sửa các file cấu hình mà ta đã làm. Ta sẽ bắt đầu với daemon System V init. Ta cũng sẽ thấy lý do tại sao nó được thay thế theo thời gian bằng các chế độ init mới hơn.

Yêu cầu

Để làm theo hướng dẫn này, bạn cần ba server DigitalOcean mà bạn đã tạo trước đó .

Ta đã có:

  • Server Debian 6 chạy MySQL
  • Server Ubuntu 14.04 chạy MySQL
  • Server CentOS 7 chạy MySQL

Ta khuyên bạn nên quay lại Phần 1 của loạt bài này và tạo các Server trước.

Ngoài ra, bạn cần phải là user root hoặc có quyền sudo trên server . Để hiểu cách hoạt động của các quyền sudo, hãy xem hướng dẫn DigitalOcean này về sudo .

Bạn không nên chạy bất kỳ lệnh, truy vấn hoặc cấu hình nào từ hướng dẫn này trên server Linux production .

Runlevels

Runlevel đại diện cho trạng thái hiện tại của hệ thống Linux.

Khái niệm này xuất phát từ System V init, nơi hệ thống Linux khởi động, khởi tạo kernel , sau đó nhập một (và chỉ một) runlevel.

Ví dụ: runlevel có thể là trạng thái tắt của server Linux, chế độ một user , chế độ khởi động lại, v.v. Mỗi chế độ sẽ quy định dịch vụ nào có thể đang chạy ở trạng thái đó.

Một số dịch vụ có thể chạy trong một hoặc nhiều cấp chạy nhưng không chạy trong các cấp khác.

Các cấp độ chạy được biểu thị bằng các chữ số đơn lẻ và chúng có thể có giá trị từ 0 đến 6. Danh sách sau đây cho thấy ý nghĩa của từng cấp độ này:

  • Runlevel 0: Tắt hệ thống
  • Runlevel 1: Một user , chế độ cứu hộ
  • Runlevels 2, 3, 4: Nhiều user , chế độ văn bản có bật mạng
  • Runlevel 5: Đa user , kích hoạt mạng, chế độ đồ họa
  • Runlevel 6: Khởi động lại hệ thống

Runlevels 2, 3 và 4 thay đổi theo phân phối. Ví dụ: một số bản phân phối Linux không triển khai runlevel 4, trong khi những bản khác thì có. Một số bản phân phối có sự phân biệt rõ ràng giữa ba cấp độ này. Nói chung, runlevel 2, 3 hoặc 4 nghĩa là trạng thái mà Linux đã khởi động ở chế độ đa user , kích hoạt mạng, chế độ văn bản.

Khi ta cho phép một dịch vụ tự động khởi động, ta thực sự đang thêm nó vào một cấp chạy. Trong Hệ thống V, Hệ điều hành sẽ bắt đầu với một cấp chạy cụ thể; và khi khởi động, nó sẽ cố gắng khởi động tất cả các dịch vụ được liên kết với runlevel đó.

Runlevels trở thành mục tiêu trong systemd, ta sẽ thảo luận trong phần systemd.

Init và PID 1

init là quá trình đầu tiên bắt đầu trong hệ thống Linux sau khi máy khởi động và kernel tải vào bộ nhớ.

Trong số những thứ khác, nó quyết định quá trình user hoặc một dịch vụ hệ thống sẽ tải như thế nào, theo thứ tự nào và liệu nó có tự động khởi động hay không.

Mọi quy trình trong Linux đều có ID quy trình (PID) và init có PID là 1. Nó là cha của tất cả các quy trình khác sau đó sinh ra khi hệ thống trực tuyến.

Lịch sử của Init

Khi Linux đã phát triển, hành vi của init daemon cũng vậy. Ban đầu, Linux bắt đầu với System V init, cùng một hệ thống được sử dụng trong UNIX. Kể từ đó, Linux đã triển khai trình Upstart init (do Ubuntu tạo ra) và bây giờ là daemon init systemd (lần đầu tiên được Fedora triển khai).

Hầu hết các bản phân phối Linux đã dần dần di chuyển khỏi Hệ thống V hoặc đang trên đường loại bỏ nó, chỉ giữ lại nó để tương thích ngược. FreeBSD, một biến thể của UNIX, sử dụng một cách triển khai khác của Hệ thống V, được gọi là BSD init. Các version Debian cũ hơn cũng sử dụng SysVinit.

Mỗi version của init daemon có những cách quản lý dịch vụ khác nhau. Lý do đằng sau những thay đổi này là nhu cầu về một công cụ quản lý dịch vụ mạnh mẽ, không chỉ xử lý các dịch vụ mà còn cả các thiết bị, cổng và các tài nguyên khác; sẽ tải tài nguyên song song và sẽ khôi phục một cách duyên dáng sau sự cố.

Hệ thống V Init Sequence

Hệ thống V sử dụng file inittab mà các phương thức init sau này như Upstart đã giữ lại để tương thích ngược.

Hãy chạy qua trình tự khởi động của System V:

  1. Daemon init được tạo từ file binary /sbin/init
  2. Tệp đầu tiên mà daemon init đọc là /etc/inittab
  3. Một trong những mục nhập trong file này quyết định cấp chạy mà máy sẽ khởi động vào. Ví dụ: nếu giá trị cho runlevel được chỉ định là 3, Linux sẽ khởi động ở chế độ đa user , văn bản với mạng được bật. (Runlevel này được gọi là runlevel mặc định)
  4. Tiếp theo, daemon init nhìn sâu hơn vào file /etc/inittab và đọc những tập lệnh init nào nó cần để chạy cho runlevel đó

Vì vậy, khi daemon init tìm thấy những tập lệnh init nào của nó cần để chạy cho cấp chạy đã cho, về cơ bản nó sẽ tìm ra những dịch vụ mà nó cần để khởi động. Các tập lệnh init này là nơi bạn có thể cấu hình hành vi khởi động cho các dịch vụ riêng lẻ, giống như ta đã làm cho MySQL trong hướng dẫn đầu tiên.

Tiếp theo, hãy xem xét chi tiết các tập lệnh init.

Tệp cấu hình hệ thống V: Tập lệnh Init

Một tập lệnh init là thứ điều khiển một dịch vụ cụ thể, như MySQL Server, trong Hệ thống V.

Các tập lệnh Init cho các dịch vụ do nhà cung cấp ứng dụng cung cấp hoặc đi kèm với bản phân phối Linux (dành cho các dịch vụ root ). Ta cũng có thể tạo các tập lệnh init của riêng mình cho các dịch vụ được tạo tùy chỉnh.

Khi một quy trình hoặc dịch vụ như MySQL Server khởi động, file chương trình binary của nó phải tải vào bộ nhớ.

Tùy thuộc vào cách dịch vụ được cấu hình, chương trình này có thể phải tiếp tục thực thi ở chế độ nền liên tục (và chấp nhận các kết nối client ). Công việc khởi động, dừng hoặc reload ứng dụng binary này được xử lý bởi tập lệnh init của dịch vụ. Nó được gọi là init script vì nó khởi tạo dịch vụ.

Trong System V, init script là một shell script.

Các tập lệnh Init còn gọi là các tập lệnh rc (lệnh chạy).

Cấu trúc folder

Thư mục /etc là folder mẹ cho các tập lệnh init.

Vị trí thực tế cho các tập lệnh init shell là trong /etc/init.d . Các tập lệnh này được softlink với các folder rc .

Trong folder /etc , ta có một số folder rc , mỗi folder có một số trong tên của nó.

Các con số đại diện cho các cấp độ chạy khác nhau. Vì vậy, ta có /etc/rc0.d , /etc/rc1.d , /etc/rc2.d , /etc/rc2.d

Sau đó, trong mỗi folder rc n .d , ta có các file bắt đầu bằng K hoặc S trong tên file của chúng, theo sau là hai chữ số. Đây là các file softlink trỏ trở lại các tập lệnh init shell thực. Tại sao lại là KS ? K nghĩa là Kill (tức là dừng) và “S” là viết tắt của Start.

Hai chữ số đại diện cho thứ tự thực hiện tập lệnh. Vì vậy, nếu ta có một file tên K25 some_script , nó sẽ thực thi trước K99 another_script .

Khởi động

Hãy quay lại với trình tự khởi động của ta . Vậy init script được gọi như thế nào? Ai gọi họ?

Các tập lệnh K và S không được gọi trực tiếp bởi daemon init, mà bởi một tập lệnh khác: tập lệnh /etc/init.d/rc .

Nếu bạn nhớ, file /etc/inittab cho init daemon biết cấp chạy mà hệ thống sẽ nhập theo mặc định. Đối với mỗi runlevel, một dòng trong file /etc/inittab gọi tập lệnh /etc/init.d/rc , chuyển runlevel đó như một tham số. Dựa trên tham số này, tập lệnh sau đó gọi các file trong folder /etc/rc n .d tương ứng. Vì vậy, nếu server khởi động với runlevel 2, các tập lệnh dưới /etc/rc2.d sẽ được gọi; đối với runlevel 3, các tập lệnh trong /etc/rc3.d được thực thi, v.v.

Trong folder rc , đầu tiên, tất cả các tập lệnh K được chạy theo thứ tự số với đối số là “dừng”, sau đó tất cả các tập lệnh S được chạy theo kiểu tương tự với đối số là “bắt đầu”. Phía sau, các tập lệnh init shell tương ứng sẽ được gọi với các tham số dừng và bắt đầu tương ứng.

Bây giờ vì các file trong folder /etc/rc n .d (tệp K nnS nn ) chỉ là các softlink , việc gọi chúng nghĩa là gọi các tập lệnh shell init thực với các tham số dừng và bắt đầu.

Tóm lại, khi server Linux vào một cấp chạy, một số tập lệnh nhất định sẽ được chạy để dừng một số dịch vụ trong khi các tập lệnh khác sẽ được chạy để khởi động các dịch vụ khác.

Việc gọi init script này cũng xảy ra khi nào hệ thống chuyển sang runlevel mới: các tập lệnh folder /etc/rc<n>.d tương ứng được thực thi. Và vì các file K và S đó không là gì ngoài các liên kết, các tập lệnh shell thực trong folder /etc/init.d được thực thi với đối số bắt đầu hoặc dừng thích hợp.

Toàn bộ quá trình đảm bảo bất kỳ dịch vụ nào không được phép chạy trong runlevel đó sẽ bị dừng và tất cả các dịch vụ được cho là chạy trong runlevel đó được khởi động.

Hệ thống V tự động khởi động

Khi ta cho phép một dịch vụ tự động khởi động tại thời điểm khởi động, ta thực sự đang sửa đổi hành vi của init.

Vì vậy, ví dụ, khi ta cho phép một dịch vụ tự động khởi động ở runlevel 3, đằng sau quá trình này sẽ tạo các liên kết thích hợp trong folder /etc/rc3.d .

Nếu điều này nghe có vẻ khó hiểu, đừng lo lắng - ta sẽ xem tất cả ý nghĩa của nó sau một phút.

Ví dụ hệ thống V

Ta sẽ quay lại ví dụ về dịch vụ MySQL của ta , lần này với nhiều lý thuyết hơn.

Bước 1 - Đăng nhập Debian Server

Với mục đích của phần này của hướng dẫn, ta sẽ quay lại Debian 6 Server mà ta đã tạo trong Phần 1. Sử dụng lệnh SSH để kết nối với server ( user Windows có thể kết nối bằng một công cụ như PuTTy).

  • ssh sammy@your_server_ip

Bước 2 - Nhìn vào inittab

Chạy lệnh sau để xem nội dung file inittab :

  • cat /etc/inittab | grep initdefault

Đầu ra sẽ giống như sau:

Output
id:2:initdefault:

2 sau trường id cho thấy hệ thống được cấu hình để bắt đầu với runlevel 2. Đó là runlevel mặc định. Trong trường hợp này, Debian chỉ định 2 là chế độ văn bản, nhiều user . Nếu bạn thực hiện lệnh sau:

  • cat /etc/inittab | grep Runlevel

kết quả xác nhận điều này:

Output
# Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot.

Bước 3 - Nhìn vào Thư mục rc

Chạy lệnh sau để liệt kê các folder rc . Bạn sẽ thấy có sáu trong số này:

  • ls -ld /etc/rc*.d
Output
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc0.d drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc1.d drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc2.d drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc3.d drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc4.d drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc5.d drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc6.d drwxr-xr-x 2 root root 4096 Jul 23 2012 /etc/rcS.d

Vì hệ thống khởi động ở runlevel 2 (init mặc định từ file inittab), các tập lệnh trong folder /etc/rc2.d sẽ thực thi khi khởi động hệ thống.

Liệt kê nội dung của folder này:

  • ls -l /etc/rc2.d

Điều này cho thấy các file không là gì ngoài các softlink , mỗi liên kết trỏ đến các file script trong /etc/init.d:

Output
. . . lrwxrwxrwx 1 root root 17 Jul 23 2012 S01rsyslog -> ../init.d/rsyslog lrwxrwxrwx 1 root root 22 Jul 23 2012 S02acpi-support -> ../init.d/acpi-support lrwxrwxrwx 1 root root 15 Jul 23 2012 S02acpid -> ../init.d/acpid lrwxrwxrwx 1 root root 17 Jul 23 2012 S02anacron -> ../init.d/anacron lrwxrwxrwx 1 root root 13 Jul 23 2012 S02atd -> ../init.d/atd lrwxrwxrwx 1 root root 14 Jul 23 2012 S02cron -> ../init.d/cron lrwxrwxrwx 1 root root 15 Jul 31 07:09 S02mysql -> ../init.d/mysql lrwxrwxrwx 1 root root 13 Jul 23 2012 S02ssh -> ../init.d/ssh . . .

Ta có thể thấy không có tập lệnh K nào ở đây, chỉ có tập lệnh S (bắt đầu). Các tập lệnh bắt đầu các dịch vụ đã biết như rsyslog , cron hoặc ssh .

Lưu ý hai chữ số sau S quyết định thứ tự bắt đầu: ví dụ: rsyslog bắt đầu trước trình cron. Ta cũng có thể thấy rằng MySQL được liệt kê ở đây.

Bước 4 - Xem Init Script

Bây giờ ta biết rằng khi một dịch vụ tuân theo System V được cài đặt, nó sẽ tạo ra một tập lệnh shell trong folder /etc/init.d . Kiểm tra tập lệnh shell cho MySQL:

  • ls -l /etc/init.d/my*
Output
-rwxr-xr-x 1 root root 5437 Jan 14 2014 /etc/init.d/mysql

Để xem kịch bản khởi động thực sự trông như thế nào, hãy đọc file :

  • cat /etc/init.d/mysql | less

Từ kết quả , bạn sẽ thấy đó là một tập lệnh bash lớn.

Bước 5 - Sử dụng chkconfig hoặc sysv-rc-conf

Trong các bản phân phối dựa trên RHEL như CentOS, một lệnh gọi là chkconfig được dùng để bật hoặc tắt một dịch vụ trong Hệ thống V. Nó cũng có thể liệt kê các dịch vụ đã cài đặt và cấp chạy của chúng.

Cú pháp để kiểm tra trạng thái của dịch vụ cho tất cả các cấp chạy trên hệ thống CentOS sẽ là:

  • chkonfig --list | grep service_name

Không có tiện ích nào như vậy đi kèm với Debian nguyên bản (chỉ cài đặt update-rc.d hoặc gỡ bỏ các dịch vụ khỏi runlevels). Tuy nhiên, ta có thể cài đặt một công cụ tùy chỉnh có tên là sysv-rc-conf để giúp ta quản lý các dịch vụ.

Chạy lệnh sau để cài đặt sysv-rc-conf :

  • sudo apt-get install sysv-rc-conf -y

Khi công cụ đã được cài đặt, chỉ cần thực hiện lệnh này để xem hành vi của runlevel cho các dịch vụ khác nhau:

  • sudo sysv-rc-conf

Kết quả xuất ra sẽ là một cửa sổ đồ họa khá đẹp mắt như hình dưới đây. Từ đây, ta có thể thấy rõ ràng những dịch vụ nào được kích hoạt cho những runlevel nào (được đánh dấu bằng X).

sysv-rc-conf Cửa sổ hiển thị dấu X cho các dịch vụ khác nhau cho mỗi cấp chạy

Sử dụng các phím mũi tên và SPACEBAR , ta có thể bật hoặc tắt một dịch vụ cho một hoặc nhiều cấp độ chạy.

Hiện tại, hãy rời khỏi màn hình bằng cách nhấn Q

Bước 7 - Kiểm tra hành vi khởi động MySQL khi khởi động

Như bạn thấy từ ảnh chụp màn hình trong phần trước và từ thử nghiệm của ta trong Phần 1 của hướng dẫn, MySQL hiện được kích hoạt trên runlevels 2-5.

Chạy lệnh dưới đây để tắt Dịch vụ MySQL:

  • sudo update-rc.d mysql disable
Output
update-rc.d: using dependency based boot sequencing insserv: warning: current start runlevel(s) (empty) of script `mysql' overwrites defaults (2 3 4 5). insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `mysql' overwrites defaults (0 1 6).

Bây giờ chạy lệnh:

  • ls -l /etc/rc2.d

Kết quả kết quả sẽ cho thấy softlink từ /etc/rc2.d thành /etc/init.d/mysql đã thay đổi thành K :

Output
. . . lrwxrwxrwx 1 root root 15 Jul 31 07:09 K02mysql -> ../init.d/mysql . . .

Nói cách khác, MySQL sẽ không còn bắt đầu ở runlevel mặc định (2).

Đây là những gì xảy ra đằng sau mức thấp trong Hệ thống V khi ta bật và tắt một dịch vụ. Miễn là có script S trong folder runlevel mặc định cho dịch vụ, init sẽ khởi động dịch vụ đó khi khởi động.

Bật lại dịch vụ:

  • sudo update-rc.d mysql enable

Bước 8 - Kiểm tra hành vi khởi động của MySQL khi gặp sự cố

Hãy xem cách Hệ thống V xử lý sự cố dịch vụ.

Lưu ý ta đã thực hiện thay đổi đối với file /etc/inittab trong Phần 1 của hướng dẫn này, để cho phép MySQL tự động khởi động sau sự cố. Ta đã thêm dòng sau:

/ etc / inittab
ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe 

Điều này nhằm đảm bảo dịch vụ MySQL bắt đầu sau sự cố. Để kiểm tra xem điều đó có xảy ra hay không, trước tiên hãy khởi động lại server :

  • sudo reboot

Khi server hoạt động trở lại, hãy SSH vào đó và kiểm tra các ID quy trình MySQL như trước:

  • ps -ef | grep mysql

Lưu ý các ID quy trình cho mysqld_safemysqld . Trong trường hợp của ta , chúng lần lượt là 895 và 1019:

Output
root 907 1 0 07:30 ? 00:00:00 /bin/sh /usr/bin/mysqld_safe mysql 1031 907 0 07:30 ? 00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 root 1032 907 0 07:30 ? 00:00:00 logger -t mysqld -p daemon.error root 2550 2532 0 07:31 pts/0 00:00:00 grep mysql

Hủy các quy trình bằng lựa chọn -9 (thay thế các PID bằng các PID của hệ thống Debian của bạn):

  • sudo kill -9 907
  • sudo kill -9 1031

Chờ khoảng năm phút và sau đó thực hiện lệnh:

  • sudo service mysql status

Đầu ra sẽ hiển thị dịch vụ MySQL đang chạy, bắt đầu bằng dòng này:

Output
/usr/bin/mysqladmin Ver 8.42 Distrib 5.1.73, for debian-linux-gnu on x86_64

Nếu bạn chạy ps -ef | grep mysql , bạn sẽ thấy rằng cả hai quy trình mysqld_safemysqld đã xuất hiện.

Cố gắng kết thúc quá trình một vài lần nữa và trong mỗi trường hợp, nó sẽ hồi sinh sau năm phút.

Đây là lý do ta thêm dòng bổ sung đó vào /etc/inittab : đây là cách bạn cấu hình dịch vụ System V để hồi sinh khi gặp sự cố. Có giải thích chi tiết về cú pháp cho dòng này trong Phần 1 .

Tuy nhiên, hãy cẩn thận khi bạn thêm tự động khởi động lại cho một dịch vụ: nếu một dịch vụ cố gắng khôi phục lại và không thành công hơn mười lần trong vòng hai phút, Linux sẽ vô hiệu hóa tự động khởi động lại trong năm phút tiếp theo. Điều này giúp hệ thống hoạt động ổn định và không bị cạn kiệt tài nguyên máy tính.

Nếu bạn tình cờ nhận được một thông báo trong console về sự kiện đó hoặc tìm thấy nó trong log hệ thống, bạn sẽ biết rằng có một vấn đề với ứng dụng cần được khắc phục, vì nó liên tục gặp sự cố.

Giới thiệu khởi động

Classic SysVinit đã là một phần của các bản phân phối Linux chính thống trong một thời gian dài trước khi Upstart xuất hiện.

Khi thị trường Linux phát triển, các cách tải công việc và dịch vụ tuần tự trở nên tốn thời gian và phức tạp hơn. Đồng thời, khi ngày càng có nhiều thiết bị hiện đại như phương tiện lưu trữ có thể cắm nóng phát triển trên thị trường, SysVinit được phát hiện là không có khả năng xử lý chúng một cách nhanh chóng.

Nhu cầu tải hệ điều hành nhanh hơn, dọn dẹp dễ dàng các dịch vụ bị lỗi và dependencies có thể dự đoán được giữa các dịch vụ hệ thống đã thúc đẩy nhu cầu về một trình quản lý dịch vụ tốt hơn. Các nhà phát triển tại Ubuntu đã nghĩ ra một phương tiện khởi tạo khác, đó là daemon Upstart.

Upstart init tốt hơn System V init theo một số cách:

  • Upstart không xử lý các tập lệnh shell phức tạp để tải và quản lý các dịch vụ. Thay vào đó, nó sử dụng các file cấu hình đơn giản dễ hiểu và dễ sửa đổi
  • Upstart không tải các dịch vụ nối tiếp nhau như Hệ thống V. Điều này làm giảm thời gian khởi động hệ thống
  • Upstart's sử dụng một hệ thống sự kiện linh hoạt để tùy chỉnh cách các dịch vụ được xử lý ở các trạng thái khác nhau
  • Upstart có những cách tốt hơn để xử lý cách dịch vụ bị lỗi sẽ hồi sinh
  • Không cần phải giữ một số softlink dư thừa, tất cả đều trỏ đến cùng một tập lệnh
  • Upstart tương thích ngược với System V. Tập lệnh /etc/init.d/rc vẫn chạy để quản lý các dịch vụ root của System V

Sự kiện khởi động

Upstart cho phép nhiều sự kiện được liên kết với một dịch vụ. Kiến trúc dựa trên sự kiện này cho phép Upstart xử lý việc quản lý dịch vụ một cách linh hoạt.

Mỗi sự kiện có thể kích hoạt một tập lệnh shell xử lý sự kiện đó.

Các sự kiện khởi động bao gồm:

  • Bắt đầu
  • Đã bắt đầu
  • Đang dừng lại
  • Đã dừng lại

Giữa những sự kiện này, một dịch vụ có thể ở một số trạng thái , như:

  • đang chờ đợi
  • bắt đầu trước
  • bắt đầu
  • đang chạy
  • dừng trước
  • dừng lại
  • Vân vân.

Upstart cũng có thể thực hiện các hành động cho từng trạng thái này, tạo ra một kiến trúc rất linh hoạt.

Khởi động lại trình tự Init

Giống như System V, Upstart cũng chạy tập lệnh /etc/init.d/rc khi khởi động. Tập lệnh này thực thi mọi tập lệnh init System V một cách bình thường.

Upstart cũng tìm trong folder /etc/init và thực thi các lệnh shell trong mỗi file cấu hình dịch vụ.

Khởi động lại file cấu hình

Upstart sử dụng các file cấu hình để kiểm soát các dịch vụ.

Upstart không sử dụng các tập lệnh Bash như cách System V làm. Thay vào đó, Upstart sử dụng các file cấu hình dịch vụ với tiêu chuẩn đặt tên là service_name .conf .

Các file có nội dung văn bản thuần túy với các phần khác nhau, được gọi là khổ thơ . Mỗi khổ thơ mô tả một khía cạnh khác nhau của dịch vụ và cách hoạt động của nó.

Các khổ thơ khác nhau kiểm soát các sự kiện khác nhau cho dịch vụ, như trước khi bắt đầu , bắt đầu , dừng trước hoặc dừng sau .

Bản thân các khổ thơ chứa các lệnh shell. Do đó, có thể gọi nhiều hành động cho mỗi sự kiện cho mỗi dịch vụ.

Mỗi file cấu hình cũng chỉ định hai điều:

  • Cấp độ chạy dịch vụ nào sẽ bắt đầu và dừng lại
  • Dịch vụ có nên hồi sinh nếu nó gặp sự cố hay không

Cấu trúc folder

Các file cấu hình Upstart nằm trong folder /etc/init (đừng nhầm với /etc/init.d ).

Ví dụ khởi động

Hãy cùng xem lại cách Upstart xử lý MySQL Server, lần này với nhiều kiến thức nền tảng hơn.

Bước 1 - Đăng nhập vào Ubuntu Server

Quay lại Server Ubuntu 14.04 mà ta đã tạo trong Phần 1.

Sử dụng lệnh SSH để kết nối với server ( user Windows có thể kết nối bằng công cụ như PuTTy).

  • ssh sammy@your_server_ip

Bước 2 - Nhìn vào Thư mục init và rc

Hầu hết các file cấu hình của Upstart đều nằm trong folder /etc/init . Đây là folder bạn nên sử dụng khi tạo dịch vụ mới.

Sau khi đăng nhập vào server , hãy thực hiện lệnh sau:

  • sudo ls -l /etc/init/ | less

Kết quả sẽ hiển thị một số lượng lớn các file cấu hình dịch vụ, mỗi lần một màn hình. Đây là những dịch vụ chạy nguyên bản trong Upstart:

Output
total 356 . . . -rw-r--r-- 1 root root 297 Feb 9 2013 cron.conf -rw-r--r-- 1 root root 489 Nov 11 2013 dbus.conf -rw-r--r-- 1 root root 273 Nov 19 2010 dmesg.conf . . . -rw-r--r-- 1 root root 1770 Feb 19 2014 mysql.conf -rw-r--r-- 1 root root 2493 Mar 20 2014 networking.conf

Nhấn Q để thoát less .

So sánh điều này với các dịch vụ System V init root trong hệ thống:

  • sudo ls -l /etc/rc3.d/* | less

Sẽ chỉ có một số ít:

Output
-rw-r--r-- 1 root root 677 Jun 14 23:31 /etc/rc3.d/README lrwxrwxrwx 1 root root 15 Apr 17 2014 /etc/rc3.d/S20rsync -> ../init.d/rsync lrwxrwxrwx 1 root root 24 Apr 17 2014 /etc/rc3.d/S20screen-cleanup -> ../init.d/screen-cleanup lrwxrwxrwx 1 root root 19 Apr 17 2014 /etc/rc3.d/S70dns-clean -> ../init.d/dns-clean lrwxrwxrwx 1 root root 18 Apr 17 2014 /etc/rc3.d/S70pppd-dns -> ../init.d/pppd-dns lrwxrwxrwx 1 root root 26 Apr 17 2014 /etc/rc3.d/S99digitalocean -> ../init.d//rc.digitalocean lrwxrwxrwx 1 root root 21 Apr 17 2014 /etc/rc3.d/S99grub-common -> ../init.d/grub-common lrwxrwxrwx 1 root root 18 Apr 17 2014 /etc/rc3.d/S99ondemand -> ../init.d/ondemand lrwxrwxrwx 1 root root 18 Apr 17 2014 /etc/rc3.d/S99rc.local -> ../init.d/rc.local

Bước 3 - Xem xét file khởi động

Ta đã thấy file mysql.conf trong Phần 1 của hướng dẫn này. Vì vậy, hãy mở một file cấu hình khác: file cho trình cron.

  • sudo nano /etc/init/cron.conf

Như bạn thấy , đây là một file cấu hình khá đơn giản cho trình cron:

/etc/init/cron.conf
# cron - regular background program processing daemon # # cron is a standard UNIX program that runs user-specified programs at # periodic scheduled times  description     "regular background program processing daemon"  start on runlevel [2345] stop on runlevel [!2345]  expect fork respawn  exec cron 

Các lĩnh vực quan trọng cần lưu ý ở đây là start on , stop onrespawn .

Lệnh start on yêu cầu Ubuntu khởi động trình crond khi hệ thống đi vào các cấp độ 2, 3, 4 hoặc 5. 2, 3 và 4 là chế độ văn bản nhiều user có bật mạng và 5 là chế độ đồ họa nhiều user . Dịch vụ không chạy trên bất kỳ cấp chạy nào khác (như 0,1 hoặc 6).

Chỉ thị fork cho Upstart biết quá trình sẽ tách khỏi console và chạy ở chế độ nền.

Tiếp theo là chỉ thị respawn . Điều này cho hệ thống biết rằng cron sẽ tự động khởi động nếu nó bị treo vì bất kỳ lý do gì.

Thoát khỏi editor mà không thực hiện bất kỳ thay đổi nào.

Tệp cấu hình cron là một file cấu hình khá nhỏ. Tệp cấu hình MySQL có cấu trúc tương tự như file cấu hình cron; nó cũng có các khổ thơ để bắt đầu, dừng và hồi sinh. Ngoài ra, nó cũng có hai khối tập lệnh cho các sự kiện trước khi bắt đầu và sau khi bắt đầu. Các khối mã này cho hệ thống biết phải thực thi những gì khi tiến trình mysqld sắp xuất hiện hoặc đã xuất hiện.

Để được trợ giúp thiết thực về cách tạo file Upstart của bạn , hãy xem hướng dẫn này về Upstart .

Bước 4 - Kiểm tra hành vi khởi động MySQL khi khởi động

Ta biết version MySQL trên server Ubuntu 14.04 của ta được đặt thành tự động khởi động tại thời điểm khởi động theo mặc định. Hãy xem cách ta có thể vô hiệu hóa nó.

Trong Upstart, việc vô hiệu hóa một dịch vụ phụ thuộc vào sự tồn tại của một file trong /etc/init/ được gọi là service_name .override . Nội dung của file phải là một từ đơn giản: manual .

Để xem cách ta có thể sử dụng file này để tắt MySQL, hãy thực thi lệnh sau để tạo file overrides này cho MySQL:

  • sudo nano /etc/init/mysql.override

Thêm dòng đơn này:

/etc/init/mysql.override
manual 

Lưu các thay đổi .

Tiếp theo, khởi động lại server :

  • sudo reboot

Sau khi server trực tuyến trở lại, hãy kiểm tra sao của dịch vụ

  • sudo initctl status mysql

Đầu ra phải là:

Output
mysql stop/waiting

Điều này nghĩa là MySQL không khởi động.

Kiểm tra xem chỉ thị start có thay đổi trong file cấu hình dịch vụ MySQL hay không:

  • sudo cat /etc/init/mysql.conf | grep start\ on

Nó vẫn phải như cũ:

Output
start on runlevel [2345]

Điều này nghĩa là việc kiểm tra file .conf trong folder init không phải là yếu tố duy nhất để xem liệu dịch vụ có bắt đầu ở các mức thích hợp hay không. Bạn cũng cần đảm bảo file .override không tồn tại.

Để chạy lại MySQL, hãy xóa file overrides và khởi động lại server :

  • sudo rm -f /etc/init/mysql.override
  • sudo reboot

Sau khi server khởi động lại, hãy kết nối từ xa với nó.

Chạy sudo initctl status mysql sẽ hiển thị dịch vụ đã bắt đầu tự động.

Bước 5 - Kiểm tra hành vi khởi động MySQL khi gặp sự cố

Theo mặc định, MySQL tự động xuất hiện sau sự cố.

Để dừng MySQL này, hãy mở file cấu hình dịch vụ /etc/init/mysql.conf :

  • sudo nano /etc/init/mysql.conf

Comment cả hai chỉ thị respawn .

/etc/init/mysql.conf
# respawn # respawn limit 2 5 

Chạy các lệnh sau để khởi động lại dịch vụ:

  • sudo initctl stop mysql
  • sudo initctl start mysql

Ta đang dừng và bắt đầu dịch vụ một cách rõ ràng vì thử nghiệm của ta cho thấy initctl restart hoặc initctl reload sẽ không hoạt động ở đây.

Lệnh thứ hai để bắt đầu dịch vụ hiển thị PID MySQL bắt đầu bằng:

Output
mysql start/running, process 1274

Lưu ý PID cho version MySQL của bạn. Nếu bạn gặp sự cố quy trình mysql bây giờ, nó sẽ không tự động xuất hiện. Hủy ID quy trình (thay thế nó bằng số của bạn ):

  • sudo kill -9 1274

Bây giờ hãy kiểm tra trạng thái của nó:

  • sudo initctl status mysql
Output
mysql stop/waiting

Cố gắng tìm trạng thái thêm một vài lần nữa, cho một khoảng thời gian giữa mỗi lần. Trong mọi trường hợp, MySQL vẫn sẽ bị dừng. Điều này đang xảy ra bởi vì file cấu hình dịch vụ không có các chỉ thị respawn nữa.

Phần 1 của hướng dẫn có giải thích chi tiết hơn về các lệnh respawn .

Khi nào bạn không muốn dịch vụ Upstart xuất hiện sau khi khởi động lại hoặc gặp sự cố?

Giả sử bạn đã nâng cấp nhân Linux của bạn hoặc đưa vào bản vá mới nhất. Bạn không muốn có bất kỳ bộ phim truyền hình nào; bạn chỉ là server để xuất hiện. Bạn có thể loại bỏ phần lớn rủi ro bằng cách tắt tính năng tự động khởi động cho bất kỳ quá trình Khởi động nào.

Nếu dịch vụ của bạn xuất hiện nhưng vẫn tiếp tục gặp sự cố, trước tiên bạn có thể dừng nó và sau đó thay đổi hành vi hồi sinh của nó.

systemd Giới thiệu

Phiên bản mới nhất trong các daemon init của Linux là systemd. Trên thực tế, nó không chỉ là một daemon init: systemd là một khung hoàn toàn mới bao gồm nhiều thành phần của một hệ thống Linux hiện đại.

Một trong những chức năng của nó là hoạt động như một người quản lý hệ thống và dịch vụ cho Linux. Trong khả năng này, một trong những điều mà hệ thống kiểm soát là cách một dịch vụ sẽ hoạt động nếu nó bị treo hoặc máy khởi động lại. Bạn có thể đọc về systemctl của systemd tại đây .

systemd tương thích ngược với các lệnh System V và các tập lệnh khởi tạo. Điều đó nghĩa là bất kỳ dịch vụ System V nào cũng sẽ chạy trong systemd. Điều này có thể thực hiện được vì hầu hết các lệnh quản trị Upstart và System V đã được sửa đổi để hoạt động theo systemd.

Trên thực tế, nếu ta chạy ps -ef | grep systemd trong hệ điều hành hỗ trợ nó, ta sẽ không thấy gì cả, vì systemd tự đổi tên thành init lúc khởi động. Có một file /sbin/init là một softlink đến /bin/systemd .

File cấu hình systemd: File đơn vị

Trung tâm của systemd là các file đơn vị . Mỗi file đơn vị đại diện cho một tài nguyên hệ thống. Sự khác biệt chính giữa systemd và hai phương thức init khác là systemd chịu trách nhiệm khởi tạo không chỉ các trình dịch vụ mà còn các loại tài nguyên khác như socket , đường dẫn hệ điều hành thiết bị, điểm mount , socket , v.v. Một tài nguyên có thể là bất kỳ những cái này.

Thông tin về tài nguyên được theo dõi trong file đơn vị.

Mỗi file đơn vị đại diện cho một tài nguyên hệ thống cụ thể và có một kiểu đặt tên của service name . unit type .

Vì vậy, ta sẽ có các file như dbus.service , sshd.socket hoặc home.mount .

Như ta sẽ thấy ở phần sau, file đơn vị dịch vụ là file văn bản đơn giản (như file .conf Upstart) với cú pháp khai báo. Các file này khá dễ hiểu và dễ sửa đổi.

Cấu trúc folder

Trong các hệ thống dựa trên Red Hat như CentOS, các file đơn vị được đặt ở hai nơi. Vị trí chính là /lib/systemd/system/ .

Tệp đơn vị được tạo tùy chỉnh hoặc file đơn vị hiện có được administrator hệ thống sửa đổi sẽ nằm trong /etc/systemd/system .

Nếu một file đơn vị có cùng tên tồn tại ở cả hai vị trí, systemd sẽ sử dụng file dưới /etc Nếu một dịch vụ được kích hoạt để bắt đầu tại thời điểm khởi động hoặc bất kỳ target / runlevel nào khác, một softlink sẽ được tạo cho file đơn vị dịch vụ đó trong các folder thích hợp trong /etc/systemd/system .Các file đơn vị trong /etc/systemd/system thực sự là các softlink đến các file có cùng tên trong /lib/systemd/system .

systemd Init Sequence: Đơn vị mục tiêu

Một loại file đơn vị đặc biệt là một đơn vị đích .

Tên file của đơn vị đích có hậu tố là .target . Các đơn vị mục tiêu khác với các file đơn vị khác vì chúng không đại diện cho một tài nguyên cụ thể. Đúng hơn, chúng đại diện cho trạng thái của hệ thống tại bất kỳ thời điểm nào.

Các đơn vị mục tiêu thực hiện điều này bằng cách group và chạy nhiều file đơn vị phải là một phần của trạng thái đó. Do đó, các mục tiêu systemd có thể được so sánh lỏng lẻo với các runlevel System V, mặc dù chúng không giống nhau.

Mỗi mục tiêu có một tên thay vì một số. Ví dụ: ta có multi-user.target thay vì runlevel 3 hoặc reboot.target thay vì runlevel 6.

Khi một server Linux khởi động với nói, multi-user.target , về cơ bản, nó đưa server đến cấp độ 2, 3 hoặc 4, là chế độ văn bản nhiều user có kích hoạt mạng.

Cách nó đưa server đến giai đoạn đó là sự khác biệt nằm ở đâu. Không giống như Hệ thống V, systemd không đưa ra các dịch vụ một cách tuần tự. Trên đường đi, nó có thể kiểm tra sự tồn tại của các dịch vụ hoặc tài nguyên khác và quyết định thứ tự tải chúng. Điều này giúp các dịch vụ có thể tải song song.

Một sự khác biệt khác giữa các đơn vị mục tiêu và runlevel là trong System V, một hệ thống Linux có thể chỉ tồn tại trong một runlevel. Bạn có thể thay đổi runlevel, nhưng hệ thống sẽ chỉ tồn tại trong runlevel mới đó. Với systemd, các đơn vị mục tiêu có thể được bao gồm , nghĩa là khi một đơn vị mục tiêu kích hoạt, nó có thể đảm bảo các đơn vị mục tiêu khác được tải như một phần của nó.

Ví dụ, một hệ thống Linux khởi động với giao diện user đồ họa sẽ được kích hoạt graphical.target , do đó sẽ tự động đảm bảo multi-user.target cũng được tải và kích hoạt.

(Theo thuật ngữ Hệ thống V, điều đó giống như việc kích hoạt cấp độ 3 và 5 cùng một lúc.)

Bảng dưới đây so sánh các cấp chạy và mục tiêu:

Runlevel (Hệ thống V init) Đơn vị mục tiêu (Systemd)
runlevel 0 poweroff.target
runlevel 1 resuce.target
runlevel 2, 3, 4 multi-user.target
runlevel 5 graphical.target
runlevel 6 reboot.target

systemd default.target

default.target tương đương với runlevel mặc định.

Trong Hệ thống V, ta đã định nghĩa runlevel mặc định trong một file có tên inittab . Trong systemd, file đó được thay thế bằng default.target . Tệp đơn vị mục tiêu mặc định nằm trong folder /etc/systemd/system . Đó là một softlink đến một trong các file đơn vị mục tiêu trong /lib/systemd/system .

Khi ta thay đổi mục tiêu mặc định, về cơ bản ta đang tạo lại softlink đó và thay đổi mức chạy của hệ thống.

Tệp inittab trong System V cũng chỉ định folder Linux sẽ thực thi các tập lệnh init của nó từ đó: nó có thể là bất kỳ folder rc n .d nào. Trong systemd, đơn vị mục tiêu mặc định xác định đơn vị tài nguyên nào sẽ được tải vào thời điểm khởi động.

Tất cả các đơn vị đó được kích hoạt, nhưng không phải tất cả song song hoặc tất cả theo trình tự. Cách một đơn vị tài nguyên tải có thể phụ thuộc vào các đơn vị tài nguyên khác mà nó muốn hoặc yêu cầu .

systemd Dependencies: Mong muốn và Yêu cầu

Lý do cho cuộc thảo luận này về file đơn vị và đơn vị mục tiêu là để làm nổi bật cách systemd giải quyết dependencies giữa các daemon của nó.

Như ta đã thấy trước đây, Upstart đảm bảo tải song song các dịch vụ bằng cách sử dụng file cấu hình. Trong Hệ thống V, một dịch vụ có thể bắt đầu trong các cấp chạy cụ thể, nhưng nó cũng có thể được thực hiện để đợi cho đến khi có dịch vụ hoặc tài nguyên khác. Theo cách tương tự, các dịch vụ systemd có thể được thực hiện để tải một hoặc nhiều mục tiêu hoặc đợi cho đến khi một dịch vụ hoặc tài nguyên khác hoạt động.

Trong systemd, một đơn vị yêu cầu một đơn vị khác sẽ không khởi động cho đến khi đơn vị yêu cầu được tải và kích hoạt. Nếu thiết bị cần thiết bị lỗi vì lý do nào đó trong khi thiết bị đầu tiên đang hoạt động, thiết bị đầu tiên cũng sẽ dừng.

Nếu bạn nghĩ về nó, điều này đảm bảo sự ổn định của hệ thống. Do đó, một dịch vụ yêu cầu một folder cụ thể hiện diện có thể được thực hiện để đợi cho đến khi điểm mount đến folder đó hoạt động. Mặt khác, một đơn vị muốn đơn vị khác sẽ không áp đặt những hạn chế như vậy. Nó sẽ không dừng nếu đơn vị muốn dừng lại khi người gọi đang hoạt động. Ví dụ về điều này sẽ là các dịch vụ không thiết yếu xuất hiện ở chế độ mục tiêu đồ họa.

Ví dụ systemd

Đã đến lúc ta đi sâu vào hành vi khởi động của MySQL trong systemd.

Bước 1 - Đăng nhập vào CentOS Server

Để hiểu tất cả các khái niệm này và cách chúng liên quan đến việc cho phép dịch vụ tự động khởi động, hãy quay lại CentOS 7 Server mà ta đã tạo trong Phần 1.

Sử dụng lệnh SSH để kết nối với server ( user Windows có thể kết nối bằng công cụ như PuTTy).

  • ssh sammy@your_server_ip

Bước 2 - Xem xét file default.target và phụ thuộc

Đây là một phần dài, bởi vì ta sẽ đi theo con đường thỏ .target càng xa càng tốt. trình tự khởi động của systemd tuân theo một chuỗi dài các phụ thuộc.

defaul.target

Tệp default.target kiểm soát dịch vụ nào bắt đầu trong quá trình khởi động server bình thường.

Thực thi lệnh sau để liệt kê file đơn vị mục tiêu mặc định:

  • sudo ls -l /etc/systemd/system/default.target

Điều này hiển thị kết quả như sau:

Output
lrwxrwxrwx. 1 root root 37 Jul 8 2014 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target

Như ta có thể thấy, mục tiêu mặc định thực sự là một softlink đến file mục tiêu nhiều user trong /lib/systemd/system/ . Vì vậy, hệ thống phải khởi động trong multi-user.target , tương tự như runlevel 3.

multi-user.target.wants

Tiếp theo, thực hiện lệnh sau để kiểm tra tất cả các dịch vụ mà file multi-user.target muốn :

  • sudo ls -l /etc/systemd/system/multi-user.target.wants/*.service

Điều này sẽ hiển thị một kết quả như thế này:

Output
. . . lrwxrwxrwx. 1 root root 37 Jul 8 2014 /etc/systemd/system/multi-user.target.wants/crond.service -> /usr/lib/systemd/system/crond.service . . . lrwxrwxrwx 1 root root 38 Jul 31 22:02 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service lrwxrwxrwx. 1 root root 46 Jul 8 2014 /etc/systemd/system/multi-user.target.wants/NetworkManager.service -> /usr/lib/systemd/system/NetworkManager.service lrwxrwxrwx. 1 root root 39 Jul 8 2014 /etc/systemd/system/multi-user.target.wants/postfix.service -> /usr/lib/systemd/system/postfix.service lrwxrwxrwx. 1 root root 39 Jul 8 2014 /etc/systemd/system/multi-user.target.wants/rsyslog.service -> /usr/lib/systemd/system/rsyslog.service lrwxrwxrwx. 1 root root 36 Jul 8 2014 /etc/systemd/system/multi-user.target.wants/sshd.service -> /usr/lib/systemd/system/sshd.service . . .

Ta có thể thấy đây là tất cả các file softlink , trỏ trở lại các file đơn vị thực trong /lib/systemd/system/ . Ta cũng có thể thấy rằng mysqld.service là một phần của multi-user.target .

Thông tin tương tự có thể được tìm thấy nếu bạn thực hiện lệnh này để lọc kết quả :

  • sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql
Output
mysqld.service

Ngoài multi-user.target , có nhiều loại mục tiêu khác nhau như system-update.target hoặc basic.target .

Để xem mục tiêu mà mục tiêu nhiều user của ta phụ thuộc vào mục tiêu nào, hãy thực hiện lệnh sau:

  • sudo systemctl show --property "Requires" multi-user.target | fmt -10
Output
Requires=basic.target

Vì vậy, để khởi động hệ thống trong multi-user.target chế độ, basic.target sẽ phải nạp đầu tiên.

basic.target

Để xem các mục tiêu basic.target phụ thuộc vào mục tiêu basic.target , hãy thực hiện lệnh này:

  • sudo systemctl show --property "Requires" basic.target | fmt -10

Đầu ra sẽ là:

Output
Requires=sysinit.target

sysinit.target

Đi đệ quy, ta có thể xem liệu có bất kỳ đơn vị bắt buộc nào cho sysinit.target . Không có gì cả. Tuy nhiên, ta có thể thấy những dịch vụ nào được sysinit.target muốn :

  • sudo systemctl show --property "Wants" sysinit.target | fmt -10

Điều này sẽ hiển thị một số dịch vụ mà sysinit muốn.

Output
Wants=local-fs.target swap.target cryptsetup.target systemd-udevd.service systemd-update-utmp.service systemd-journal-flush.service plymouth-read-write.service . . .

Như bạn thấy , hệ thống không chỉ ở một mục tiêu. Nó tải các dịch vụ theo kiểu phụ thuộc khi nó chuyển đổi giữa các mục tiêu.

Bước 3 - Xem xét file đơn vị

Bây giờ tiến thêm một bước nữa, hãy xem bên trong file đơn vị dịch vụ. Ta đã thấy file đơn vị dịch vụ MySQL trong Phần 1 của hướng dẫn này và ta sẽ sử dụng lại nó trong thời gian ngắn, nhưng bây giờ hãy mở một file đơn vị dịch vụ khác, file cho sshd:

  • sudo nano /etc/systemd/system/multi-user.target.wants/sshd.service

Nó trông như thế này:

Output
[Unit] Description=OpenSSH server daemon After=syslog.target network.target auditd.service [Service] EnvironmentFile=/etc/sysconfig/sshd ExecStartPre=/usr/sbin/sshd-keygen ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] WantedBy=multi-user.target

Cũng giống như file cấu hình daemon Upstart, file đơn vị dịch vụ này sạch và dễ hiểu.

Điều quan trọng đầu tiên cần hiểu là mệnh đề After . Điều này cho biết dịch vụ SSHD cần tải sau khi hệ thống và mục tiêu mạng và dịch vụ ghi log kiểm tra được tải.

Tệp cũng cho thấy dịch vụ được multi-user.target mong muốn , nghĩa là mục tiêu sẽ tải dịch vụ này, nhưng nó sẽ không tắt hoặc sập nếu sshd không thành công.

multi-user.target là mục tiêu mặc định, nên sshd daemon phải bắt đầu lúc khởi động.

Thoát khỏi editor .

Bước 4 - Kiểm tra hành vi khởi động MySQL khi khởi động

Trong Phần 1 của hướng dẫn, ta đã bật và chạy dịch vụ MySQL. Hãy xem làm thế nào để thay đổi điều đó.

Trong phần trước, ta chạy một lệnh để xác nhận mysqld.service đang bị truy nã bởi multi-user.target . Khi ta liệt kê nội dung của folder /etc/systemd/system/multi-user.target.wants/ , ta thấy một softlink trỏ trở lại đơn vị dịch vụ ban đầu trong /usr/lib/systemd/system/ .

Chạy lệnh sau để vô hiệu hóa dịch vụ để nó không tự động khởi động lúc khởi động:

  • sudo systemctl disable mysqld.service

Bây giờ, hãy chạy lệnh này để kiểm tra xem MySQL có còn được multi-user.target muốn multi-user.target :

  • sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql

Không có gì sẽ được trả lại. Chạy lệnh bên dưới để kiểm tra xem softlink có còn tồn tại hay không:

  • sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*

Liên kết không tồn tại:

Output
ls: cannot access /etc/systemd/system/multi-user.target.wants/mysql*: No such file or directory

Nếu bạn muốn, hãy thử khởi động lại server . MySQL không nên xuất hiện.

Bây giờ chạy lại dịch vụ:

  • sudo systemctl enable mysqld.service

Liên kết sẽ trở lại:

  • sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
Output
lrwxrwxrwx 1 root root 38 Aug 1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service

(Nếu bạn đã khởi động lại trước đó, bạn nên khởi động lại MySQL.)

Như bạn thấy , việc bật hoặc tắt dịch vụ systemd sẽ tạo hoặc xóa softlink khỏi folder wants của mục tiêu mặc định.

Bước 5 - Kiểm tra hành vi khởi động MySQL khi gặp sự cố

MySQL hiện sẽ tự động xuất hiện sau sự cố. Hãy xem làm thế nào để vô hiệu hóa điều đó.

Mở file đơn vị dịch vụ MySQL trong editor :

  • sudo nano /etc/systemd/system/multi-user.target.wants/mysqld.service

Sau thông tin tiêu đề, nội dung của file trông giống như sau:

/etc/systemd/system/multi-user.target.wants/mysqld.service
[Unit] Description=MySQL Community Server After=network.target After=syslog.target  [Install] WantedBy=multi-user.target Alias=mysql.service  [Service] User=mysql Group=mysql  # Execute pre and post scripts as root PermissionsStartOnly=true  # Needed to create system tables etc. ExecStartPre=/usr/bin/mysql-systemd-start pre  # Start main service ExecStart=/usr/bin/mysqld_safe  # Don't signal startup success before a ping works ExecStartPost=/usr/bin/mysql-systemd-start post  # Give up if ping don't get an answer TimeoutSec=600  Restart=always PrivateTmp=false 

Như ta đã thấy trong Phần 1, giá trị của tham số Restart được đặt thành always (đối với sshd, giá trị này chỉ được đặt thành khi on-failure ). Điều này nghĩa là dịch vụ MySQL sẽ khởi động lại đối với các mã thoát hoặc hết thời gian chờ sạch hoặc không sạch.

Trang user cho dịch vụ systemd hiển thị bảng sau cho các thông số Khởi động lại:

Khởi động lại cài đặt / Thoát nguyên nhân Không luôn luôn đang thành công thất bại bất thường phá thai cơ quan giám sát
Làm sạch mã hoặc tín hiệu thoát X X
Mã thoát không sạch X X
Tín hiệu không sạch X X X X
Hết giờ X X X
Cơ quan giám sát X X X X

Trong file đơn vị dịch vụ systemd, hai tham số - RestartRestart RestartSec - kiểm soát hành vi sự cố. Tham số đầu tiên chỉ định khi nào dịch vụ sẽ khởi động lại và tham số thứ hai xác định thời gian nó sẽ đợi trước khi khởi động lại.

Comment chỉ thị Khởi động lại, lưu file và thoát khỏi editor . Điều này sẽ vô hiệu hóa hành vi khởi động lại.

/etc/systemd/system/multi-user.target.wants/mysqld.service
# Restart=always 

Tiếp theo, reload daemon systemd, sau đó khởi động lại dịch vụ mysqld :

  • sudo systemctl daemon-reload
  • sudo systemctl restart mysqld.service

Tiếp theo, tìm PID chính của dịch vụ bằng cách chạy lệnh này:

  • sudo systemctl status mysqld.service
Output
. . . Main PID: 11217 (mysqld_safe)

Sử dụng lệnh kill -9 , giết PID chính, sử dụng số của bạn .

  • sudo kill -9 11217

Chạy lại sudo systemctl status mysqld.service sẽ cho thấy dịch vụ đã bị lỗi:

  • sudo systemctl status mysqld.service
Output
mysqld.service - MySQL Community Server Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled) Active: failed (Result: signal) since Sun 2015-06-21 02:28:17 EDT; 1min 33s ago Process: 2566 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS) Process: 2565 ExecStart=/usr/bin/mysqld_safe (code=killed, signal=KILL) Process: 2554 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS) Main PID: 2565 (code=killed, signal=KILL) Jun 21 02:20:09 test-centos7 systemd[1]: Starting MySQL Community Server... Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Logging to '/var/log/mysqld.log'. Jun 21 02:20:09 test-centos7 mysqld_safe[2565]: 150621 02:20:09 mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql Jun 21 02:20:10 test-centos7 systemd[1]: Started MySQL Community Server. Jun 21 02:28:16 test-centos7 systemd[1]: mysqld.service: main process exited, code=killed, status=9/KILL Jun 21 02:28:17 test-centos7 systemd[1]: Unit mysqld.service entered failed state.

Hãy thử tìm trạng thái dịch vụ một vài lần và mỗi lần dịch vụ sẽ được hiển thị là không thành công.

Vì vậy, ta đã mô phỏng một sự cố mà dịch vụ đã dừng và không hoạt động trở lại. Điều này là do ta đã hướng dẫn systemd không khởi động lại dịch vụ.

Bây giờ, nếu bạn chỉnh sửa lại file đơn vị mysqld.service , bỏ ghi chú tham số Restart , lưu nó, reload daemon systemctl và cuối cùng khởi động dịch vụ, nó sẽ trở lại như trước.

Đây là cách một dịch vụ systemd root có thể được cấu hình để tự động khởi động sau sự cố. Tất cả những gì ta phải làm là thêm một chỉ thị bổ sung cho Restart (và tùy chọn RestartSec ) trong phần [Service] của file đơn vị dịch vụ.

Kết luận

Vì vậy, đây là cách Linux xử lý khởi động dịch vụ. Ta đã thấy cách thức hoạt động của các quy trình System V, Upstart và systemd init và cách chúng liên quan đến việc tự động khởi động một dịch vụ sau khi khởi động lại hoặc gặp sự cố.

Cú pháp khai báo của file cấu hình Upstart hoặc file đơn vị systemd là một cải tiến so với các tập lệnh init System V phức tạp.

Khi bạn làm việc với môi trường Linux của riêng mình, hãy kiểm tra version phân phối của bạn và xem nó hỗ trợ init daemon nào.

Sẽ rất đáng để suy nghĩ về nơi bạn muốn kích hoạt một dịch vụ và nơi bạn muốn tắt nó. Trong hầu hết các trường hợp, bạn không phải thay đổi bất kỳ điều gì đối với các ứng dụng của bên thứ ba hoặc các trình Linux root . Chỉ khi bạn tạo các ứng dụng dựa trên dịch vụ của riêng mình, bạn mới phải suy nghĩ về hành vi khởi động và hồi sinh của chúng.


Tags:

Các tin liên quan

Cách thiết lập server IRC trên Ubuntu 14.04 với InspIRCd 2.0 và Shaltúre
2015-08-26
Cách chuyển tiếp cổng thông qua cổng Linux với Iptables
2015-08-20
Cách cấu hình dịch vụ Linux để khởi động tự động sau khi gặp sự cố hoặc khởi động lại - Phần 1: Ví dụ thực tế
2015-08-19
Cách sử dụng Hệ thống kiểm toán Linux trên CentOS 7
2015-07-16
Cách sử dụng Hệ thống kiểm toán Linux trên CentOS 7
2015-07-16
Thiết lập ban đầu của server Fedora 22
2015-07-08
Cách thiết lập Shiny Server trên Ubuntu 14.04
2015-06-28
Cách backup server LAMP bằng Bacula trên Ubuntu 14.04
2015-06-11
Cách cấu hình sao chép DNS trên server Slave PowerDNS trên Ubuntu 14.04
2015-06-04
Cách thay đổi mật khẩu tài khoản trên server OpenLDAP
2015-05-29