systemdサービスユニットファイルの動的変数


14

systemdサービスユニットファイルで環境変数を動的に割り当てる方法はありますか?

4つのGPUを搭載したマシンがあり、GPUごとに特定のサービスの複数のインスタンスをスピンアップする必要があります。例えば:

  • 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

注意が必要な場合は、インスタンスサービスファイルにexecコマンドとして小さなbashスクリプトシーケンスを組み込むことができます。例えば

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

$$文字列内の単一になります$のbashに渡された結果ではなく、もっと重要なのは停止します${...}systemdにによって補間されるから。(systemdの以前のバージョンではの使用について文書化されていなかったため$$、その時点でサポートされているかどうかはわかりません)。


私はそのようなことをすることになりました。:)
カル

1
を呼び出してbash -c、ユニットファイルからプログラムを起動しますか?電話exec?これは、最初のフォークリフトが実際にフォークリフトに問題があるため、フォークリフトの上にフォークリフトを使用するようなものです(別のフォークリフトを使用する場合もあります)。
デビッドトンホーファー

残念ながら、ExecStartPreを使用してenvファイルを作成してから使用することはできません。明らかに、事前に作成する必要があるため、このようなものが機能します。または、分割を行うラッパースクリプト:)もう1つの奇妙なオプションは、別のサービスを作成してenvをセットアップすることです。ファイルではなく、必ずそれはカントーのテンプレートでどのように動作するか:stackoverflow.com/a/42841480/32453
rogerdpack

8

邪魔にならない。サービスを開始する前に、これらのことを行う必要があります。1つの方法は、環境ファイルに置くことです。

[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=...

4

systemdユニットファイル内で環境変数を実際に設定できるようです...

コメンターからの提案ごとに、ここに解決策があります:

systemdユニットでの環境変数の使用

環境指令

systemdには、実行されたプロセスの環境変数を設定する環境ディレクティブがあります。変数割り当てのスペースで区切られたリストを取ります。このオプションは複数回指定できます。その場合、リストされているすべての変数が設定されます。同じ変数を2回設定すると、後の設定が前の設定を上書きします。空の文字列がこのオプションに割り当てられている場合、環境変数のリストはリセットされ、以前の割り当てはすべて無効になります。環境ディレクティブは、etcd2やflannelなど、組み込みのコンテナLinux systemdユニットで使用されます。

以下の例では、暗号化を使用するように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-reloadsudo systemctl restart etcd2.service新しい環境をetcd2デーモンに適用します。

次のURLから引用したテキスト:https : //coreos.com/os/docs/latest/using-environment-variables-in-systemd-units.html


2
これは理論的には質問に回答するかもしれませんが、ここに回答の重要な部分を含め、参照用のリンクを提供することが望ましいでしょう。
スティーブンラウチ

1
あなたのコメントは理論的にstackexchangeでの私の将来の応答を改善するかもしれませんが、あなたが無能である可能性を指摘するためにコメントするのではなく、あなたのコメントに答えの重要な部分を含めることが望ましいでしょう:)
Cyber​​K

1
Stack Exchangeへようこそ!コメントをありがとう、あなたは私を笑顔にした。また、回答を編集していただきありがとうございます。私たちは、時間の経過とともに価値をもたらすものを構築しようとしていますが、リンクのみの回答はあまり古くありません。
スティーブンラウフ

追加するEnvironment=ABC=%iと、その環境が設定されます。変数「%i全体」。不要な「引用を超えるもの」を取り除くラッパーを作成し、実際の実行可能ファイルを呼び出すことができると思います。ただし、ラッパーを作成している場合は%i、引数として渡すことさえできます。例:ExecStart=my_wrapper %i
-rogerdpack

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.