Làm cách nào để cấu hình systemd để giết và khởi động lại một daemon khi tải lại?


12

Tôi có một trình nền cũ của trường mà tôi muốn điều khiển bằng systemd. Khi tập tin cấu hình của nó thay đổi, nó cần phải bị hủy và khởi động lại. Nói cách khác, sau khi chỉnh sửa tập tin cấu hình, systemctl reload MYSERVICEnên giết tiến trình và khởi động lại nó.

Nỗ lực 1: Thử mặc định. Điều này cho systemd biết cách khởi động daemon, nhưng không phải cách tải lại nó.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Kết quả là, startrestartlàm việc, nhưng reloadđưa ra lỗi này:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Nỗ lực 2: Nói cho nó biết làm thế nào để giết quá trình. Điều này giết chết quá trình nhưng systemd không khởi động lại nó cho tôi.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...theo dõi bởi...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... giết quá trình nhưng nó không được khởi động lại tự động.

Cố gắng 3: Sử dụng ExecReload để khởi động lại quá trình. Điều này thất bại vì một vài lý do:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... thông báo lỗi tôi nhận được ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Tôi hy vọng sẽ có một Tải lại = kill_and_restart hoặc một cái gì đó nhưng không có may mắn như vậy.

Làm thế nào để bảo systemd giết và khởi động lại một daemon khi tải lại?


Điều này thực sự cần phải được đưa vào tải lại , nơi nó không hoàn toàn phù hợp? Bạn có thể không làm cho daemon cư xử hợp lý?
Michael Hampton

Cảm ơn @MichaelHampton, nhưng đây không phải là tình huống tôi có thể viết lại chương trình. Tôi đánh giá cao đề nghị hữu ích của bạn. Điều đó nói rằng, tôi chắc chắn đây là một trường hợp sử dụng hệ thống phổ biến và một câu trả lời chính tắc có thể giúp ích cho nhiều người.
TomOnTime

1
Tôi chắc chắn một câu trả lời có thể giúp được ai đó, vì vậy tôi đã đưa ra câu hỏi. Tôi chỉ không chắc chắn rằng đây là trường hợp sử dụng phổ biến. Đã sử dụng systemd trong năm năm hoặc lâu hơn, gần như kể từ ngày nó được tung ra trên thế giới, đây là lần đầu tiên tôi có thể nhớ lại việc nghe về bất cứ ai thử loại kịch bản này. Có thể tôi đang hiểu nhầm điều gì đó vì thiếu chi tiết.
Michael Hampton

Câu trả lời:


16

Câu trả lời là "bạn không"! Nhưng chúng tôi có tin tốt.

Triết lý của systemd là tải lại là tùy chọn và không được xác định nếu không có chức năng tải lại thực sự. Tôi định nghĩa "chức năng tải lại thực sự" là tải lại không giết và khởi động lại dịch vụ hoặc làm cho dịch vụ thay đổi PID. Nói cách khác, systemd chỉ muốn phản ánh những tính năng tồn tại.

Thay vào đó, bạn nên sử dụng systemctl reload-or-restartcái sẽ tải lại nếu nó tồn tại và khởi động lại nếu không.

Từ trang đàn ông ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Do đó: (1) để trống ExecReload, (2) sử dụng systemctl reload-or-restart MYSERVICEvà, (3) bạn sẽ được thiết lập tất cả.

Nếu bạn cố gắng sử dụng ExecReload để xác định cách giết và khởi động lại dịch vụ, nó sẽ có một PID mới và systemd sẽ bị nhầm lẫn.


3

Triết lý của systemd reloadlà tùy chọn và người dùng systemd nên biết, đối với mọi dịch vụ, liệu nó nên gọi reloadhay giả nó bằng cách gọi restart.

Do đó, câu trả lời cho câu hỏi của bạn là "Nó không hoạt động và không nên. Hãy giải quyết vấn đề này ở lớp cao hơn tiếp theo."

Nói cách khác, systemd muốn bạn chỉ thực hiện " tải lại " nếu dịch vụ bên dưới hỗ trợ chức năng tải lại thực sự ... tức là tải lại không giết và khởi động lại dịch vụ hoặc làm cho dịch vụ thay đổi PID. Nói cách khác, systemd chỉ muốn phản ánh những tính năng tồn tại.

Bạn có thể tự hỏi: Nhưng sẽ không dễ hơn nếu tôi có thể thực hiện tải lại "giả" bằng cách cho phép ExecReloadgiết và khởi động lại dịch vụ? Sau đó, tôi có thể sử dụng systemctl reload FOOcho tất cả các dịch vụ của mình và tôi sẽ không phải nhớ những dịch vụ nào hỗ trợ và dịch vụ nào không?

Vâng, điều đó sẽ dễ dàng hơn, nhưng đó sẽ không phải là cách của systemd. Systemd muốn người gọi là điều cần biết nếu reloadtồn tại cho dịch vụ. Systemd muốn trở thành một giao diện chung cho các tính năng tồn tại, nó không muốn chịu trách nhiệm điền vào các khoảng trống.

Ví dụ, con rối giả định rằng một dịch vụ điều khiển hệ thống không có reloadmặc định giết chết và khởi động lại quá trình . Nếu loại Dịch vụ [] đã thêm một cách để chỉ định tải lại tồn tại và nên sử dụng nó trong thông báo, thì nó sẽ cần tìm hiểu các dịch vụ nào có hoặc không có tải lại gốc. Đầu bếp và tất cả các hệ thống khác cũng sẽ phải học điều tương tự vì systemd muốn nó được giải quyết ở lớp đó. (MiniRant: để bắt đầu một hệ thống quy trình dường như là hệ thống hoàn toàn biết, gắn kết, tất cả các không gian tên tùy chỉnh i-do-mọi thứ tại lớp của tôi. Vì vậy, tôi không thể cho bạn biết lý do tại sao nó không mở rộng triết lý này để tải lại. Có lẽ một trong những tác giả có thể kêu vang ở đây.)


1
systemctl reload-or-restart, nó sẽ tải lại dịch vụ nếu nó hỗ trợ và khởi động lại nếu không. Không biết tại sao Puppet đưa ra giả định này.
Michael Hampton
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.