Systemd सेवा इकाई फ़ाइलों में डायनामिक चर


15

वहाँ एक systemd सेवा इकाई फ़ाइल में पर्यावरण चर को गतिशील रूप से असाइन करने का एक तरीका है?

हमारे पास एक मशीन है जिसमें 4 जीपीयू हैं, और हम प्रति जीपीयू की एक निश्चित सेवा के कई उदाहरणों को स्पिन करना चाहते हैं। उदाहरण के लिए:

  • gpu_service @ 1: 1.service
  • gpu_service @ 2: 1.service
  • gpu_service @ 3: 1.service
  • gpu_service @ 4: 1.service
  • 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 ले सकता हूं और GPU नंबर प्राप्त करने के लिए इसे कुछ (शेल) फ़ंक्शन के माध्यम से चला सकता हूं, और फिर मैं तदनुसार USE_GPU पर्यावरण चर सेट कर सकता हूं?

सबसे महत्वपूर्ण बात यह है कि मैं एक से अधिक /etc/systemd/system/gpu_service@x:y.service/local.confफाइलें लिखने की झंझट नहीं चाहता, इसलिए मैं अधिक उदाहरणों को लिख सकता हूं।

जवाबों:


10

यदि आप सावधान हैं, तो आप उदाहरण सेवा फ़ाइल में अपने निष्पादन कमांड के रूप में एक छोटा सा बैश स्क्रिप्ट अनुक्रम शामिल कर सकते हैं। उदाहरण के लिए

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

$$स्ट्रिंग में एक भी बन जाएगा $परिणाम बैश के लिए पारित किया है, लेकिन अधिक महत्वपूर्ण बंद हो जाएगा ${...}systemd द्वारा अंतर्वेशित होने से। (सिस्टमड के पहले के संस्करणों ने इसके उपयोग का दस्तावेज नहीं बनाया था $$, इसलिए मुझे नहीं पता कि यह तब समर्थित था)।


मैंने ऐसा कुछ करना समाप्त कर दिया। :)
काल

1
bash -cयूनिट फ़ाइल से प्रोग्राम शुरू करने के लिए कॉल करें ? बुलाओ exec? यह एक फोर्कलिफ्ट के शीर्ष पर एक फोर्कलिफ्ट का उपयोग करने जैसा है (शायद शीर्ष पर एक और फोर्कलिफ्ट के साथ) क्योंकि पहले फोर्कलिफ्ट को वास्तव में टखने में परेशानी होती है।
डेविड टोनहोफर

दुर्भाग्य से आप एक Enec फ़ाइल लिखने के लिए ExecStartPre का उपयोग नहीं कर सकते हैं, तो इसका उपयोग करें, जाहिर है इसे पहले से लिखा जाना है, इसलिए ऐसा कुछ काम करेगा। या बंटवारा करने के लिए एक आवरण स्क्रिप्ट :) अन्य विचित्र विकल्प एनवी को सेटअप करने के लिए एक और सेवा बनाने के लिए होगा। फ़ाइल, निश्चित नहीं है कि कैसे यह टेम्पलेट के साथ काम करेगा: 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 में एक पर्यावरण निर्देश है जो निष्पादित प्रक्रियाओं के लिए पर्यावरण चर निर्धारित करता है। यह चर असाइनमेंट की एक अलग-अलग सूची लेता है। यह विकल्प एक से अधिक बार निर्दिष्ट किया जा सकता है जिस स्थिति में सभी सूचीबद्ध चर सेट किए जाएंगे। यदि समान चर दो बार सेट किया गया है, तो बाद की सेटिंग पहले की सेटिंग को ओवरराइड कर देगी। यदि रिक्त स्ट्रिंग को इस विकल्प को सौंपा गया है, तो पर्यावरण चर की सूची रीसेट हो जाती है, सभी पूर्व असाइनमेंट पर कोई प्रभाव नहीं पड़ता है। वातावरण के निर्देशों का उपयोग बिल्ट-इन कंटेनर लिनक्स सिस्टमड इकाइयों में किया जाता है, उदाहरण के लिए etcd2 और फलालैन में।

नीचे दिए गए उदाहरण के साथ, आप एन्क्रिप्शन का उपयोग करने के लिए अपने etcd2 डेमॉन को कॉन्फ़िगर कर सकते हैं। बस /etc/systemd/system/etcd2.service.d/30-certificates.confetcd2.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.serviceetcd2 डेमन पर नए वातावरण लागू करें।

निम्नलिखित URL से लिया गया कोटेड टेक्स्ट: https://coreos.com/os/docs/latest/use-environment-variables-in-systemd-units.html


2
हालांकि यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक हिस्सों को यहां शामिल करना बेहतर होगा , और संदर्भ के लिए लिंक प्रदान करें।
स्टीफन राउच

1
हालांकि आपकी टिप्पणी सैद्धांतिक रूप से स्टेक्सएक्सचेंज में मेरी भविष्य की प्रतिक्रियाओं में सुधार कर सकती है, लेकिन आपके लिए यह बेहतर होगा कि आप टिप्पणी करने के बजाय अपनी टिप्पणी में उत्तर के आवश्यक भागों को शामिल करें, यह
बताने के लिए

1
स्टैक एक्सचेंज में आपका स्वागत है! टिप्पणी के लिए धन्यवाद, आपने मुझे मुस्कुरा दिया। अपना उत्तर संपादित करने के लिए समय निकालने के लिए भी धन्यवाद। हम कुछ ऐसा बनाने की कोशिश कर रहे हैं जिसका समय के साथ मूल्य हो, और केवल जवाबों को लिंक करें, बहुत अच्छी तरह से उम्र नहीं है।
स्टीफन राउच

यदि आप Environment=ABC=%iइसे जोड़ते हैं तो वह एनवी सेट करता है। चर "% i की संपूर्णता में"। मुझे लगता है कि आप "बोली से परे सामान" को छीनने के लिए एक रैपर बना सकते हैं जो आप नहीं चाहते हैं, और यह वास्तविक निष्पादन योग्य कहता है। लेकिन अगर आप एक रैपर बना रहे हैं, तो आप %iइसे पूर्व के तर्क के रूप में भी पारित कर सकते हैं :ExecStart=my_wrapper %i
रॉगरडैक

सवाल "गतिशील" चर के लिए था; आपने बस हमें स्थैतिक समाधान के लिए जवाब दिया है।
ओथियस

0

यह बदसूरत और काफी नहीं है जो आपने मांगा था, न ही यह ऑटोस्टार्ट के लिए अनुमति देता है, लेकिन अनुयायियों के लिए यह व्यवस्थित वातावरण का उपयोग करके कुछ करना संभव है :

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

बस सभी तरीकों की सूची बनाने की कोशिश कर रहा है :)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.