ตัวแปรแบบไดนามิกในไฟล์หน่วยบริการ systemd


14

มีวิธีการกำหนดตัวแปรสภาพแวดล้อมในไฟล์ systemd service unit หรือไม่

เรามีเครื่องที่มี 4 GPU และเราต้องการที่จะหมุนบริการหลายอย่างต่อหนึ่ง GPU เช่น:

  • gpu_service @ 1: 1. บริการ
  • gpu_service @ 2: 1. บริการ
  • gpu_service @ 3: 1. บริการ
  • gpu_service @ 4: 1. บริการ
  • gpu_service @ 1: 2.service
  • gpu_service @ 2: 2.service
  • gpu_service @ 3: 2.service
  • gpu_service @ 4: 2.service
  • โฆษณาคลื่นไส้

ดังนั้น 1: 1, 2: 1 ฯลฯ จึงเป็น% i อย่างมีประสิทธิภาพในไฟล์หน่วยบริการ

เพื่อให้บริการเชื่อมโยงกับ GPU ที่เฉพาะเจาะจงตัวดำเนินการบริการจะตรวจสอบตัวแปรสภาพแวดล้อมบางอย่างเช่น:

USE_GPU=4

มีวิธีที่ฉันสามารถใช้% i ในไฟล์ service unit และเรียกใช้ผ่านฟังก์ชั่น (shell) เพื่อรับหมายเลข GPU จากนั้นฉันสามารถตั้งค่าตัวแปรสภาพแวดล้อม USE_GPU ได้หรือไม่

ที่สำคัญที่สุดคือฉันไม่ต้องการความยุ่งยากในการเขียน/etc/systemd/system/gpu_service@x:y.service/local.confไฟล์หลาย ๆไฟล์เพียงเพื่อให้สามารถหมุนอินสแตนซ์ได้มากขึ้น

คำตอบ:


10

หากคุณระมัดระวังคุณสามารถรวมลำดับ bash script ขนาดเล็กเป็นคำสั่ง exec ของคุณในไฟล์บริการอินสแตนซ์ เช่น

ExecStart=/bin/bash -c 'v=%i; USE_GPU=$${v%:*} exec /bin/mycommand'

$$ในสตริงจะกลายเป็นหนึ่งเดียว$ในผลที่ได้ส่งผ่านไปยังทุบตี แต่ที่สำคัญกว่าจะหยุด${...}จากการถูกสอดแทรกโดย systemd (systemd รุ่นก่อนหน้านี้ไม่ได้บันทึกการใช้$$ดังนั้นฉันไม่รู้ว่ามันรองรับหรือไม่)


ในที่สุดฉันก็ทำอะไรแบบนั้น :)
Kal

1
เรียก a bash -cเพื่อเริ่มโปรแกรมจากไฟล์หน่วย? โทรexec? นี่เหมือนกับการใช้รถยกที่ด้านบนของรถยก (อาจจะเป็นรถยกอีกคันที่อยู่ด้านบน) เพราะรถยกคันแรกมีปัญหาในการยกของจริง
David Tonhofer

น่าเสียดายที่คุณไม่สามารถใช้ ExecStartPre เพื่อเขียนไฟล์ env จากนั้นใช้มันดูเหมือนจะต้องเขียนไว้ล่วงหน้าดังนั้นสิ่งนี้จะใช้ได้ หรือสคริปต์ตัวตัดเพื่อแยก :) ตัวเลือกที่แปลกประหลาดอื่น ๆ จะสร้างบริการอื่นเพื่อตั้งค่า env ไฟล์ไม่แน่ใจว่าจะใช้งานกับเทมเพลตได้อย่างไร: stackoverflow.com/a/42841480/32453
rogerdpack

8

ไม่มีการสร้างในทาง คุณต้องทำสิ่งเหล่านี้ก่อนเริ่มให้บริการ วิธีหนึ่งจะนำไปไว้ในไฟล์สภาพแวดล้อม

[Service]
# Note you need to escape percentage sign
ExecStartPre=/bin/sh -c "my_awesome_parser %%i > /run/gpu_service_%i"
EnvironmentFile=/run/gpu_service_%i
ExecStart=...

3

ดูเหมือนว่าคุณสามารถตั้งค่าตัวแปรสภาพแวดล้อมในไฟล์หน่วย systemd ...

ตามคำแนะนำจากผู้แสดงความคิดเห็นต่อไปนี้เป็นวิธีแก้ปัญหา:

การใช้ตัวแปรสภาพแวดล้อมในหน่วย systemd

คำสั่งด้านสิ่งแวดล้อม

systemd มีคำสั่ง Environment ซึ่งกำหนดตัวแปรสภาพแวดล้อมสำหรับกระบวนการที่ดำเนินการ รายการการมอบหมายตัวแปรคั่นด้วยช่องว่าง ตัวเลือกนี้อาจมีการระบุมากกว่าหนึ่งครั้งซึ่งในกรณีนี้ตัวแปรทั้งหมดที่ระบุไว้จะถูกตั้งค่า หากตั้งค่าตัวแปรเดียวกันสองครั้งการตั้งค่าในภายหลังจะแทนที่การตั้งค่าก่อนหน้า หากสตริงว่างถูกกำหนดให้กับตัวเลือกนี้รายการตัวแปรสภาพแวดล้อมจะถูกรีเซ็ตการมอบหมายก่อนหน้านี้ทั้งหมดจะไม่มีผลกระทบ คำสั่งของสภาพแวดล้อมถูกใช้ในหน่วยคอนเทนเนอร์ Linux systemd ที่มีอยู่แล้วตัวอย่างเช่นใน etcd2 และผ้าสักหลาด

ด้วยตัวอย่างด้านล่างคุณสามารถกำหนดค่า etcd2 daemon ของคุณเพื่อใช้การเข้ารหัส เพียงสร้าง/etc/systemd/system/etcd2.service.d/30-certificates.confdrop-in สำหรับ etcd2.service:

[Service]
# Client Env Vars
Environment=ETCD_CA_FILE=/path/to/CA.pem
Environment=ETCD_CERT_FILE=/path/to/server.crt
Environment=ETCD_KEY_FILE=/path/to/server.key
# Peer Env Vars
Environment=ETCD_PEER_CA_FILE=/path/to/CA.pem
Environment=ETCD_PEER_CERT_FILE=/path/to/peers.crt
Environment=ETCD_PEER_KEY_FILE=/path/to/peers.key

จากนั้นรันsudo systemctl daemon-reloadและsudo systemctl restart etcd2.serviceเพื่อใช้สภาวะแวดล้อมใหม่กับ etcd2 daemon

ข้อความที่ยกมาจาก URL ต่อไปนี้: https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html


2
ในขณะที่สิ่งนี้อาจตอบคำถามในทางทฤษฎีมันก็ควรที่จะรวมส่วนสำคัญของคำตอบที่นี่และให้ลิงค์สำหรับการอ้างอิง
Stephen Rauch

1
ในขณะที่ความคิดเห็นของคุณในทางทฤษฎีอาจปรับปรุงการตอบสนองในอนาคตของฉันใน stackexchange มันจะดีกว่าสำหรับคุณที่จะได้รวมส่วนสำคัญของคำตอบในความคิดเห็นของคุณแทนเพียงการแสดงความคิดเห็นเพื่อชี้ให้เห็นว่าคนที่ไร้ความสามารถอาจจะ :)
CyberK

1
ยินดีต้อนรับสู่ Stack Exchange! ขอบคุณสำหรับความคิดเห็นคุณทำให้ฉันยิ้มได้ นอกจากนี้ขอขอบคุณที่สละเวลาแก้ไขคำตอบของคุณ เรากำลังพยายามสร้างบางสิ่งบางอย่างที่จะมีค่าเมื่อเวลาผ่านไปและเชื่อมโยงคำตอบเท่านั้นไม่อายุดี
Stephen Rauch

หากคุณเพิ่มEnvironment=ABC=%iจะตั้งค่าที่ env ตัวแปร "เป็น% i ทั้งหมด" ฉันเดาว่าคุณสามารถทำเสื้อคลุมเพื่อตัด "สิ่งที่เกินคำพูด" ที่คุณไม่ต้องการและมันเรียกว่าปฏิบัติการจริง แต่ถ้าคุณกำลังทำ wrapper คุณก็สามารถผ่าน%iเข้าไปเป็นข้อโต้แย้งกับมันได้เช่นกันExecStart=my_wrapper %i
23419

คำถามคือสำหรับตัวแปร "ไดนามิก"; คุณเพียงแค่ให้คำตอบสำหรับการแก้ปัญหาแบบคงที่กับเรา
Otheus

0

มันน่าเกลียดและไม่ใช่สิ่งที่คุณขอและไม่อนุญาตให้ทำการเริ่มอัตโนมัติ แต่สำหรับผู้ติดตามคุณสามารถทำบางสิ่งได้โดยใช้สภาพแวดล้อม systemctl :

$ sudo systemctl set-environment USE_GPU=4 # add it to the env. variables for future services
$ sudo systemctl start gpu_service@4:2.service

เพียงแค่พยายามแสดงรายการวิธีทั้งหมดที่เป็นไปได้ :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.