Налаштування Docker Secrets: безпечне керування секретами в контейнерах

Ключі та паролі сервісів часто лежать у відкритому вигляді — у змінних середовища, файлах та історіях збірок. Ми налаштовуємо Docker secrets під ключ: ізолюємо доступ, вибудовуємо ротацію та передаємо регламенти, щоб розгортання перестало бути ручною роботою з ризиком витоку.
Часті запитання

Docker secrets: де витікають ключі в контейнерному середовищі

Збій зазвичай починається на збірці: пароль або токен передають в образ через змінні середовища та аргументи збірки.

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

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

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

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

Тут же поруч стоять права процесу: контейнер, запущений від суперкористувача, не розмежовує доступ, і секрет читається тим самим кодом, що приймає зовнішні запити.

Третя звичка — друкувати конфігурацію. Журнали збірки та роботи застосунку містять рядки підключення з паролем усередині, вивід помилок при першому зверненні до бази, дампи змінних при старті.

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

Розбираємо, як це закривається штатними засобами docker secrets: значення передається не в середовищі, а файлом, доступним лише конкретній службі.

Ізольований доступ і ротація ключів: вимірюваний ефект

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

Час виведення нового ключа в роботу

Ротація зводиться до створення нової версії секрету й перезапуску лише тих сервісів, що на неї посилаються.

Оновлення одного сервісу вкладається в хвилини замість узгодженого вікна простою на всю систему; попередню версію видаляємо після того, як останній споживач перечитав значення.

Частка сервісів із розмежованим доступом

Секрет прив'язується до конкретного сервісу, тому база не бачить ключ платіжного шлюзу, а вебзастосунок — облікові дані черги. Доводимо показник до всіх сервісів: у кожного рівно ті секрети, без яких він не стартує, решта для нього недоступні.

Ізоляція середовищ і зниклий клас відмов

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

Що залишається під контролем

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

Docker secrets проти змінних середовища: режими й обмеження

Docker secrets віддає значення файлом у tmpfs усередині контейнера: процес читає /run/secrets/<ім'я>, а змінна середовища ніде не зберігається.

Змінні середовища простіші, але видно в inspect, успадковуються дочірніми процесами й потрапляють у дампи та логи — при витоку образу або дампа пароль іде разом із ним.

Варіант Коли підходить Обмеження
Docker secrets оркестратор із підтримкою secrets, монтування в tmpfs застосунок читає файл, а не готову змінну
Змінні середовища локальний стенд, некритичні параметри видно в inspect і логах, успадковуються процесами
Змонтовані файли старі версії compose, ручне керування секрет лежить на хості відкрито, ротація вручну
Зовнішнє сховище секретів кілька середовищ і кластерів, аудит доступу потрібен агент і доступ до мережі при старті

Вибір за середовищем

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

Вибір за типом навантаження

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

Впровадження за етапами: від аудиту до передачі регламентів

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

  1. Інвентаризація секретів. Збираємо перелік: що за секрет, який сервіс ним користується, де зберігається, як часто змінюється. На виході — реєстр із власниками та класами критичності.
  2. Схема потоків секретів. Малюємо шлях значення від сховища до процесу: монтування в контейнер, доступ за роллю сервісу, ротація. Схема одразу показує зайві копії у змінних середовища та в образах — їх прибираємо першими.
  3. Налаштування сховища та прав. Заводимо секрети через Docker Secrets, розмежовуємо доступ за сервісами й середовищами, щоб середовище розробки не бачило робочих значень. Права видаємо за принципом мінімальної достатності.
  4. Переведення сервісів. Підключаємо по одному, з перевіркою після кожного кроку. Так помилка локалізується в одному сервісі, а не валить весь контур — розрахунок індивідуальний.
  5. Перевірка відмов. Ламаємо самі: відкликаємо доступ, підміняємо значення, зупиняємо сховище — і дивимося, як сервіс це переживає.
  6. Передача регламентів. Віддаємо реєстр, схему, порядок ротації та інструкцію для чергового.

Перевірка на стенді та порядок відкату

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

Відкат передбачено на кожному кроці: поки сервіс не підтвердив отримання нового значення, старе залишається чинним, тому повернення — це перемикання на попередній запис, а не відновлення з резервної копії.

Конфігурації, схеми та регламенти: що залишається у вас

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

  • Конфігурації секретів: оголошення секретів та їх прив'язка до сервісів, способи доставки в контейнер, поведінка за відсутності секрету — додавання нового значення стає правкою одного місця, а не ручною операцією на сервері.
  • Схема потоків: звідки секрет береться, через які середовища проходить, де опиняється під час роботи сервісу і де не повинен опинитися ніколи.
  • Політики доступу: матриця «сервіс — секрет — рівень доступу», включно з розмежуванням між середовищами та ролями.
  • Регламент ротації: періодичність, порядок дій, відповідальний і точка фіксації факту зміни.
  • Документація: опис архітектури, ухвалених рішень і свідомих обмежень — щоб наступна команда не відкривала їх заново.
  • Інструкції для команди: покрокові сценарії «додати секрет», «відкликати доступ», «перевірити конфігурацію», «відкотитися на попереднє значення».
  • Перелік перевірок перед викочуванням: що валідується автоматично, а що залишається на рев'ю.

Політики доступу

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

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

Регламент ротації

Ротація будується без простою: нове значення створюється поруч зі старим, сервіс приймає обидва, і тільки після підтвердження старе відкликається.

У регламенті зафіксовано періодичність, відповідального та порядок дій при компрометації — коли змінювати потрібно негайно і за іншою гілкою сценарію.

Кейс: міграція секретів сервісу без простою

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

Ротація одного значення займала вечір — правка файлу, перезбирання образів, зупинка групи контейнерів і підйом заново. За квартал таку операцію відкладали тричі: вікно простою не узгоджувалося з роботою продукту.

Вихідний стан: одне значення — чотири копії

Ключ існував одночасно в репозиторії, у змінних середовища контейнера, у виводі діагностики та в журналах застосунку при невдалому підключенні.

Значення читав будь-хто, у кого був доступ до огляду контейнера на хості, а відкликання прав робили руками: спочатку гасили сервіс, потім міняли значення, потім піднімали.

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

Результат: ротація за хвилини та перевірка на бойовому контурі

Значення перенесли в секрети Docker: сховище віддає їх контейнеру файлом в окремому розділі пам'яті, доступному лише процесу.

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

Перевіряли ступенями: копія трафіку, потім десята частина вузлів, потім усі. Частка помилок підключення не зросла, час ротації скоротився до хвилин, простій — нуль, копія значення залишилася одна, а частка сервісів з автоперевіркою на витік дійшла до ста відсотків.

Що робити, якщо секрети вже лежать у змінних середовища

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

Перехід на docker secrets роблять через подвійний контур: код читає значення спочатку зі змонтованого файлу, а за його відсутності падає назад на змінну середовища. Файл живе в окремій ділянці пам'яті контейнера і не осідає ні в образі, ні в історії запуску. Контур знімають, коли всі екземпляри сервісу відпрацювали на новому джерелі повний цикл випуску.

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

Зі значеннями, що втекли, поводяться інакше, ніж із робочими: усе, що побувало у змінній середовища, вважають розкритим і не переносять, а замінюють.

Ротацію ведуть без простою — спочатку випускають нове значення, переводять споживачів, потім гасять старе, щоб відкат залишався можливим до кінця переведення.

Коли останній споживач переведений, змінну прибирають з опису сервісу й ставлять перевірку, яка ловить її повернення в діагностиці та логах. Далі працює регламент ротації — за строком і за інцидентом.

Технічні сумніви: ротація, відкат, сумісність середовищ

Сумніви щодо секретів зазвичай одні й ті самі: чи доведеться зупиняти сервіс заради ротації, що робити, якщо нове значення виявиться хибним, і чи не спливуть значення там, де їх бути не повинно. Нижче — практичні відповіді на ті питання, які надходять найчастіше.

Чи можна змінювати секрет без перезапуску контейнера?

Docker Secrets підставляє значення файлом усередині контейнера, тому запущений процес бачить стару версію до перезапуску. Ротацію робимо двоетапною: застосунок читає секрет при кожному зверненні, а роздача йде по одному завданню — без простою сервісу.

Як відкотити зіпсований секрет?

Попереднє значення зберігаємо як окремий секрет із суфіксом версії: відкат — це зміна посилання в описі сервісу та повторне розкочування. Тримаємо дві версії, старе значення видаляємо після підтвердженої роботи нового.

Чи однаково це працює в різних середовищах?

Логіка одна, відрізняється джерело значення: у продуктивному середовищі — секрет оркестратора, локально — файл поза репозиторієм. Застосунок забирає значення через єдиний інтерфейс, тому змінюється лише спосіб доставки.

Чи не потраплять значення секретів у журнали?

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

Обговоримо задачу: контур секретів під ваш стек і процеси

Щоб розрахунок був предметним, а не «за відчуттями», нам потрібен мінімум ввідних щодо вашого контуру. Надішліть те, що є під рукою, — решту уточнимо в розмові та повернемося з оцінкою і планом робіт.

  • Схема сервісів: які контейнери в контурі, як вони пов'язані, хто читає секрети — застосунок при старті, збірка чи завдання за розкладом.
  • Контури: скільки середовищ (розробка, тестове, промислове) і чим вони відрізняються за складом секретів і правами доступу.
  • Порядок ротації: хто її ініціює, з якою періодичністю, що має відбуватися з уже запущеними контейнерами після зміни значення.
  • Поточний стан: де секрети лежать зараз — у файлах усередині образу, у змінних середовища, у системі керування конфігурацією чи в зовнішньому сховищі.
  • Обмеження: вимоги служби безпеки й перевіряльників, розмежування доступу за ролями, заборони на зберігання у відкритому вигляді в репозиторії та журналах.
  • Порядок відкату: чи припустимо перезапустити сервіс при оновленні секрету і за який час це має відбуватися.
  • Підтримка після впровадження: чи потрібен регламент ротації, навчання команди та чергування на період перших оновлень.

За цими ввідними повернемося з планом: етапи, склад змін у маніфестах і правах, порядок ротації та відкату, що перевіряємо на кожному кроці. Далі залишаємося на зв'язку — допомагаємо вести регламент і розбирати інциденти, поки команда не почне керувати секретами самостійно.

Опишіть задачу в листі або короткій дзвінкій розмові — цього достатньо, щоб почати.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139