Який кращий спосіб зберігання конфігурацій додатків?


38

Більшу частину часу я зберігаю конфігурацію програми розробки в кореневому каталозі проекту, наприклад:

app
|-- config.json

Але це здається не найкращим підходом, оскільки ця конфігурація зберігається в системі контролю версій - можливо, це призводить до витоку імен користувачів, паролів та інших чутливих речей.

12 Посібник із програми Factor рекомендує взагалі видаляти конфігураційні файли та використовувати змінні середовища для налаштування:

... зберігає конфігурацію у змінних середовища. Env vars легко змінювати між пристроями без зміни коду; на відміну від конфігураційних файлів, мало шансів випадково їх перевірити в код репо; і на відміну від користувальницьких конфігураційних файлів або інших механізмів конфігурації, таких як Властивості системи Java, вони є мовним та оперативним стандартом ОС.

Це звучить дуже добре для мене, але де можна зберігати вказані змінні середовища, не перевіряючи їх на контроль джерел? І якими інструментами я можу скористатися для передачі цих змінних у додаток? Тут може бути кілька десятків параметрів конфігурацій, і вводити їх вручну кожного разу, коли ви запускаєте додаток, це не приємно - тому їх треба десь зберігати у якомусь файлі. Таким чином, згаданий файл опиниться в контролі джерела, і ми повернемося туди, де ми почали.

Чи існує якийсь загальновизнаний спосіб обробки параметрів конфігурації, який не ризикує зберегти локальну конфігурацію в керуванні джерелами?


1
Ну, принаймні, git має щось на зразок, .gitignoreде я можу визначити файли чи папки, які не слід перевіряти в контролі версій. Як ви кажете, я не бачу, де Env vars дійсно повинен допомогти, якщо у вас є сценарій для їх встановлення, і його слід зберігати разом з проектом, або у вас є "десь" у вашій системі (домашній каталог або навіть у запуску машин. сценарії), які, здається, створюють цілу масу проблем самостійно, особливо якщо потрібна велика кількість конфігурацій. У будь-якому випадку я б розділив конфігураційні файли, щоб конфіденційна інформація містилася в різних файлах.
thorsten müller

@ thorstenmüller - проблема лише з .gitignore, що конфігурація бази / шаблону все ще має зберігатися, а це означає, що додаток має прочитати два конфігурації - основну, з параметрами за замовчуванням (зберігається в scm) та локальну, що перекриває базу (і не зберігається в scm). З точки зору env vars, я думаю, що масове розгортання стає простішим - простіше вказати змінні середовища для нового налаштування віртуальної машини, ніж написати щось у якийсь нестандартний файл.
Рогач

Хороший запитання. Після того, як я почав використовувати для цього звичайний сховище даних для користувачів, життя стало простішим ;-)
Вовк

1
Ви пробували "Redis" redis.io . Він призначений спеціально лише для зберігання структури ключових значень.
Каран

2
@jporcenaluk - Мені подобаються сховища ключових значень, але додавання повноцінного редагування в додаток просто для управління конфігураційним керуванням відчуває себе трохи зайвим. З іншого боку, можливо, я ніколи не працював над досить великими проектами.
Рогач

Відповіді:


16

Можливо, на це немає жодної хорошої відповіді. Схоже, що вам потрібно зберігати ці дані десь безпечно, оскільки вони знадобляться для цілей відновлення аварій одного дня. Це однаковою мірою стосується файлів властивостей та сценаріїв, які встановлюють змінні середовища.

  • З вихідним кодом (у SVN / GIT тощо) це дуже погана ідея, оскільки ці дані містять паролі виробничої бази даних тощо.
  • Ваша корпоративна нічна резервна копія може бути достатньою, але навряд чи збережеш легкодоступну історію змін.
  • Дані потрібно підбирати окремо до програмного забезпечення, що споживає. У нашій нинішній системі зміна конфігурації призводить до нового складання програми, і це просто неправильно.

Зараз ми розглядаємо рішення цієї проблеми і схиляємось до сховища коду з обмеженим доступом. Це сховище міститиме лише дані про конфігурацію. Чи мають інші поділитися досвідом?


2
Наявність двох окремих сховищ для одного проекту здається не дуже хорошою ідеєю - ви не можете робити чисті відкати або працювати з гілками, тому що тоді вам потрібно буде маніпулювати двома сховищами одночасно (наприклад, інша гілка вимагає певного нового параметра налаштування, і коли ви переключившись на цю нову гілку, не переходячи також у сховище конфігурацій, речі розбиваються дивним чином).
Рогач

2
@Rogach Я сприймаю вашу думку. Є вагомі причини, щоб зберегти певну конфігурацію з кодом, але, як ви говорите у своєму запитанні, чутливі речі повинні йти в інше місце. Тож два сховища здаються неминучими. Також я не згадував, що тут часто допомагають сервери додатків. Джерела даних та змінні JNDI можуть бути налаштовані адміністратором і не будуть загальнодоступними.
ківірон

Другий магазин має сенс. Можливо, існують і інші види даних, також конфіденційні, які можуть зберігатися разом із конфігурацією (наприклад, виробничі дані, які знаходяться в аналізі для вирішення проблем клієнтів).
Вовк

1
@Rogach Вони, здається, приваблюють велику кількість ненависті, але підмодулі git впораються з цим просто чудово, я думаю - якби основний був налаштований правильно, а репо з обмеженим доступом просто могли б жити всередині нього.
РідкоНеді

9

Досліджуючи проблеми та можливі рішення, мені допомагає використовувати метод, популяризований Джеффом Етвудом : Якби Бог створив спосіб зберігання конфіденційної інформації про конфігурацію, як би це зробити?

Ну, він би знав, кому потрібна інформація про конфігурацію, і надаватиме її лише тим людям, і до цієї інформації ніхто ніколи не зможе отримати доступ.

Першу частину вже слід подбати про те, щоб ваша система управління джерелами повинна бути аутентифікацією користувачів. І цей підхід також надає обгрунтованість згідно з №10 у 10 Заповідях управління джерелами Трої Хант , "залежності повинні бути в контролі джерел".

Але як зберегти його в безпеці, якщо воно просочилося? Ну, це не потрібно зберігати там у простому тексті! Використовуйте шифрування. У .NET є кроки, які ви можете виконати для шифрування даних рядкових з'єднань у своїх конфігураційних файлах . Вам доведеться знайти еквівалентні методи, щоб зробити це відповідно до вашої конкретної технології.


3
Просто хотів уточнити - як допоможе конфігурація шифрування? Як я розумію, вам потрібно буде поділитися однаковим паролем розшифровки між усіма розробниками, і це звучить як заклик до проблем.
Рогач

Якщо хтось за межами вашої компанії отримує доступ до вашого сховища, ваші паролі затуманено. Якщо хтось копіює файли з проекту на USB-накопичувач і залишає його десь, те саме. Зробити це буде більше роботи, звичайно. Більше безпеки зазвичай надходить за ціною зручності. Це рішення трохи непростий, я вам це дам. Я відкритий для кращого способу вирішити питання ОП!
jporcenaluk

5

Багато людей критикують збереження конфігурації у звичайних файлах разом із вихідним кодом, але, на мій досвід, це насправді досить гарне рішення:

  • Простий в реалізації будь-якою мовою. У багатьох випадках ви отримуєте підтримку складних файлів конфігурації. Наприклад, у випадку Java з Spring Boot ви отримуєте підтримку YAML, яка може виражати будь-яку деревоподібну структуру, і легко мати окремі файли конфігурації для різних середовищ, а також конфігурацію базової лінії, з якої файли, пов'язані з середовищем, можуть успадковувати.
  • Для запуску програмного забезпечення потрібна конфігурація, а для зміни коду часто потрібно додавати / змінювати налаштування конфігурації, тому нормально зберігати конфігурацію та код разом.
  • Зберігання конфігурації з джерелом дає всі переваги управління джерелом, як-от знати, хто змінив яке налаштування та коли або зможе перевірити конфігурації під час звичайного перегляду коду.
  • Якщо ви не працюєте на ЦРУ, аргумент безпеки мені здається перекритим. Отже пароль вашої бази даних зберігається у файлі на машині, де працює ваша програма. Що ж, якщо хтось отримає доступ до машини з вашим додатком, ви, мабуть, вже в багатьох клопотах - вони можуть, наприклад, зняти ваш додаток і запустити власний додаток замість цього ж порту. У такому сценарії доступ до пароля БД не може бути такою великою проблемою. Якщо всі ваші з'єднання повністю не зашифровані, маючи доступ до вашої машини, вони все одно можуть нюхати багато цікавих даних із мережевих інтерфейсів.
  • Ви можете використовувати такий інструмент, як Hiera, щоб мати текстовий файл конфігурації, але не зберігати паролі та інші конфіденційні дані всередині нього.

Отже, для багатьох випадків текстова конфігурація, що зберігається в керуванні джерелами, разом з кодом - хороший початок.

Якщо ви перебуваєте в розподілених системах або хочете мати можливість проміняти конфігурацію без перерозподілу додатків, можливо, краще знайдете рішення, засноване на сервері конфігурації. Spring Cloud має підтримку таких механізмів , і конфігурації, що обслуговують бекенд, можуть бути сховищем git або Eureka . Ви також можете прокатати власні, використовуючи, наприклад, Zookeeper . Будь-який із цих підходів полегшить керування послідовними конфігураціями на багатьох серверах для оновлення конфігурацій без необхідності перебудови та перерозподілу програмного забезпечення. Це, звичайно, коштує, що це вивчення конфігураційного сервера та використання його у ваших програмах, а також інша система розгортання та обслуговування.


Але код змінює руку на того, хто не володіє секретами у конфігураційних файлах, це справді буде безлад.
Тім Людвинський

@TimLudwinski Ключі / секрети належать компанії, а не окремим розробникам, тому їх слід підтримувати таким чином, щоб вони не загубилися, якщо залишиться жодна окрема особа. Наприклад, вони можуть бути виправлені та підтримуватися командою адміністраторів / служб безпеки, щоб мати центральний реєстр.
Michał Kosmulski

5

Ми боремося з тією ж проблемою, де я працюю. Зараз усі наші конфігурації базуються на файлах та джерелах, керованих окремими програмами, які ними користуються. Це призводить до дублювання і до розробників, які мають доступ до паролів production / qa замість просто розробки.

Це сказало, що я думаю, що ми придумали гарне рішення вперед. Ми переміщуємо наші конфігураційні файли до окремого git repo (позначеного як config repo). Потім ми встановлюємо сервер spring-cloud-config (java), який просто обслуговує файли з config repo на основі профілів, переданих йому. Це відмінно підходить для програм Java, які можуть користуватися клієнтом та завантажувати їх під час запуску. Для наших програм PHP / non-java ми знімемо файл безпосередньо. (Не ідеально). В майбутньому ми можемо написати щось, що дозволяє додатку PHP самостійно завантажувати конфігури та зберігати їх у будь-якому місці, але це не перший пріоритет для першого запуску. Я думаю, що це рішення є конфігураційною послугою, яка явно не порушує 12-ти факторних рекомендацій щодо додатків.

Я вважаю, що зоопарку можна використовувати для того ж самого (я бачив налаштування з kubernetes + zookeeper), тому я не зовсім впевнений, чому ця відповідь отримала -1 вище.

Посилання:

https://spring.io/guides/gs/centralized-configuration/

https://cloud.spring.io/spring-cloud-config/


3

Замість того, щоб зберігати всю конфігурацію в одному файлі, зберігайте її в декількох файлах.

  • Мати каталог конфігурації . Усі там файли інтерпретуються як файли конфігурації, крім можливо README*.
  • Усі назви файлів сортуються за алфавітом, а файли завантажуються в такому порядку. Саме тому файли в таких випадках часто починаються з цифри або два: 01-logging.json. 02-database.jsonтощо.
  • Дані з усіх файлів завантажуються в одну структуру конфігурації, доступну програмі. Ось так декілька файлів можуть доповнювати налаштування один одного і навіть передбачувати їх передбачувано.
  • Зберігайте у VCS файли конфігурацій із безпечними для перегляду значеннями або значеннями за замовчуванням. Додайте конфігураційні файли з секретами під час розгортання або, ще краще, скористайтеся службою зберігання секретних секретів.

На найближчому вікні Linux подивіться /etc/sudoers.dабо /etc/nginx/conf.d. Він показує ту саму схему.

Управління секретами - це інший звір. Ви можете керувати ними як ручний крок, поки ви маленький. Ви можете використовувати такі речі, як Zookeeper. Ви навіть можете перевірити секрети в VCS в зашифрованому вигляді і розшифрувати їх як етап розгортання. Існує ряд інших варіантів.

(Крім того, огляд: JSON - це не гарний формат конфігураційного файлу, оскільки він не дає коментарів; коментарі мають вирішальне значення. Формати TOML, YAML і навіть INI краще використовувати на практиці.)


2

Я думаю, що ваші параметри дещо визначені ОС, в яку ви розгортаєтесь

Я б запропонував, так, поставити значення в контролі джерел. АЛЕ лише версії 'dev'. Ви хочете, щоб ваш вихідний код збирався І працював! не включати зайві таємні дії

Потім ваш процес складання та розгортання повинен замінювати ці значення за середовищем під час розгортання. (восьминога має таку модель)


0

Apache zookeeper надає чудові варіанти зберігання конфігурацій додатків для розподілених систем. Зміни, внесені у зоопарку, можуть бути зафіксовані та оброблені, якщо на кінці програми є куратор чи слухач зоокетера.


6
Які варіанти? як це працює? Де їх зберігають? Чи один віддає перевагу іншому? Які різні переваги та недоліки кожного варіанту? Як це взаємодіє в різних операційних системах?

3
@Gangz - Мене зацікавить більш детальна відповідь. Будь ласка, не відволікайте на них голоси і вдосконалюйте свою відповідь, щоб вона могла допомогти.
Джей Елстон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.