Systemd hizmet birimi dosyalarındaki dinamik değişkenler


15

Systemd hizmet birimi dosyasında ortam değişkenlerini dinamik olarak atamanın bir yolu var mı?

4 GPU'lu bir makinemiz var ve GPU başına belirli bir hizmetin birden fazla örneğini döndürmek istiyoruz. Örneğin:

  • gpu_service @ 1: 1. hizmet
  • gpu_service @ 2: 1. hizmet
  • gpu_service R3: 1. hizmet
  • gpu_service @ 4: 1. hizmet
  • gpu_service @ 1: 2.service
  • gpu_service @ 2: 2.service
  • gpu_service R3: 2.service
  • gpu_service @ 4: 2.service
  • nauseam

Böylece 1: 1, 2: 1, vb. Etkin bir şekilde hizmet birimi dosyasındaki% i değeridir.

Hizmetin belirli bir GPU'ya bağlanması için hizmet yürütülebilir dosyası belirli bir ortam değişkenini denetler, örneğin:

USE_GPU=4

% İ hizmet birimi dosyası içinde almak ve GPU numarasını türetmek için bazı (kabuk) işlevi ile çalıştırmak bir yolu var mı, ve sonra buna göre USE_GPU ortam değişkeni ayarlayabilirsiniz?

En önemlisi, birden fazla /etc/systemd/system/gpu_service@x:y.service/local.confdosya yazma zahmetini istemiyorum, bu yüzden daha fazla örneği döndürebilirim.

Yanıtlar:


10

Dikkatli olursanız, örnek hizmet dosyasında exec komutunuz olarak küçük bir bash komut dizisi ekleyebilirsiniz. Örneğin

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

$$Dizede tek olacak $bash geçirilen sonuçta, ama daha önemlisi duracaktır ${...}systemd tarafından interpolated olmaktan. (Systemd'in önceki sürümleri kullanımını belgelemedi $$, bu yüzden desteklenip desteklenmediğini bilmiyorum).


Sonunda böyle bir şey yaptım. :)
Kal

1
Bir Çağrı bash -cbirim dosyasından bir programı başlatmak için? Ara exec? Bu, bir forkliftin üzerinde bir forklift kullanmak gibidir (belki başka bir forklift ile), çünkü ilk forkliftin aslında forklift ile ilgili sorunu vardır.
David Tonhofer

Ne yazık ki bir env dosyası yazmak için bir ExecStartPre kullanamazsınız, sonra kullanın, görünüşe göre önceden yazılmış olması gerekir, böylece böyle bir şey işe yarayacaktır. Veya bölme yapmak için bir sarıcı komut dosyası :) Diğer tuhaf seçenek env kurmak için başka bir hizmet oluşturmak olacaktır. dosyası, bunun şablonlarla nasıl çalışacağından emin değilim tho: stackoverflow.com/a/42841480/32453
rogerdpack

8

Hiçbir şekilde inşa edilmiş. Hizmetiniz başlamadan önce bunları yapmanız gerekir. Bunun bir yolu onu bir ortam dosyasına koymak olabilir.

[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

Görünüşe göre bir systemd birim dosyasının içindeki ortam değişkenlerini ayarlayabilirsiniz ...

Yorum yapanların önerileri doğrultusunda, çözüm şöyledir:

Systemd birimlerinde ortam değişkenlerini kullanma

Çevre direktifi

systemd, yürütülen işlemler için ortam değişkenlerini ayarlayan bir Ortam direktifine sahiptir. Boşlukla ayrılmış değişken atamalarının bir listesini alır. Bu seçenek bir kereden fazla belirtilebilir, bu durumda listelenen tüm değişkenler ayarlanır. Aynı değişken iki kez ayarlanırsa, sonraki ayar önceki ayarı geçersiz kılar. Bu seçeneğe boş dize atanırsa, ortam değişkenleri listesi sıfırlanır, önceki atamaların hiçbir etkisi olmaz. Ortam direktifleri, etcd2 ve flannel gibi yerleşik Container Linux sistemd birimlerinde kullanılır.

Aşağıdaki örnekte etcd2 arka plan programınızı şifreleme kullanacak şekilde yapılandırabilirsiniz. Sadece oluşturmak /etc/systemd/system/etcd2.service.d/30-certificates.confaçılır kutusunu etcd2.service için:

[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

Sonra çalıştırın sudo systemctl daemon-reloadve sudo systemctl restart etcd2.serviceetcd2 artalanına yeni ortamlar uygulamak için.

Aşağıdaki URL'den alınan alıntılanan metin: https://coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html


2
Bu teorik olarak soruyu cevaplayabilse de , cevabın temel kısımlarını buraya eklemek ve referans için bağlantı sağlamak tercih edilir .
Stephen Rauch

1
Yorumunuz teorik olarak stackexchange'teki gelecekteki yanıtlarımı geliştirebilse de, birisinin ne kadar beceriksiz olabileceğini göstermek için yorum yapmak yerine cevabın temel bölümlerini yorumunuza
eklemeniz tercih edilir

1
Stack Exchange'e hoş geldiniz! Yorum için teşekkürler, beni güldürdün. Ayrıca yanıtınızı düzenlemek için zaman ayırdığınız için teşekkür ederiz. Zaman içinde değeri olan bir şey inşa etmeye çalışıyoruz ve sadece cevaplar çok iyi yaşlamıyor.
Stephen Rauch

Eğer eklerseniz Environment=ABC=%io env. "% i" nin bütününe değişken. Sanırım istemediğiniz "alıntı ötesinde şeyler" çıkarmak için bir sarıcı yapabilir ve gerçek yürütülebilir çağırır. Ancak bir sarıcı yapıyorsanız %i, bunun için bir argüman olarak bile geçebilirsiniz :ExecStart=my_wrapper %i
rogerdpack

Soru "dinamik" değişkenler içindi; bize statik çözümün cevabını verdiniz.
Otheus

0

Çirkin ve tam olarak ne istediğini değil, otomatik başlatmaya da izin vermez, ancak takipçiler için systemctl ortamını kullanarak bir şeyler yapmak mümkündür :

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

Sadece mümkün olan tüm yolları listelemeye çalışıyorum :)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.