Làm thế nào để tạo một dịch vụ systemd ảo để dừng / bắt đầu một số trường hợp cùng nhau?


12

Tôi dự định lưu trữ một số phiên bản của cùng một ứng dụng web cho khách hàng sử dụng systemd. Tôi muốn có thể stopstarttừng trường hợp khách hàng sử dụng systemd, cũng như coi toàn bộ tập hợp các trường hợp khách hàng là một dịch vụ duy nhất có thể dừng lại và bắt đầu cùng nhau.

systemddường như cung cấp các khối xây dựng mà tôi cần sử dụng PartOfvà các tệp đơn vị mẫu, nhưng tôi đã dừng dịch vụ mẹ, dịch vụ khách hàng con không bị dừng. Làm thế nào tôi có thể làm cho điều này làm việc với systemd? Đây là những gì tôi có cho đến nay.

Tệp đơn vị mẹ , app.service:

[Unit]
Description=App Web Service

[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal

Tệp mẫu đơn vị có tên app@.service, được sử dụng để tạo phiên bản khách hàng:

[Unit]
Description=%I Instance of App Web Service

[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal

app-poc.shTập lệnh của tôi (Bằng chứng về khái niệm chỉ in ra tệp nhật ký trong một vòng lặp):

#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
  echo "The App PoC loop for $@"
  sleep 2;
done

Để chứng minh khái niệm, tôi đã có các tệp đơn vị systemd ~/.config/systemd/user.

Sau đó tôi khởi động cha mẹ và một thể hiện dựa trên mẫu (sau systemctl --user daemon-reload):

systemctl --user start app
systemctl --user start app@customer.service

Từ việc sử dụng journalctl -ftôi có thể thấy rằng cả hai đã bắt đầu và cá thể khách hàng tiếp tục chạy. Bây giờ tôi hy vọng việc đóng cửa cha mẹ sẽ ngăn chặn đứa trẻ (vì tôi đã sử dụng PartOf), nhưng nó không. Ngoài ra, bắt đầu cha mẹ cũng không bắt đầu đứa trẻ như mong đợi.

systemctl --user stop app

Cảm ơn!

(Tôi đang sử dụng Ubuntu 16.04 với systemd 229).


1
"PartOf = Định cấu hình các phụ thuộc tương tự như Yêu cầu =, nhưng giới hạn ở việc dừng và khởi động lại các đơn vị." Nếu bạn muốn bắt đầu làm việc, bạn không cần phải sử dụng Requires=thay thế?
nguồn

Câu trả lời:


10

Bạn cần di chuyển dòng

PartOf=app.service

ra khỏi [Service]và vào [Unit]phần, và thêm vào [Unit]các app.servicedanh sách khách hàng để bắt đầu, ví dụ

Wants=app@customer1.service app@customer2.service

hoặc như sourcejedi đã nói trong các bình luận, Requires=điều tương tự. Bạn có thể giữ các PartOfdịch vụ dừng bạn bắt đầu bằng tay không có trong danh sách trên, như thế nào systemctl --user start app@customer3.service.


Tôi xác nhận bạn đã đúng về PartOf. Cảm ơn. Tôi sẽ xử lý "Muốn" thông qua một liên kết tượng trưng, ​​trở thành hành động duy nhất tôi cần thực hiện để kích hoạt một khách hàng mới với systemd. Đối với trường hợp thử nghiệm của tôi: `ln -s /home/mark/.config/systemd/user/app@.service / home / mark / .config / systemd / user / app.service.wants / unity @ foo.service`
Mark Stosberg

13

Tôi đã học được rằng đây là những gì "Đơn vị mục tiêu" dành cho hệ thống. Bằng cách sử dụng Đơn vị mục tiêu, tôi nhận được những lợi ích tôi muốn mà không cần phải tạo phần giả [Service]mà tôi có ở trên. Một ví dụ hoạt động tệp "Đơn vị mục tiêu" trông như thế này:

# named like app.target
[Unit]
Description=App Web Service

# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target

Sau đó, mỗi trường hợp khách hàng nên bao gồm PartOftrong [Unit]phần (như được chỉ ra bởi @meuh) và cũng nên có một [Install]phần để enabledisablesẽ hoạt động trên dịch vụ cụ thể:

# In a file name like app@.service
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target

[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal

# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp

# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target

Để hiển thị phiên bản khách hàng và khởi động khi mục tiêu được bắt đầu, lệnh kích hoạt một lần này được sử dụng:

 systemctl enable app

Tại thời điểm này tôi có thể sử dụng stopstarttrên app@customerđể cho một trường hợp cụ thể, hoặc tôi có thể sử dụng start appstop appngăn chặn tất cả các ứng dụng với nhau.


Làm thế nào về tình trạng? Tôi không thể tìm thấy một cách đơn giản để có trạng thái của tất cả các dịch vụ mà Ứng dụng muốn. Tôi biết làm thế nào tôi có thể viết kịch bản đó, nhưng ...
Tommi Kyntola

1
Ý tôi là giống như nhận được trạng thái của các ứng dụng trong nhóm mục tiêu đó mà không liệt kê tất cả những gì là một phần của nó, thẻ hoang dã hay không, tốt nhất là sử dụng tên nhóm đó và thậm chí không quan tâm đến những gì nó được tạo ra.
Tommi Kyntola

2
Nó không đơn giản. Tập lệnh đó thuộc về gói nào? Nó sẽ phải được sửa đổi mỗi khi một thành phần mới được thêm vào. Quên điều đó và triển khai / bảo trì đi haywire. Điều tôi rõ ràng muốn là chỉ cần thêm một gói mới với cài đặt partOf cho thấy sự hiện diện của nó trong nhóm đó và sau đó không sửa đổi một số tập lệnh còn sót lại. Và sau đó dừng lại và bắt đầu mục tiêu đó hoạt động như trước. Điều này hoạt động, nhưng tình trạng dường như rơi ra khỏi phạm vi đó. Tôi thậm chí không thể tìm ra cách để có được danh sách các đơn vị đang có thời gian chạy trong mục tiêu. Trường hợp sử dụng này không được bao phủ bởi systemd.
Tommi Kyntola

2
@TommiKyntola Đây là một bash one-liner mà bạn không cần cập nhật khi phụ thuộc mục tiêu thay đổi:systemctl status $(systemctl list-dependencies --plain otp.target)
Mark Stosberg

2
@TommiKyntola Tôi đồng ý rằng systemdcó thể cải thiện khả năng sử dụng ở đây. Tôi đã mở một yêu cầu tính năng để đề xuất trạng thái được cải thiện cho các mục tiêu.
Mark Stosberg
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.