VPS, VDS, выделенные серверы и DigitalOcean/Hetzner: когда простое дешевле облака
Три предыдущие статьи — про https://courses.digitable.life/post/devops/11-aws/, https://courses.digitable.life/post/devops/12-azure/ и https://courses.digitable.life/post/devops/13-gcp-and-others/ — описывали мир, где под каждую задачу есть управляемый сервис, а под каждый управляемый сервис — своя строка в счёте. Этот мир прекрасен ровно до момента, когда вы открываете счёт и видите 4 000 $ за инфраструктуру, обслуживающую 300 запросов в секунду и базу на 200 ГБ.
И тогда возникает честный вопрос, который в индустрии почему-то считается неприличным: а нельзя ли просто взять сервер?
Можно. Часто — нужно. Эта статья про нижний, «скучный» слой инфраструктуры: виртуальные и выделенные серверы, которые вы арендуете как железо, а не как сервис. Про то, почему они в разы дешевле, что именно вы платите этой разницей, и как отличить ситуацию «мы экономим 40 тысяч долларов в год» от ситуации «мы сэкономили 40 тысяч и потеряли 200 на инциденте».
Никакой идеологии. Гиперскейлер — не «правильно», свой сервер — не «по-мужски». Обе позиции стоят денег, и обе бывают верными.
Терминология: что вам на самом деле продают
Слова в этом сегменте рынка размыты намеренно — маркетингом. Разложим.
Shared hosting — вы получаете каталог на чужом сервере и PHP/FTP. Ядро, systemd, порты — не ваши. Для лендинга на WordPress подходит, для инженерной работы — нет. В этой статье не рассматриваем.
VPS (Virtual Private Server) — виртуальная машина на общем физическом хосте. У вас свой root, своё ядро (обычно), свои сетевые интерфейсы. Ресурсы — CPU, диск, сеть — делятся с соседями.
VDS (Virtual Dedicated Server) — исторически термин означал полную аппаратную виртуализацию (KVM/Xen) в противоположность контейнерной (OpenVZ/LXC/Virtuozzo), где вы делите ядро хоста и не можете загрузить свои модули, поменять sysctl или запустить нормальный Docker с overlay2. Сегодня почти все продают KVM, и разница между VPS и VDS стала чисто маркетинговой — особенно в русскоязычном сегменте, где «VDS» просто звучит солиднее. Единственный практический вывод: если хостер не пишет прямо «KVM», спросите. OpenVZ-контейнеры всё ещё продают в дешёвом сегменте, и на них вы получите сюрпризы вида «ваш docker не запускается» или «free -m показывает память всего хоста».
Dedicated server / bare metal — целая физическая машина в аренду. Гипервизора нет вообще (или вы ставите свой). Ресурсы полностью ваши, включая всю производительность NVMe и всю пропускную способность памяти.
Bare metal cloud — то же железо, но с API, почасовой тарификацией и автоматическим провижинингом за 2–10 минут (AWS *.metal, Equinix Metal, OVH, Scaleway Elastic Metal, Hetzner отчасти). Мост между двумя мирами: скорость облака, физика железа.
Colocation — вы покупаете сервер сами, везёте в чужой ДЦ, платите за стойко-место, электричество и канал. Самый дешёвый на масштабе и самый дорогой по вниманию. Про него — в https://courses.digitable.life/post/devops/15-cloud-cost-and-tradeoffs/.
Спектр управляемости: за что вы платите разницу
Правильная ментальная модель — не «облако против сервера», а лестница ответственности. Каждая ступень снимает с вас работу и добавляет к счёту.
ОС, сеть, всё выше
Провайдер: стойка, питание, канал"] end subgraph L1["Bare metal в аренду — Hetzner AX/EX, OVH"] A1["Вы: ОС и всё выше
Провайдер: железо, замена дисков,
питание, сеть, IPMI/rescue"] end subgraph L2["VPS/VDS — Hetzner Cloud, DO Droplets, Vultr"] A2["Вы: ОС и всё выше
Провайдер: + гипервизор, снапшоты,
API, сетевые диски, LB, DNS"] end subgraph L3["Managed-платформа — RDS, EKS, App Platform"] A3["Вы: схема данных, код, конфиг
Провайдер: + СУБД, бэкапы, failover,
апгрейды, control plane"] end subgraph L4["Serverless — Lambda, Cloud Run, Fargate"] A4["Вы: код и лимиты
Провайдер: + ёмкость, масштабирование,
патчинг, изоляция"] end L0 --> L1 --> L2 --> L3 --> L4 L4 -.->|"× 3–8 к цене за единицу
вычислений относительно L1"| L1 style L0 fill:#4f9d69,color:#fff style L1 fill:#4f9d69,color:#fff style L2 fill:#3d8bcd,color:#fff style L3 fill:#d9a441,color:#000 style L4 fill:#e76f51,color:#fff
Ключевая мысль: вы не выбираете уровень для всей компании — вы выбираете его для каждой рабочей нагрузки отдельно. Совершенно нормальная архитектура: PostgreSQL и приложение на bare metal в Хельсинки, объектное хранилище в Cloudflare R2, CDN в Cloudflare, редко используемая ML-инференция на GPU по требованию в облаке, DNS у регистратора. Такая система дешевле чисто облачной в 4–6 раз и почти не сложнее в эксплуатации, если границы проведены по правильным местам.
Почему разница в цене такая огромная
Восемнадцатикратный разброс за одну и ту же спецификацию требует объяснения. Железо у всех примерно одинаковое: тот же EPYC, тот же Xeon, те же Samsung/Micron NVMe. Разница складывается из пяти вещей.
1. Переподписка (oversubscription). Хостер продаёт больше vCPU, чем у него физических потоков. Contabo за 17 $ отдаёт «8 vCPU» при коэффициенте 5:1 и выше — вы покупаете право стоять в очереди. Hetzner CCX и DO General Purpose дают 1:1 и стоят соответственно.
2. Трафик. Это самая недооценённая статья. У гиперскейлеров исходящий трафик — маржинальный продукт, у европейских хостеров — почти бесплатный.
| Провайдер | Включено | Сверх квоты | 10 ТБ egress/мес обойдутся в |
|---|---|---|---|
| Hetzner Cloud | 20 ТБ на сервер (EU) | ~€1 / ТБ | 0 € |
| Hetzner dedicated | безлимит на 1 Гбит/с | — | 0 € |
| OVH VPS/bare metal | безлимит (лимит по полосе) | — | 0 € |
| DigitalOcean | 1–10 ТБ пулом на аккаунт | 0,01 $ / ГБ | ~0–90 $ |
| Vultr | 1–10 ТБ пулом | 0,01 $ / ГБ | ~0–90 $ |
| Akamai / Linode | пулом по аккаунту | 0,005 $ / ГБ | ~0–50 $ |
| Cloudflare R2 / Bunny | — | 0 $ egress | 0 $ |
| AWS / GCP / Azure | 100 ГБ | ~0,085 $–0,09 / ГБ | ~850–900 $ |
Медиасервис, отдающий 50 ТБ в месяц, платит AWS около 4 500 $ только за то, что байты покинули дата-центр. На Hetzner это ноль. Именно egress, а не CPU, чаще всего делает переезд экономически неизбежным.
3. SLA и компенсации. AWS обещает 99,99 % для EC2 в нескольких AZ и возвращает сервисные кредиты при нарушении. Hetzner Cloud формально даёт 99,9 % и компенсирует… стоимостью сервера. Разница в обещании закладывается в цену: провайдер держит резервную ёмкость, дублирует питание и каналы, содержит инженеров, готовых к эскалации в 3 часа ночи.
4. Managed-сервисы и экосистема. Цена EC2 включает не только виртуалку — она включает IAM, CloudTrail, VPC-фичи, интеграции, десятилетия документации и рынок специалистов. Вы платите за то, что решение «нужен Kafka» превращается в один Terraform-ресурс, а не в двухнедельный проект.
5. Compliance и юрлицо. SOC 2, HIPAA, PCI DSS, FedRAMP, BAA, региональные сертификаты, готовые DPA. Если ваш корпоративный клиент требует эти бумаги, дешёвый хостер их не даст — и вопрос цены снимается сам собой.
Всё это — реальная ценность. Вопрос не «переплачиваете ли вы», а «нужно ли вам то, за что вы переплачиваете, именно сейчас».
Shared vCPU против dedicated vCPU: что мерить
Главный измеримый показатель — steal time: доля тактов, которые гипервизор отдал соседям, пока ваш процесс был готов считать. В Linux это колонка st в vmstat и %steal в top/mpstat.
# мгновенная картина: 5 замеров по секунде
$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 0 0 2117840 118204 5482116 0 0 3 41 221 388 22 4 62 0 12
4 0 0 2115292 118204 5482148 0 0 0 112 1204 2891 31 6 45 0 18
5 0 0 2113004 118204 5482180 0 0 0 8 1388 3102 28 5 47 0 20
st = 12–20 % на дешёвом VPS в будний вечер — типичная картина. Это значит, что пятая часть купленного процессора вам не досталась, и, что хуже, досталась непредсказуемо: p99 разъезжается сильнее, чем среднее.
# длительное наблюдение с раскладкой по ядрам
$ mpstat -P ALL 60 60 | awk '/Average/ {print $2, $3, $12, $NF}'
# CPU %usr %idle %steal
# all 27.4 49.1 19.3 <- steal почти 20 % в среднем за час
Практическое правило проверки перед покупкой: возьмите машину на час (все нормальные хостеры тарифицируют почасово), прогоните нагрузку и посмотрите не среднее, а разброс.
# однопоточная производительность ядра — сравнивает поколения CPU честнее, чем «ГГц»
$ sysbench cpu --cpu-max-prime=20000 --threads=1 --time=60 run | grep 'events per second'
events per second: 1284.55 # Hetzner CCX (EPYC, dedicated)
events per second: 812.30 # тот же тариф у бюджетного хостера в 19:00
events per second: 1190.02 # он же в 06:00 — соседи спят
# диск: то, ради чего вообще берут NVMe. Проверять случайную запись, а не последовательное чтение
$ fio --name=randwrite --ioengine=libaio --direct=1 --bs=4k --iodepth=32 \
--size=4G --rw=randwrite --runtime=60 --group_reporting
# локальный NVMe (bare metal): IOPS=186k, BW=728MiB/s, lat p99=0.41ms
# локальный NVMe (Hetzner Cloud): IOPS= 41k, BW=162MiB/s, lat p99=1.9ms
# сетевой том (DO Block Storage): IOPS= 7.5k, BW= 30MiB/s, lat p99=8.4ms
# AWS gp3 (3000 IOPS baseline): IOPS= 3.0k, BW= 12MiB/s, lat p99=1.1ms
Последний блок — важнейший для баз данных. Разница между локальным NVMe на выделенном сервере и сетевым томом в облаке составляет один-два порядка по IOPS и по задержке. PostgreSQL, который на bare metal держит нагрузку на одной машине, в облаке потребует инстанса вдвое дороже — или дорогого io2-тома. Это компенсирует часть разницы в цене в пользу железа, и обычно её забывают учесть.
Обратная сторона: локальный NVMe умирает вместе с сервером. Об этом — ниже, в разделе про отказы.
Обзор игроков: кого стоит рассматривать
| Провайдер | Сильная сторона | Слабая сторона | Кому подходит |
|---|---|---|---|
| Hetzner (DE/FI/US/SG) | лучшая цена за такт в мире, безлимитный трафик, приличный API и Terraform-провайдер, бесплатная DDoS-защита | мало регионов, строгая антифрод-политика, поддержка только по тикетам, суровые правила при подозрении на майнинг/спам | тем, кто считает деньги и умеет админить |
| DigitalOcean | лучшая документация в индустрии, простой UX, managed PostgreSQL/Redis/K8s, App Platform | цена ближе к гиперскейлерам, чем к Hetzner; managed-сервисы беднее AWS | небольшие команды без выделенного DevOps |
| Vultr | много локаций (32+), bare metal с почасовой оплатой, GPU | качество сети между регионами неровное | распределённая по миру мелкая инфраструктура |
| Akamai (Linode) | зрелость, интеграция с CDN Akamai, честные dedicated-планы | цены выросли после покупки | тем, кому нужен CDN и compute у одного вендора |
| OVHcloud (FR) | огромный выбор bare metal, безлимитный трафик, дешёвые аукционы | репутация поддержки, пожар в Страсбурге в 2021 как напоминание о бэкапах | Европа, GDPR, дешёвое железо |
| Scaleway (FR) | ARM-инстансы, S3-совместимое хранилище, серверлесс | дороже Hetzner, региональная привязка | французский/европейский compliance |
| Contabo (DE) | абсурдно дёшево | сильная переподписка, нестабильная производительность, слабый API | лаборатории, dev-окружения, торренты знаний |
| Selectel / Timeweb / Beget / VK Cloud (RU) | 152-ФЗ, оплата в рублях, локальный саппорт по телефону | ограниченный мировой охват, разное качество | продукты для российского рынка |
| Equinix Metal | bare metal с настоящим API, BGP, глобальная сеть | дорого | инфраструктурные компании, сети |
Отдельно — объектное хранилище, потому что оно почти всегда стоит вынести отдельно от compute: Cloudflare R2 и Backblaze B2 берут ноль за egress, что делает связку «свой сервер + R2» радикально дешевле «EC2 + S3» на любых медийных нагрузках.
Дерево решения
которой у хостера нет?
(HIPAA BAA, FedRAMP, PCI L1)"} C1 -->|да| CLOUD["Гиперскейлер или
сертифицированный провайдер"] C1 -->|нет| C2{"Нагрузка сильно
эластична?
пик / база > 5"} C2 -->|да| C3{"Пик предсказуем
по расписанию?"} C3 -->|нет| CLOUD C3 -->|да| HYB["Гибрид: база на железе,
пики в облаке по API"] C2 -->|нет| C4{"Нужна географическая
раскладка > 3 регионов?"} C4 -->|да| CLOUD C4 -->|нет| C5{"Есть ли в команде
хоть один человек,
умеющий чинить Linux в 4 утра?"} C5 -->|нет| MAN["Managed-платформа:
DO App Platform, Render,
Fly.io, managed БД"] C5 -->|да| C6{"Egress > 5 ТБ/мес
или диск — узкое место?"} C6 -->|да| METAL["Bare metal:
экономия 3–8×"] C6 -->|нет| C7{"Бюджет на инфру
> 1 500 $/мес?"} C7 -->|да| METAL C7 -->|нет| VPS["VPS/VDS:
простота без переплаты"] style CLOUD fill:#e76f51,color:#fff style METAL fill:#4f9d69,color:#fff style VPS fill:#3d8bcd,color:#fff style HYB fill:#6a4fa3,color:#fff style MAN fill:#d9a441,color:#000
Обратите внимание на узел про человека, умеющего чинить Linux. Это не шутка и не про «настоящих админов» — это про наличие компетенции как актива. Экономия 3 000 $ в месяц не имеет смысла, если единственный носитель знаний ушёл в отпуск, а база не поднимается.
Практика: инфраструктура на Hetzner через Terraform
Абстрактные рассуждения бесполезны без рабочего кода. Ниже — реальная конфигурация: три ноды в приватной сети, файрвол, балансировщик, отдельный том под данные. Про Terraform в общем — https://courses.digitable.life/post/devops/09-terraform-and-iac/.
# versions.tf
terraform {
required_version = ">= 1.6"
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "~> 1.49"
}
}
# state — не в облаке Hetzner, а там, где он переживёт потерю провайдера
backend "s3" {
bucket = "acme-tfstate"
key = "prod/hetzner.tfstate"
region = "auto"
endpoint = "https://<account>.r2.cloudflarestorage.com"
skip_credentials_validation = true
skip_region_validation = true
skip_requesting_account_id = true
use_path_style = true
}
}
variable "hcloud_token" {
type = string
sensitive = true
}
provider "hcloud" {
token = var.hcloud_token
}
# network.tf — приватная сеть: весь внутренний трафик не выходит в интернет и не тарифицируется
resource "hcloud_network" "core" {
name = "core"
ip_range = "10.10.0.0/16"
labels = { env = "prod" }
}
resource "hcloud_network_subnet" "app" {
network_id = hcloud_network.core.id
type = "cloud"
network_zone = "eu-central" # покрывает fsn1, nbg1, hel1
ip_range = "10.10.1.0/24"
}
# Файрвол — обязательно на уровне провайдера, а не только iptables внутри ВМ:
# он отсекает пакеты ДО вашей машины и не зависит от состояния ОС
resource "hcloud_firewall" "app" {
name = "app-fw"
rule {
direction = "in"
protocol = "tcp"
port = "22"
source_ips = ["203.0.113.10/32"] # только бастион/офис, не 0.0.0.0/0
description = "SSH с бастиона"
}
rule {
direction = "in"
protocol = "tcp"
port = "443"
source_ips = ["0.0.0.0/0", "::/0"]
}
rule {
direction = "in"
protocol = "icmp"
source_ips = ["0.0.0.0/0", "::/0"] # не отключайте ICMP: сломаете Path MTU Discovery
}
}
# servers.tf
resource "hcloud_ssh_key" "ops" {
name = "ops-team"
public_key = file("${path.module}/keys/ops.pub")
}
resource "hcloud_server" "app" {
count = 3
name = "app-${count.index + 1}"
server_type = "ccx23" # 4 dedicated vCPU / 16 ГБ — предсказуемая задержка
image = "debian-12"
location = element(["fsn1", "nbg1", "hel1"], count.index) # разные ДЦ = разные домены отказа
ssh_keys = [hcloud_ssh_key.ops.id]
firewall_ids = [hcloud_firewall.app.id]
user_data = file("${path.module}/cloud-init/app.yaml")
public_net {
ipv4_enabled = true # с 2024 у Hetzner платный IPv4 (~0,50 €/мес) — отключайте, где не нужен
ipv6_enabled = true
}
network {
network_id = hcloud_network.core.id
ip = "10.10.1.${count.index + 11}"
}
labels = { env = "prod", role = "app" }
lifecycle {
# защита от «terraform apply снёс прод»: смена image пересоздаёт сервер
ignore_changes = [image]
}
}
# Отдельный том под данные: переживает пересоздание сервера и переносится между машинами
resource "hcloud_volume" "pgdata" {
name = "pgdata"
size = 200 # ГБ, ~0,044 €/ГБ/мес
server_id = hcloud_server.app[0].id
automount = false # монтируем сами, через cloud-init/Ansible
delete_protection = true
format = "ext4"
}
resource "hcloud_load_balancer" "lb" {
name = "app-lb"
load_balancer_type = "lb11" # ~5,4 €/мес
location = "fsn1"
}
resource "hcloud_load_balancer_target" "app" {
count = 3
type = "server"
load_balancer_id = hcloud_load_balancer.lb.id
server_id = hcloud_server.app[count.index].id
use_private_ip = true # трафик LB → сервер по приватной сети
}
resource "hcloud_load_balancer_service" "https" {
load_balancer_id = hcloud_load_balancer.lb.id
protocol = "tcp"
listen_port = 443
destination_port = 443
health_check {
protocol = "tcp"
port = 443
interval = 10
timeout = 5
retries = 3
}
}
output "app_ips" {
value = hcloud_server.app[*].ipv4_address
}
# cloud-init/app.yaml — базовая закалка машины при первой загрузке
#cloud-config
package_update: true
package_upgrade: true
packages:
- fail2ban
- unattended-upgrades
- ufw
- chrony
- prometheus-node-exporter
- restic
users:
- name: deploy
groups: [sudo]
shell: /bin/bash
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA... ops@acme
write_files:
- path: /etc/ssh/sshd_config.d/99-hardening.conf
content: |
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers deploy
ClientAliveInterval 300
- path: /etc/sysctl.d/99-net.conf
content: |
# разумные значения для сервера, отдающего много соединений
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_tw_reuse = 1
vm.swappiness = 10
# обязательно, если запускаете контейнеры/k3s
net.ipv4.ip_forward = 1
- path: /etc/apt/apt.conf.d/51unattended-extra
content: |
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
runcmd:
- [systemctl, restart, ssh]
- [sysctl, --system]
- [systemctl, enable, --now, fail2ban]
# k3s-нода: см. отдельную статью трека про лёгкие дистрибутивы
- curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--flannel-iface=enp7s0" sh -s -
Разворачивается это за одну команду:
$ terraform apply -var-file=prod.tfvars
...
hcloud_server.app[0]: Creation complete after 12s [id=48291043]
hcloud_server.app[1]: Creation complete after 14s [id=48291044]
hcloud_server.app[2]: Creation complete after 13s [id=48291051]
hcloud_load_balancer_service.https: Creation complete after 3s
Apply complete! Resources: 11 added, 0 changed, 0 destroyed.
# сервер готов к работе примерно через 40 секунд после создания
$ hcloud server list
ID NAME STATUS IPV4 PRIVATE NET LOCATION
48291043 app-1 running 159.69.x.x 10.10.1.11 fsn1
48291044 app-2 running 116.203.x.x 10.10.1.12 nbg1
48291051 app-3 running 65.108.x.x 10.10.1.13 hel1
Итог: три dedicated-vCPU-машины + LB + том = около 95 €/мес. Сопоставимая конструкция в AWS (3 × m7i.xlarge + ALB + 200 ГБ gp3 + NAT + egress) — около 620 $/мес. Это и есть та самая разница, ради которой всё затевается: 6 300 $ экономии в год на одном небольшом окружении.
Про k3s поверх такой раскладки — https://courses.digitable.life/post/devops/07-k3s-and-lightweight/; про GitOps-доставку в него — https://courses.digitable.life/post/devops/08-helm-and-gitops/.
Что придётся построить самому
Это самая честная часть статьи. Разница в счёте — не подарок, а перенос работы на вас. Ниже — что именно вы забираете себе вместе с экономией.
| Управляемый сервис | Аналог на своём железе | Разовые часы | Часы/мес | Что реально болит |
|---|---|---|---|---|
| RDS PostgreSQL Multi-AZ | PostgreSQL + Patroni + etcd + pgBackRest | 30–60 | 3–6 | failover, апгрейд мажорной версии, PITR-восстановление |
| ElastiCache | Redis Sentinel или Valkey | 8–16 | 1 | split-brain, персистентность |
| ALB/NLB | HAProxy / Caddy / Traefik + keepalived | 8–20 | 1–2 | TLS-сертификаты, drain при деплое |
| S3 | MinIO/Ceph — не делайте, берите R2/B2 | — | — | durability на своём железе — иллюзия |
| CloudWatch | Prometheus + Loki + Grafana | 20–40 | 2–4 | ретеншен, кардинальность, алерты |
| IAM | SSH-ключи + sudo + Vault/SOPS | 10–20 | 1–2 | ротация, offboarding |
| Autoscaling Group | скрипт над API хостера или Cluster Autoscaler | 10–30 | 1 | скорость реакции, лимиты аккаунта |
| KMS / Secrets Manager | SOPS + age, или свой Vault | 8–16 | 1 | ключи от ключей, восстановление |
| Route 53 health checks | внешний мониторинг + скрипт переключения | 4–8 | 0,5 | ложные срабатывания |
Суммарно на типовой продакшн: 120–200 часов первоначальной настройки и 10–18 часов в месяц на поддержку. По ставке 40 $/час это 480–720 $/мес операционных затрат плюс 5–8 тысяч разово. Если экономия на счёте — 3 000 $/мес, сделка отличная. Если 400 $/мес — вы только что купили себе работу.
Отсюда практический порог, к которому сходится большинство команд: ниже примерно 1 000–1 500 $/мес расходов на инфраструктуру своё железо экономически не оправдано — управленческие издержки съедают выигрыш. Выше 5 000 $/мес — оправдано почти всегда. Между — считайте по своей ситуации, честно включая стоимость своего времени.
Отказы: чем всё это кончается в реальности
В облаке отказ узла — событие категории «под заменили, никто не заметил». На выделенном сервере это событие категории «инцидент». Разберём жизненный цикл честно.
или монтаж (bare metal: 1 ч – 3 дня) Провижининг --> Продакшн: cloud-init + Ansible + проверки Продакшн --> Деградация: SMART-предупреждение,
ECC-ошибки, рост задержек Продакшн --> Отказ: диск, БП, память, коммутатор Деградация --> Слив: увести трафик заранее Слив --> Обслуживание: тикет в саппорт Отказ --> Rescue: загрузка в rescue-систему,
снятие данных Rescue --> Обслуживание Обслуживание --> Провижининг: замена железа,
переустановка с нуля Обслуживание --> Списан: не чинится / устарел Продакшн --> Списан: миграция на новое поколение Списан --> [*] note right of Отказ Ключевой вопрос: сколько стоит час в этом состоянии? Если > стоимости второго сервера — берите второй. end note
Что происходит при отказе диска на выделенном сервере Hetzner:
+ mdraid degraded O->>LB: Убрать app-2 из пула (drain) LB-->>O: Соединения слиты за 30 с O->>H: Тикет: «замена диска в слоте 2, S/N ...» Note over O,H: SLA на реакцию: 30–60 минут в рабочее время,
ночью — как повезёт, если нет платного контракта H-->>O: «Диск заменён, сервер загружен» O->>S: mdadm --add /dev/md0 /dev/nvme1n1p1 S-->>O: resync 2,4 ТБ ≈ 3–5 часов Note over S: Всё это время массив без избыточности —
второй отказ = потеря данных O->>M: Проверить, что восстановление завершено O->>LB: Вернуть app-2 в пул rect rgb(231, 111, 81, 0.15) Note over O,H: Итого: 4–8 человеко-часов внимания.
В облаке этого шага не существует вовсе. end
Из этого следуют три обязательных практики.
Первая: RAID — не опция. Любой выделенный сервер с данными берётся минимум с двумя NVMe в RAID1 (mdadm или ZFS mirror). Провайдеры продают конфигурации с одним диском — они годятся только для stateless-нод.
# при заказе Hetzner: разметка через installimage
$ installimage -a -r yes -l 1 -i images/Debian-1206-bookworm-amd64-base.tar.gz \
-p /boot:ext3:1G,lvm:vg0:all -v vg0:root:/:ext4:40G,vg0:data:/var/lib:xfs:400G \
-d nvme0n1,nvme1n1 -n app-2
# проверка состояния массива — в мониторинг, не в память дежурного
$ cat /proc/mdstat
Personalities : [raid1]
md0 : active raid1 nvme0n1p1[0] nvme1n1p1[1]
1000068608 blocks super 1.2 [2/2] [UU]
bitmap: 3/8 pages [12KB], 65536KB chunk
Вторая: бэкапы — offsite и проверяемые. Снапшот на том же хостере не защищает от потери аккаунта, ошибки биллинга или пожара в ДЦ (см. OVH Страсбург, март 2021). Схема 3-2-1: три копии, два носителя, одна вне площадки.
# /etc/restic/env — учётки; бэкенд — Backblaze B2 или Cloudflare R2, где egress бесплатный
export RESTIC_REPOSITORY="s3:https://s3.eu-central-003.backblazeb2.com/acme-backups/pg"
export RESTIC_PASSWORD_FILE="/etc/restic/passphrase"
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
#!/usr/bin/env bash
# /usr/local/bin/backup-pg.sh — базовый бэкап PostgreSQL с WAL-архивом
set -euo pipefail
source /etc/restic/env
# консистентный физический бэкап без остановки базы
pg_basebackup -D - -Ft -X none -c fast \
| restic backup --stdin --stdin-filename "base-$(date -u +%FT%TZ).tar" \
--tag pg --tag base --host "$(hostname -s)"
# ретеншен: политика, а не «удалю руками когда-нибудь»
restic forget --tag pg --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune
# ПРОВЕРКА — без неё бэкапов нет, есть иллюзия бэкапов
restic check --read-data-subset=5%
# /etc/systemd/system/backup-pg.timer
[Unit]
Description=Ночной базовый бэкап PostgreSQL
[Timer]
OnCalendar=*-*-* 02:17:00
RandomizedDelaySec=900
Persistent=true
[Install]
WantedBy=timers.target
Раз в квартал — учебное восстановление на чистую машину с секундомером. Цифра, которую вы получите, и есть ваш реальный RTO. Всё остальное — фантазии. Untested backup is not a backup.
Третья: считайте доступность честно. Один сервер даёт вам где-то 99,5–99,9 % в год — это 9–44 часа простоя. Не потому, что железо плохое, а потому что бывают перезагрузки, апгрейды ядра, замены дисков и работы в ДЦ. Два сервера в разных ДЦ с автоматическим переключением дают 99,95 %+, но требуют, чтобы переключение действительно работало — а оно ломается ровно тогда, когда нужно. Проверяется учениями, а не верой.
# floating IP у Hetzner: переключается за секунды через API — основа дешёвого HA
$ hcloud floating-ip assign 12345 app-2
Floating IP 12345 assigned to server app-2
# в keepalived это делает скрипт по смене состояния VRRP
# /etc/keepalived/notify.sh
#!/bin/bash
[ "$3" = "MASTER" ] && curl -sS -X POST \
-H "Authorization: Bearer $HCLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"server\": $(cat /etc/hcloud-server-id)}" \
"https://api.hetzner.cloud/v1/floating_ips/12345/actions/assign"
Три расчёта из жизни
Абстракции заканчиваются, начинается арифметика. Все цифры — порядок величины на начало 2026 года; проверяйте актуальные прайсы.
Сценарий A: MVP, 2 разработчика, 500 пользователей
Нужно: приложение, PostgreSQL, Redis, объектное хранилище на 50 ГБ, CI.
| Вариант | Состав | $/мес | Комментарий |
|---|---|---|---|
| AWS (наивно) | t3.medium × 2, RDS db.t3.small Multi-AZ, ElastiCache, ALB, NAT | ~320 | NAT Gateway 35 $ за пустоту — классика |
| AWS (аккуратно) | t4g.small × 2, RDS Single-AZ, без NAT, S3 | ~120 | Graviton + отказ от лишнего |
| DigitalOcean | 2 × 2 vCPU/4 ГБ, managed PG 1 нода, Spaces | ~95 | самый низкий порог входа |
| Fly.io / Render | 2 инстанса + managed PG | ~70 | нулевая эксплуатация, потолок ниже |
| Hetzner | 1 × CPX31 (всё на одной машине), R2 | ~18 | требует умения администрировать |
Вывод: на этом масштабе разница в абсолютных деньгах мала (100–300 $), а разница во времени команды велика. Берите то, что требует меньше внимания: managed-платформу или DO. Экономия 80 $/мес не стоит одного вечера отладки репликации. Это тот самый случай, когда «дорогое» облако — рациональный выбор.
Сценарий B: SaaS, 40 сотрудников, 15 ТБ egress
Нужно: ~24 vCPU под приложение, PostgreSQL 500 ГБ с репликой, Redis, поиск, CI на 40 сборок в день, стейджинг.
| Вариант | $/мес | Из чего складывается |
|---|---|---|
| AWS on-demand | ~4 100 | EKS 73 + ноды 1 500 + RDS Multi-AZ 900 + egress 1 350 + CloudWatch 180 + NAT 100 |
| AWS с оптимизацией | ~2 400 | Savings Plans, Graviton, egress через CloudFront, логи в S3 |
| DigitalOcean | ~1 600 | DOKS + managed PG + Spaces, egress в основном покрыт пулом |
| Hetzner Cloud + R2 | ~520 | 8 × CCX33, LB, тома, объекты в R2 с нулевым egress |
| Hetzner bare metal + R2 | ~380 | 4 × AX52, k3s поверх, реплика PG на четвёртой машине |
Плюс операционные расходы: на Hetzner добавьте ~15 часов/мес × 40 $ = 600 $ и разово ~150 часов. Полный TCO Hetzner ≈ 1 120 $/мес, AWS с оптимизацией ≈ 2 400 + 5 часов/мес ≈ 2 600 $/мес.
Вывод: экономия около 18 000 $ в год — это уже половина ставки инженера. Переезд оправдан, если в команде есть компетенция. Обратите внимание, что решающий вклад дал не CPU, а egress: 1 350 $ против нуля.
Сценарий C: видеоплатформа, 200 ТБ egress/мес
| Вариант | $/мес egress | Итого |
|---|---|---|
| AWS S3 + CloudFront | ~14 000 (CDN дешевле прямого egress, но не бесплатен) | ~17 000 |
| Cloudflare R2 + CDN | 0 | ~3 500 |
| Bunny.net / Hetzner + свой origin | ~1 000 | ~1 800 |
Вывод: для трафикоёмких продуктов вопрос даже не обсуждается. Ни одна оптимизация compute не догонит десятикратную разницу в стоимости байтов. Отсюда — публичная история 37signals, которые вышли из облака и заявили об экономии около 2 млн $ в год, а также Dropbox, ушедший из S3 ещё в 2016-м на собственное хранилище.
Типичные ошибки
Считать только счёт за compute. В расчёт входят: ваше время, стоимость простоя, стоимость найма человека с нужными навыками, стоимость миграции обратно. Инженер, который тратит 20 % времени на инфраструктуру вместо продукта, стоит дороже, чем строка в счёте AWS.
Брать самый дешёвый VPS и удивляться. Contabo за 5 € — это Contabo за 5 €. Для продакшна с SLO берите dedicated vCPU. Разница в цене вдвое, разница в предсказуемости p99 — на порядок.
Экономить на IPv4 без плана. Hetzner берёт ~0,50 €/мес за IPv4 с 2024 года. На 100 машинах это 50 €. Отключать можно, но тогда нужен IPv6-only с NAT64/DNS64 наружу — и половина внешних API вас не примет. Решение: приватная сеть + один NAT-хост с публичным IPv4.
Не настроить файрвол провайдера. ufw внутри ВМ падает вместе с ВМ и не защищает от сканеров, которые найдут ваш SSH через 40 секунд после создания сервера. Файрвол на уровне API — обязателен.
Держать бэкапы у того же провайдера. Единая точка отказа: пожар, блокировка аккаунта, ошибка биллинга, спор о содержимом. Копия обязана лежать у другого юрлица в другой стране.
Игнорировать локальность диска. Локальный NVMe пропадает вместе с сервером. Данные, которые нельзя потерять, требуют либо репликации на вторую машину, либо сетевого тома (медленнее), либо и того и другого.
Обещать 99,99 % на одной машине. Один сервер — это 99,5–99,9 %. Если в контракте написано больше, вы уже должны клиенту.
Не читать AUP. Дешёвые хостеры жёстко относятся к майнингу, массовым рассылкам, сканированию, торрентам и внезапному росту трафика. Отключение аккаунта без предупреждения — реальный сценарий. Держите отчуждаемость: IaC, бэкапы, DNS с низким TTL.
Переезжать «весь целиком за квартал». Миграция из облака — это программа на 6–12 месяцев, а не спринт. Порядок: сначала статика и медиа в R2 (мгновенная выгода на egress), потом stateless-нагрузки, потом CI, и только в самом конце — базы.
Не проверять восстановление. Про это уже было, и это повторится в любой статье про эксплуатацию: незапротестированный бэкап — не бэкап.
Гибрид — то, к чему приходит большинство
Взрослая инфраструктура почти никогда не бывает чистой. Типичная раскладка команды, которая прошла обе крайности:
CDN + WAF + DDoS
0 $ egress"] CF --> LB["HAProxy / LB хостера
Hetzner, 2 ДЦ"] LB --> K["k3s-кластер
4 × bare metal
приложение, воркеры"] K --> PG[("PostgreSQL + реплика
локальный NVMe
Patroni")] K --> R2[("Cloudflare R2
объекты, 0 $ egress")] K -.->|"редкие тяжёлые задачи"| GPU["GPU по требованию
Vultr / Lambda Labs
почасово"] PG --> BK[("Backblaze B2
offsite-бэкапы
другое юрлицо")] K -.->|"пиковые распродажи"| CLOUD["Облачные ноды
по API за 60 с"] OBS["Prometheus + Loki
+ Grafana
на отдельной машине"] -.-> K OBS -.-> PG style CF fill:#d9a441,color:#000 style K fill:#4f9d69,color:#fff style PG fill:#3d8bcd,color:#fff style R2 fill:#6a4fa3,color:#fff style CLOUD fill:#e76f51,color:#fff
Логика простая и повторяемая:
- Постоянная предсказуемая нагрузка — на своём железе, где она стоит в разы дешевле.
- Байты наружу — через провайдера с нулевым egress. Это самый дешёвый рычаг из всех.
- Пики и редкие специальные ресурсы (GPU, гигантская память на час) — в облаке почасово, потому что покупать железо под пиковую нагрузку абсурдно.
- Состояние — там, где вы контролируете бэкапы, и с копией у другого вендора.
- DDoS и TLS-терминация — у того, кто занимается этим профессионально.
Ключевое условие, которое делает гибрид возможным без боли: всё описано кодом и не привязано к API одного вендора. Kubernetes/k3s, Terraform, контейнеры и стандартный S3-протокол — именно они превращают выбор провайдера из архитектурного решения в строчку в переменной. Это, пожалуй, главный аргумент в пользу того, чтобы терпеть сложность Kubernetes даже на маленьком масштабе.
Где проходит граница выбора
Обратите внимание на левый верхний угол — Cloudflare R2 и подобные ему сервисы. Это редчайший случай, когда дёшево и просто одновременно: специализированный сервис у специализированного вендора. Начинать оптимизацию всегда нужно оттуда, а не с переезда всего продакшна на железо.
Правый нижний угол — «дорого и сложно» — тоже реален: это, например, managed Kubernetes гиперскейлера у команды, которая всё равно управляет нодами, тюнит CNI и платит за control plane. Проверьте, не сидите ли вы там.
Юридика, риски и отчуждаемость
Технически железо равноценно облаку. Юридически — нет, и это часто оказывается решающим.
- Контракт и поддержка. У Hetzner нет менеджера аккаунта, к которому можно эскалировать. Тикеты, ответ часами. Если ваш SLA перед клиентом требует гарантированной реакции — нужен либо платный контракт (у OVH, Equinix, Selectel такие есть), либо гиперскейлер.
- Прекращение обслуживания. Дешёвые провайдеры отключают аккаунты по подозрению в нарушении AUP быстрее, чем разбираются. План на этот случай: IaC + offsite-бэкапы + DNS с TTL 60 секунд + проверенная процедура развёртывания у второго провайдера.
- Регуляторика. 152-ФЗ, GDPR-локализация, отраслевые требования. Место хранения персональных данных — не техническое решение.
- Санкционные и платёжные риски. Способ оплаты, юрисдикция провайдера, возможность внезапной блокировки — реальные факторы, а не паранойя. Диверсификация провайдеров стоит денег, но это страховка.
Практический тест на отчуждаемость, который стоит проводить раз в год: сможете ли вы поднять продакшн у другого провайдера за 8 часов, имея только Git-репозиторий и бэкапы? Если нет — вы привязаны сильнее, чем думаете, и неважно, к AWS или к Hetzner. Про безопасность этого пайплайна — https://courses.digitable.life/post/devops/17-security-in-pipeline/; про то, как понять, что всё работает, — https://courses.digitable.life/post/devops/16-observability-and-oncall/.
Мини-итог
- VPS и VDS сегодня — одно и то же; значение имеет тип виртуализации (KVM, а не OpenVZ) и тип vCPU (dedicated, а не shared). Проверяйте
%stealпод нагрузкой, а не описание тарифа. - Разница в цене с гиперскейлерами — 3–8× за такт и до 100× за трафик, и она реальна: за неё вы отдаёте SLA, managed-сервисы, compliance и экосистему.
- Egress — самый дешёвый рычаг экономии. Прежде чем переезжать на железо, вынесите статику и медиа туда, где исходящий трафик бесплатен. Часто на этом оптимизация и заканчивается.
- Локальный NVMe быстрее сетевого тома на один-два порядка — это отдельный, часто решающий аргумент для баз данных.
- Экономия — это перенос работы на себя: 120–200 часов разово и 10–18 часов в месяц. Ниже ~1 500 $/мес счёта переезд обычно не окупается, выше ~5 000 $/мес — окупается почти всегда.
- Один сервер — это 99,5–99,9 %. Хотите больше — два сервера в разных ДЦ и регулярные учения по переключению.
- RAID1, offsite-бэкапы у другого вендора и проверенное восстановление — не хорошие практики, а условие допуска на этот уровень.
- Целевое состояние для большинства — гибрид, а не крайность: своё железо под базовую нагрузку, специализированные вендоры под трафик и хранение, облако под пики.
Источники
- Hetzner Cloud API и Terraform-провайдер — рабочая документация с примерами всех ресурсов из статьи.
- DigitalOcean Tutorials — лучшая практическая документация по администрированию Linux в индустрии, полезна независимо от провайдера.
- 37signals: The Big Cloud Exit FAQ и Why we’re leaving the cloud — публичные цифры реального выхода из облака, с критикой и ответами.
- Dropbox Magic Pocket — инженерный разбор ухода с S3 на собственное хранилище эксабайтного масштаба.
- Cloudflare R2 pricing — модель без платы за egress и обоснование, почему она возможна.
- Brendan Gregg, «Systems Performance», 2nd ed. — эталон по измерению CPU, диска и сети; главы про виртуализацию объясняют steal time с первых принципов.
- fio documentation и sysbench — инструменты честного сравнения провайдеров.
- restic documentation — дедуплицирующие бэкапы с шифрованием на стороне клиента.
- Patroni и pgBackRest — то, чем заменяют RDS, если решились.
- Hetzner Robot: installimage и Rescue System — как разметить выделенный сервер и что делать, когда он не грузится.
- The Cloud Native Attitude / CNCF FinOps materials — дисциплина управления облачными расходами, к которой мы переходим дальше.
Что дальше
Мы сравнили варианты качественно и посчитали три сценария на салфетке. Следующий шаг — построить настоящую финансовую модель: амортизация железа, стоимость капитала, скрытые статьи облачного счёта, юнит-экономика на запрос и практики FinOps, позволяющие управлять расходами постоянно, а не раз в год в панике. Об этом — Стоимость инфраструктуры: облако против своего железа, FinOps, реальные расчёты.