CI/CD, инфраструктура и облака VPS, VDS, выделенные серверы и DigitalOcean/Hetzner: когда простое дешевле облака
0%

VPS, VDS, выделенные серверы и DigitalOcean/Hetzner: когда простое дешевле облака

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/.

Спектр управляемости: за что вы платите разницу

Правильная ментальная модель — не «облако против сервера», а лестница ответственности. Каждая ступень снимает с вас работу и добавляет к счёту.

Ключевая мысль: вы не выбираете уровень для всей компании — вы выбираете его для каждой рабочей нагрузки отдельно. Совершенно нормальная архитектура: PostgreSQL и приложение на bare metal в Хельсинки, объектное хранилище в Cloudflare R2, CDN в Cloudflare, редко используемая ML-инференция на GPU по требованию в облаке, DNS у регистратора. Такая система дешевле чисто облачной в 4–6 раз и почти не сложнее в эксплуатации, если границы проведены по правильным местам.

Почему разница в цене такая огромная

Цена сопоставимой конфигурации 8 vCPU / 32 ГБ у разных провайдеров

Восемнадцатикратный разброс за одну и ту же спецификацию требует объяснения. Железо у всех примерно одинаковое: тот же 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: что мерить

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» на любых медийных нагрузках.

Дерево решения

Обратите внимание на узел про человека, умеющего чинить 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 $/мес — оправдано почти всегда. Между — считайте по своей ситуации, честно включая стоимость своего времени.

Отказы: чем всё это кончается в реальности

В облаке отказ узла — событие категории «под заменили, никто не заметил». На выделенном сервере это событие категории «инцидент». Разберём жизненный цикл честно.

Что происходит при отказе диска на выделенном сервере Hetzner:

Из этого следуют три обязательных практики.

Первая: 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, и только в самом конце — базы.

Не проверять восстановление. Про это уже было, и это повторится в любой статье про эксплуатацию: незапротестированный бэкап — не бэкап.

Гибрид — то, к чему приходит большинство

Взрослая инфраструктура почти никогда не бывает чистой. Типичная раскладка команды, которая прошла обе крайности:

Логика простая и повторяемая:

  • Постоянная предсказуемая нагрузка — на своём железе, где она стоит в разы дешевле.
  • Байты наружу — через провайдера с нулевым 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-бэкапы у другого вендора и проверенное восстановление — не хорошие практики, а условие допуска на этот уровень.
  • Целевое состояние для большинства — гибрид, а не крайность: своё железо под базовую нагрузку, специализированные вендоры под трафик и хранение, облако под пики.

Источники

Что дальше

Мы сравнили варианты качественно и посчитали три сценария на салфетке. Следующий шаг — построить настоящую финансовую модель: амортизация железа, стоимость капитала, скрытые статьи облачного счёта, юнит-экономика на запрос и практики FinOps, позволяющие управлять расходами постоянно, а не раз в год в панике. Об этом — Стоимость инфраструктуры: облако против своего железа, FinOps, реальные расчёты.

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов