Налаштування Spot/Preemptible Instances для пакетних завдань
Spot Instances (AWS) та Preemptible VMs (GCP) — хмарні ресурси з додаткової ємності провайдера за ціною на 60-90% нижче, ніж on-demand. Зворотна сторона: можуть бути примусово зупинені з повідомленням за 2 хвилини. Це не проблема для пакетних завдань, які можуть перезавантажуватися.
Робочі навантаження, придатні для Spot
Добре підходять:
- CI/CD воркери (кожна збірка — окреме завдання)
- Обробка зображень і відео (перекодування, зміна розміру)
- ML навчання (на основі контрольних точок)
- Парсинг та ETL конвеєри
- Рендеринг
- Антивірусні сканування, аналітичні запити
Не підходять:
- Статичні бази даних (критичні дані)
- Веб-сервери без швидкої заміни
- Сервіси з суворими SLA і без DR
AWS Spot Instances: практика
Spot Fleet з кількома типами інстансів — ключ до стабільності. Якщо m5.xlarge недоступний в одній зоні доступності, Fleet використовує m4.xlarge або c5.xlarge в іншій:
{
"SpotFleetRequestConfig": {
"AllocationStrategy": "capacityOptimized",
"TargetCapacity": 10,
"LaunchTemplateConfigs": [
{
"LaunchTemplateSpecification": {"LaunchTemplateId": "lt-xxx", "Version": "1"},
"Overrides": [
{"InstanceType": "m5.xlarge", "WeightedCapacity": 1},
{"InstanceType": "m5a.xlarge", "WeightedCapacity": 1},
{"InstanceType": "m4.xlarge", "WeightedCapacity": 1},
{"InstanceType": "c5.xlarge", "WeightedCapacity": 1}
]
}
]
}
}
Стратегія capacityOptimized знижує ймовірність перериву, вибираючи пули з найбільшою доступною ємністю.
Обробка повідомлення про перерив Spot
За 2 хвилини до зупинення AWS відправляє подію метаданих інстансу. Приложення повинне перехопити та граціозно завершити завдання:
import requests
import signal
import sys
def check_spot_interruption():
"""Викликати кожні 5 секунд з воркера"""
try:
response = requests.get(
'http://169.254.169.254/latest/meta-data/spot/interruption-notice',
timeout=1
)
if response.status_code == 200:
return True # Очікується перерив
except requests.exceptions.RequestException:
pass
return False
class BatchWorker:
def process_task(self, task):
# Контрольна точка для кожних N елементів
for i, item in enumerate(task.items):
if i % 100 == 0 and check_spot_interruption():
self.save_checkpoint(task.id, i)
sys.exit(0) # Граціозний вихід, завдання буде перезапущено
self.process_item(item)
task.mark_complete()
AWS EventBridge для Spot Interruption
{
"source": ["aws.ec2"],
"detail-type": ["EC2 Spot Instance Interruption Warning"],
"detail": {
"instance-action": ["terminate"]
}
}
EventBridge → Lambda → зберегти контрольну точку + видалити інстанс із пулу + повернути завдання у чергу.
Kubernetes з Spot вузлами
Karpenter (AWS) автоматично вибирає тип інстансу (включаючи Spot) та обробляє переривання:
apiVersion: karpenter.sh/v1alpha5
kind: Provisioner
metadata:
name: batch-workers
spec:
requirements:
- key: "karpenter.sh/capacity-type"
operator: In
values: ["spot", "on-demand"]
- key: "node.kubernetes.io/instance-type"
operator: In
values: ["m5.xlarge", "m5a.xlarge", "m4.xlarge", "c5.xlarge"]
taints:
- key: batch
effect: NoSchedule
consolidation:
enabled: true
При Spot Interruption Karpenter cordon + drain вузла, поди перепланують на інші вузли.
GCP Preemptible / Spot VMs
GCP Preemptible: максимум 24 години життя + повідомлення за 30 секунд (у 15 разів менше, ніж AWS). Spot VMs: без обмеження 24 годин, тільки на основі доступності.
gcloud compute instances create batch-worker \
--machine-type=n2-standard-4 \
--provisioning-model=SPOT \
--instance-termination-action=STOP \
--zone=us-central1-a
Ефективність та економія
Реальні приклади:
- CI/CD конвеєр: перехід з on-demand t3.xlarge на Spot → економія 70%
- ML навчання на Spot p3.2xlarge: $0.918/година замість $3.06/години
Надбавка від переривань та перезавантажень: зазвичай 5-15% додаткового часу. Загальна економія: 60-80% при правильній реалізації контрольних точок.
Часова шкала налаштування
- Spot Fleet / Launch Template — 1-2 дні
- Обробка переривань у приложенні — 2-3 дні
- Kubernetes Karpenter зі Spot — 2-3 дні
- Тестування з симуляцією переривання — 1 день







