시스템 서비스 단위 파일의 동적 변수


14

시스템화 된 서비스 단위 파일에서 환경 변수를 동적으로 지정하는 방법이 있습니까?

GPU가 4 개인 머신이 있으며 GPU 당 특정 서비스의 여러 인스턴스를 스핀 업하려고합니다. 예 :

  • gpu_service @ 1 : 1.service
  • 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를 가져 와서 일부 (쉘) 기능을 통해 GPU 번호를 도출 한 다음 USE_GPU 환경 변수를 적절하게 설정할 수있는 방법이 있습니까?

가장 중요한 것은 /etc/systemd/system/gpu_service@x:y.service/local.conf더 많은 인스턴스를 스핀 할 수 있도록 여러 파일 을 작성하는 번거 로움을 원하지 않습니다 .

답변:


10

주의를 기울이면 인스턴스 서비스 파일에서 작은 bash 스크립트 시퀀스를 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 파일을 작성한 다음 사용할 수는 없습니다. 분명히 미리 작성해야하므로 이런 식으로 작동합니다. 또는 분리를 수행하는 래퍼 스크립트 :) 다른 기괴한 옵션은 환경을 설정하기 위해 다른 서비스를 만드는 것입니다. 파일, 모르겠 즉 그래도 템플릿 어떻게 작동하는지 : 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에는 실행 된 프로세스에 대한 환경 변수를 설정하는 Environment 지시문이 있습니다. 공백으로 구분 된 변수 할당 목록이 필요합니다. 이 옵션은 두 번 이상 지정 될 수 있으며이 경우 나열된 모든 변수가 설정됩니다. 동일한 변수를 두 번 설정하면 나중에 설정이 이전 설정보다 우선합니다. 빈 문자열이이 옵션에 지정되면 환경 변수 목록이 재설정되고 모든 이전 지정은 적용되지 않습니다. 환경 지시문은 내장 Container Linux 시스템 단위 (예 : etcd2 및 flannel)에서 사용됩니다.

아래 예에서 암호화를 사용하도록 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.serviceetcd2 데몬에 새로운 환경을 적용 할 수 있습니다.

다음 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하면 해당 환경이 설정됩니다. 변수 "% i 전체에". 나는 당신이 원하지 않는 "따옴표 이상의 물건"을 제거하기 위해 래퍼를 만들 수 있다고 생각하며 실제 실행 파일을 호출합니다. 그러나 래퍼를 만드는 경우 다음 %i과 같이 인수로 전달할 수도 있습니다 .ExecStart=my_wrapper %i
rogerdpack

문제는 "동적"변수에 대한 것이었다. 정적 솔루션에 대한 답변을 제공했습니다.
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.