שאלה כיצד להגדיר משתנה הסביבה בשירות systemd?


יש לי מערכת לינוקס עם מערכת ואני יצרתי שירות משלי. שירות התצורה בכתובת /etc/systemd/system/myservice.service נראה ככה:

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

עכשיו אני רוצה להיות משתנה הסביבה להגדיר עבור /bin/myforegroundcmd. איך אני עושה את זה?


119
2017-08-01 19:43






תשובות:


הזמנים משתנים וכך גם שיטות העבודה המומלצות.

ה הנוכחי הדרך הטובה ביותר לעשות זאת היא לרוץ systemctl edit myservice, אשר תיצור קובץ לעקוף בשבילך או לאפשר לך לערוך אחד קיים.

בהתקנות רגילות זה ייצור ספרייה /etc/systemd/system/myservice.service.d, ובתוך ספריה זו צור קובץ ששמו מסתיים .conf (בדרך כלל, override.conf), ובתיק זה ניתן להוסיף או לדרוס כל חלק של היחידה שנשלח על ידי ההפצה.

לדוגמה, בקובץ /etc/systemd/system/myservice.service.d/myenv.confYou

[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"

כמו כן, שים לב שאם הספרייה קיימת וריקה, השירות שלך יושבת! אם אתה לא מתכוון לשים משהו בספרייה, לוודא שזה לא קיים.


לשם כך, הדרך הישנה היתה:

הדרך המומלצת כדי לעשות זאת היא ליצור קובץ /etc/sysconfig/myservice אשר מכיל את המשתנים שלך, ולאחר מכן לטעון אותם עם EnvironmentFile.

לפרטים מלאים, עיין בתיעוד של Fedora איך לכתוב סקריפט.


144
2017-08-01 20:07



אני מניח sysconfig היא ספציפית פדורה אבל השאלה היא על Arch Linux. התשובה על ידי paluh מעניין יותר אני חושב - Ludovic Kuty
/etc/sysconfig היא ספציפית Fedora. AFAIR Arch Linux היה דוחף על כך את קבצי התצורה איפשהו חבילה ספציפית במקום /etc ולא את המיקום הספציפי של Fedora. כמו /etc/myservice.conf, אם כי באמצעות קובץ נוסף לא נראה את הדרך הנכונה כאן. - Michał Górny
לא לא לא. / etc / sysconfig אינו מומלץ. זה חסר משמעות, יחד עם / etc / default / * מ debian, כי הם חסרי טעם, והשמות הם חסרי משמעות הגיוני רק עבור תאימות לאחור הסיבות (כל / וכו 'הוא על תצורה של המערכת, לא רק / etc / sysconfig, ו / etc / defaults הוא עבור overrides, לא את ברירות מחדל). פשוט לשים את ההגדרות ישירות בקובץ היחידה, או אם זה בלתי אפשרי, בקובץ enviornment כי יש מקום ספציפי החבילה (כמו ההערה של Michał). - zbyszek
@ FrederickNord זה רק משתנה = זוגות ערך, כגון DJANGO_SETTINGS_MODULE=project.settings, אחד בכל שורה. - Michael Hampton♦
@ MichaelHampton אתה יכול בבקשה להוסיף קישור התיעוד "הנוכחי הטוב ביותר"? - jb.


התשובה תלויה אם המשתנה אמור להיות קבוע (כלומר, לא אמור להיות שונה על ידי המשתמש מקבל את היחידה) או משתנה (אמור להיות מוגדר על ידי המשתמש).

מאז זה היחידה המקומית שלך, הגבול הוא מטושטש למדי, או בכל מקרה יעבוד. עם זאת, אם אתה התחיל להפיץ את זה וזה יהיה בסופו של דבר /usr/lib/systemd/system, זה יהיה חשוב.

ערך קבוע

אם הערך לא צריך להשתנות לכל מקרה, הדרך המועדפת תהיה להציב אותו Environment=, ישירות בקובץ היחידה:

[Unit]
Description=My Daemon

[Service]
Environment="FOO=bar baz"
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

היתרון הוא שהמשתנה נשמר בקובץ יחיד עם היחידה. לכן, קל יותר לנוע בין המערכות.

ערך משתנה

עם זאת, הפתרון לעיל אינו פועל היטב כאשר sysadmin אמור לשנות את הערך של משתנה הסביבה מקומית. באופן ספציפי יותר, יהיה צורך להגדיר את הערך החדש בכל פעם שקובץ היחידה מתעדכן.

במקרה זה, יש להשתמש בקובץ נוסף. איך - בדרך כלל תלוי במדיניות ההפצה.

פתרון מעניין במיוחד הוא להשתמש /etc/systemd/system/myservice.service.d ספרייה. שלא כמו פתרונות אחרים, ספריה זו נתמכת על ידי systemd עצמה ולכן מגיע עם נתיבים ספציפיים להפצה.

במקרה זה, אתה שם קובץ כמו /etc/systemd/system/myservice.service.d/local.conf המוסיפה את החלקים החסרים של קובץ היחידה:

[Service]
Environment="FOO=bar baz"

לאחר מכן, systemd מיזוג שני הקבצים בעת הפעלת השירות (זכור systemctl daemon-reload לאחר שינוי אחד מהם). ומאז נתיב זה משמש ישירות על ידי systemd, אתה לא משתמש EnvironmentFile= לזה.

אם הערך אמור להשתנות רק בחלק מהמערכות המושפעות, באפשרותך לשלב את שני הפתרונות, לספק ברירת מחדל ישירות ליחידה ולעקוף מקומית בקובץ השני.


67
2018-04-23 07:48



systemctl daemon-reload היא הפקודה כדי לטעון מחדש את systemd - Dmitry Buzolin
EnvironmentFile= הוא טוב יותר כאשר הערכים הם סודות כמו סיסמאות. ראה התשובה שלי לפרטים. - Don Kirkby


http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - יש לך שתי אפשרויות (אחת כבר הצביע על ידי מיכאל):

Environment=

ו

EnvironmentFile=

34
2017-10-16 13:55





מייקל נתן אחד פתרון נקי אבל רציתי לקבל משתנה env משתנה מ סקריפט. למרבה הצער, ביצוע פקודות bash אינו אפשרי בקובץ יחידת systemd. למרבה המזל אתה יכול להפעיל bash בתוך ExecStart:

http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&ampect=5

שים לב שהגדרה זו אינה תומכת ישירות בקווי פקודות של פגז. אם קווי הפקודה פגז הם לשמש הם צריכים להיות מועברים במפורש ליישום פגז כלשהו.

דוגמה במקרה שלנו היא אז:

[Service]
ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"

6
2017-07-23 13:31



זה לא יעבוד מסיבות מרובות (אלא אם כן זה "one-shot" שירות, וזה חסר טעם למדי). הצלחתי להשיג את הדברים הבאים: /bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program'. ה -a מבטיח שהסביבה מיוצאת לתת-התהליך (אלא אם כן אתה רוצה להקדים את כל המשתנים whatever עם export ) - Otheus
למה זה לא יעבוד? זה תמיד צריך להפעיל כל הפקודה הכוללת ביצוע סקריפט, לא? - user1830432
אולי ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd הוא פתרון קצת יותר טוב במקרה זה. - kstep
@ Otheus: תשובה נהדרת, נשמר על ידי יום כאשר הייתי צריך ליצור קובץ Tomcat 8 יחידה. - Daniel
יש דרך לבצע פקודת bash "ב" קובץ שירות systemd. ראה קישור זה: coreos.com/os/docs/latest/... - Mark Lakata


התשובות על ידי מיכאל ו מיכל הם מועילים לענות על השאלה המקורית כיצד להגדיר משתנה סביבה עבור שירות systemd. עם זאת, אחד שימוש נפוץ עבור משתני סביבה היא להגדיר נתונים רגישים כמו סיסמאות במקום שלא ייעשה בטעות מחויבת בקרת מקור עם קוד היישום שלך.

אם זה למה אתה רוצה להעביר משתנה הסביבה לשירות שלך, אל להשתמש Environment= בקובץ תצורת היחידה. להשתמש EnvironmentFile= ואת הצבע אותו לקובץ תצורה אחר כי הוא לקריא רק על ידי חשבון שירות (ומשתמשים עם גישה שורש).

הפרטים של קובץ תצורת היחידה גלויים לכל משתמש עם פקודה זו:

systemctl show my_service

שמתי קובץ תצורה ב /etc/my_service/my_service.conf ושם את סודותי שם:

MY_SECRET=correcthorsebatterystaple

ואז בתיק השירות שלי, השתמשתי EnvironmentFile=You

[Unit]
Description=my_service

[Service]
ExecStart=/usr/bin/python /path/to/my_service.py
EnvironmentFile=/etc/my_service/my_service.conf
User=myservice

[Install]
WantedBy=multi-user.target

בדקתי את זה ps auxe לא יכול לראות את משתני הסביבה האלה, ולמשתמשים אחרים אין גישה /proc/*/environ. בדוק על המערכת שלך, כמובן.


6
2018-05-04 00:29