Налаштування Windows-контейнерів у Docker/Kubernetes

Контейнери на Windows поводяться інакше, ніж на Linux, і падають там, де все вже перевірено. Ми налаштовуємо Windows-контейнери в кластері під ключ: підбираємо режим ізоляції, готуємо хости та регламенти оновлення. Простої під час оновлення сервісів скорочуються, а команда отримує передбачуваний контур.
Часті запитання

Чому Windows-контейнери падають на чужому хості

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

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

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

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

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

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

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

Що дає керований контейнерний контур

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

Передбачувана збірка

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

Коротке вікно оновлення

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

Простій сервісу — секунди, а не нічні вікна

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

Повторюваність оточення

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

Windows-контейнери: режими ізоляції та сумісність

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

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

Варіант Коли підходить Обмеження режиму
Режим процесу, спільне ядро Однорідний парк хостів, щільне пакування, довгоживучі сервіси Версія ядра хоста має збігатися з лінією образу; ізоляції ядра немає
Гіпервізорний режим Різнорідні хости, мультиорендність, старі навантаження поруч із новими Важчий старт, нижча щільність, потрібна вкладена віртуалізація
Окремий пул Windows-вузлів Змішаний кластер, Linux-навантаження поруч із Windows Планування за мітками та заборонами, частина мережевих плагінів недоступна
Пул під одну лінію базового образу Жорсткі вимоги до сумісності версій, рідкісні оновлення Зростає число пулів, оновлення хостів синхронізується з образами

Порядок впровадження: від аудиту хостів до передачі

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

  1. Аудит інфраструктури. Інвентаризація парку машин: гілка системи, доступність режиму ізоляції, драйвери сховища, маршрути до реєстру образів. Результат — таблиця «вузол — придатність — що дозробити».

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

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

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

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

  6. Передача команді. Конфігурації, схема контуру, регламент оновлень і порядок діагностики типових відмов; розбір із черговою зміною.

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

Комплект конфігурацій, схем і регламентів на виході

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

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

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

Кейс: прибрали простої під час оновлення сервісів

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

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

Що змінили

Сервіси перенесли в контейнери під управлінням Kubernetes, виділивши окремий пул Windows-вузлів.

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

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

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

Що стало

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

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

Що робити, якщо контейнери вже розгорнуті в кластері?

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

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

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

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

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

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

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

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

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

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

Часті технічні сумніви перед стартом

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

Ці точки ми фіксуємо в матриці сумісності та перевіряємо в конвеєрі збірки, а не з'ясовуємо на етапі випуску. Нижче — сумніви, які найчастіше виринають перед першою розкаткою.

Контейнер запуститься на будь-якому вузлі кластера?

Ні. Образ і вузол мають бути на одній гілці — розбіжність дає відмову на старті або нестабільну роботу під навантаженням.

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

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

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

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

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

Що змінюється при перенесенні на інший хост або контур?

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

Як із ліцензіями при перенесенні?

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

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

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

Цього вистачає, щоб зрозуміти обсяг робіт і ризики сумісності, а не з'ясовувати їх уже на етапі впровадження.

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

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

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

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

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

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

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