Перейти до вмісту

Блог ·

VM чи контейнер? Що продавати на Proxmox

Гість KVM і контейнер LXC поділяють один гіпервізор, один простір чисел і один прайс-лист, і майже нічого більше. Відмінності, які коштують грошей.

Автор: Provibr

Proxmox VE запускає два види гостей. Віртуальна машина KVM завантажує власне ядро за емульованою прошивкою, а контейнер LXC поділяє ядро хоста, на якому стоїть. Для клієнта, який купує VPS, обидва є «сервером із root», і саме тому порівняння зазвичай роблять маркетинговою таблицею з рядками про щільність і накладні витрати.

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

Нещодавно ми додали другий вид обчислень до власної інтеграції з Proxmox, а це означало читати API з конкретним питанням «де ці два розходяться». Ось що з цього вийшло, у тому порядку, в якому воно нас дивувало.

Один кластер, один простір чисел

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

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

Це має прямий наслідок для всього, що зберігає гостей Proxmox у власній базі даних. Покладіть вид в обмеження унікальності, щоб «машина 5001» і «контейнер 5001» були двома різними рядками, і ви отримаєте схему, здатну тримати два записи на одного гостя й дати їм за нього битися. Ідентифікатор унікальний сам собою, а вид є спостереженням, збереженим поруч. Якщо ви обираєте діапазони для парку машин, арифметика з вибору діапазону VMID на Proxmox не змінюється з появою контейнерів, і в цьому вся суть.

Контейнер розпаковують, а не клонують

Друге розходження це шлях створення, і воно більше, ніж видається.

Віртуальну машину зазвичай отримують клонуванням шаблона: ви називаєте джерело, обираєте повне чи звʼязане, і отримуєте копію образу диска. Контейнер отримують розпаковуванням архіву на новий том. Немає гостя-джерела, немає вибору між повним і звʼязаним, і немає диска cloud-init, бо немає до чого підключати диск.

Тому тіло запиту майже не має спільних полів із тим, що створює машину. Контейнер хоче ostemplate, який вказує на архів у сховищі, прапорець unprivileged, hostname, rootfs і значення swap. Машина хоче scsi0, scsihw, bios, boot і ide2, коли вона завантажується з ISO. Використати один словник замість іншого це помилка, якої треба уникати свідомо: слова достатньо схожі, щоб поле під назвою disk за рік означало дві різні речі в одній кодовій базі.

Дві деталі в тому тілі варто вкрасти незалежно від того, на чому ви будуєте.

rootfs=<storage>:<size> є розподілом, а не посиланням. Це означає «створити новий том такого розміру в гігабайтах у цьому сховищі». Форма, яка називає наявний том, виглядає майже так само й робить категорично інше: вона привласнює том, що може досі містити чужі дані.

Пропустити параметр це безпечна відповідь. Вкладеність, keyctl, FUSE, bind mounts і прокидання пристроїв усі вимкнені, доки ви їх не надішлете, і немає «порожнього» значення, яке треба памʼятати записати. Тож правильна типова постава для хостинг-платформи це короткий запит, а не довгий. Поле архітектури це та сама історія: Proxmox виводить його з архіву, і надсилання такого, що не збігається, падає під час розпакування.

Три речі, яких контейнер ніколи не зробить

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

ДіяГість KVMКонтейнер LXC
Запустити, зупинити, вимкнути, видалититактак, та сама форма, інший сегмент шляху
Призупинити чи приспатитакні: це монітор QEMU
Завантажитися з мережі через PXEтакніколи
Встановити з ISOтакніколи
Обрати порядок завантаження, BIOS чи UEFIтакніколи
Консолькадровий буфер VNCтермінал, іншим протоколом
Swapневидимий для хостаналаштування гіпервізора з числом

Пʼятьом із тих рядків клітинки замало, і вони діляться на три групи.

Мережеве завантаження, встановлення з ISO і вибір прошивки неможливі з однієї причини, а не з трьох: у контейнера немає прошивки. Він не запускає завантажувач, у нього немає порядку завантаження, і в його старті немає нічого, чому можна було б сказати спробувати спершу мережу. Якщо ви продаєте продукт, де «перевстановлення з нашої бібліотеки образів» є можливістю, зауважте, що шлях PXE від відповіді DHCP до готової інсталяції не має контейнерного відповідника. Перезбирання контейнера це інший механізм з іншими гарантіями, і він заслуговує на власний екран, а не на сіру кнопку.

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

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

Swap є продуктовим рішенням, а не типовим значенням

Ось те, що вигулькне у зверненнях до підтримки.

Proxmox дає новому контейнерові 512 MiB swap, якщо ви не скажете інакше. Успадкуйте це мовчки, і тариф, проданий як «2 GiB памʼяті», віддає 2,5 GiB придатної памʼяті, а різниця ніде не проявиться більшим числом: вона проявиться як контейнер, який стає повільним замість того, щоб чесно вичерпати памʼять, місяцями пізніше, на хості, що почав свопити.

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

Вимірювання swap має власну ціну. Гуртовий перелік, який дає лічильники процесора, памʼяті, диска й мережі для кожного гостя в кластері, взагалі не несе поля swap, для жодного з видів. Єдине місце, де Proxmox його повідомляє, це endpoint статусу окремого гостя, тож це один додатковий виклик HTTP на кожен запущений контейнер, назавжди. Ми читаємо його раз на хвилину: тричі на хвилину потроює навантаження на чужий гіпервізор заради числа, що рухається хвилинами, а раз на пʼять хвилин кладе рівно один зразок у пʼятихвилинне відро згортки, від чого стовпець максимуму дорівнює середньому й тому є прикрасою.

Дві вади, які ми випустили, вважаючи їх одним і тим самим

Обидві були живими місяцями до того раунду, який пішов шукати.

Перша: наш екран імпорту показував контейнери як віртуальні машини. Перелік ресурсів кластера з type=vm не є фільтром QEMU, він повертає обидва види, а поле, яке каже, який саме, просто не читали. Ніщо не впало. Список був неправильний.

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

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

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

  1. Вид є властивістю тарифу чи вибором на оформленні? Обидва варіанти можна захистити. Типове значення під вибором не можна: клієнт, який замовив контейнер і отримав машину, дістав іншу модель безпеки, інше ядро й інший набір можливостей, ніж той, що обрав.
  2. Які відмови є постійними, а які тимчасовими? Скажіть це в інтерфейсі, саме цими словами. «Неможливо для контейнера» і «ще не збудовано» є різними обіцянками.
  3. Звідки береться захист від підміни? Чесна прогалина у власній роботі: клонована машина отримує фільтрацію IP при видачі, а контейнер поки що ні. Proxmox має ті самі endpoint брандмауера для обох, тож це крок збірки, а не перешкода, але контейнер, виданий без цього, може слати трафік, видаючи себе за когось іншого.
  4. Що моніторинг показує для контейнера? Усе, що виведено з гостьового агента, кадрового буфера чи прошивки, є порожнім. Порожнє це нормально. Порожнє, подане як здоровий нуль, ні.

У нас є поле тарифу, шлях замовлення й запит на створення, збудовані й звірені із сирою формою HTTP цього API. Чого ми не зробили, так це не створили контейнер на чиємусь продакшн-гіпервізорі, тож чесний опис нашої підтримки контейнерів звучить як «форма правильна, а прохід туди й назад не перевірено», і це корисна річ, яку варто вміти сказати вголос про власну платформу.

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

Почніть з одного хоста й одного агента

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