Автоматический бэкап etcd в S3 создаёт опасную иллюзию защищенности, которая рушится при первом реальном инциденте в HA-кластере K3s. Когда вы запускаете процедуру восстановления на одном из мастеров, встроенный etcd пытается накатить снепшот поверх текущей структуры Raft. Если остальные управляющие узлы продолжают работать или сохранили старые данные в локальном хранилище, кластер мгновенно рассинхронизируется и блокирует операции записи. Рабочий регламент аварийного восстановления требует жесткой технической последовательности: - Полная остановка службы k3s на всех control-plane узлах кластера. - Очистка каталога /var/lib/rancher/k3s/server/db/etcd на всех ведомых мастерах для уничтожения старого состояния Raft. - Запуск процедуры cluster-reset на первичном узле с флагами --etcd-s3-enabled, --etcd-s3-bucket и указанием конкретного файла через --cluster-reset-restore-path или --etcd-s3-snapshot-name. - Проверка запуска одиночного кворума и последовательное переприсоединение остальных ...
Автоматический бэкап etcd в S3 создаёт опасную иллюзию защищенности, которая рушится при первом реальном инциденте в HA-кластере K3s. Когда вы запускаете процедуру восстановления на одном из мастеров, встроенный etcd пытается накатить снепшот поверх текущей структуры Raft. Если остальные управляющие узлы продолжают работать или сохранили старые данные в локальном хранилище, кластер мгновенно рассинхронизируется и блокирует операции записи. Рабочий регламент аварийного восстановления требует жесткой технической последовательности: - Полная остановка службы k3s на всех control-plane узлах кластера. - Очистка каталога /var/lib/rancher/k3s/server/db/etcd на всех ведомых мастерах для уничтожения старого состояния Raft. - Запуск процедуры cluster-reset на первичном узле с флагами --etcd-s3-enabled, --etcd-s3-bucket и указанием конкретного файла через --cluster-reset-restore-path или --etcd-s3-snapshot-name. - Проверка запуска одиночного кворума и последовательное переприсоединение остальных серверов через сброс их локальной базы. Отдельная точка отказа — учетные данные S3 и node-token. Если восстановление выполняется на с нуля развернутый нод, K3s не сможет прочитать настройки S3 из неинициализированной базы. Все ключи доступа, эндпоинты и параметры bucket должны быть явно прописаны в файле конфигурации config.yaml до момента выполнения команды сброса, иначе старт завершится ошибкой авторизации API. Разборы сетевых инцидентов, регламенты сборки отказоустойчивых bare-metal инфраструктур и сценарии DR регулярно выходят в проекте https://ftops.space.
Гиперскейлеры продают гигагерцы и гигабайты, но умалчивают про реальную структуру сетевых задержек. В пулах EKS или GKE межзональный трафик проходит через слои виртуализации vNIC, фильтры гипервизора и оверлейные сети. Результат — устойчивый p99 latency между нодами на уровне 1.8–3.2 миллисекунд. В K3s-кластере на голом железе с прямым 10GbE/100GbE L2-фабриком и eBPF-маршрутизацией без оверлея межнодовая задержка падает до 80–150 микросекунд. Для транзакционных баз данных и распределенного кэша это разница между падением пропускной способности и стабильной работой под пиковой нагрузкой. Финансовая модель облака окончательно ломается на блочных хранилищах и межзональном egress. Гарантированные 30 000 IOPS на io2 или gp3 с высоким лимитом операций обходятся в месяц дороже, чем разовый закуп двух корпоративных U.3 NVMe накопителей с ресурсом 3 DWPD. K3s на bare-metal позволяет отдавать подам сырые диски через Local Path Provisioner или собирать распределенное хранилище на Rook-Ceph с прям...
Гиперскейлеры продают гигагерцы и гигабайты, но умалчивают про реальную структуру сетевых задержек. В пулах EKS или GKE межзональный трафик проходит через слои виртуализации vNIC, фильтры гипервизора и оверлейные сети. Результат — устойчивый p99 latency между нодами на уровне 1.8–3.2 миллисекунд. В K3s-кластере на голом железе с прямым 10GbE/100GbE L2-фабриком и eBPF-маршрутизацией без оверлея межнодовая задержка падает до 80–150 микросекунд. Для транзакционных баз данных и распределенного кэша это разница между падением пропускной способности и стабильной работой под пиковой нагрузкой. Финансовая модель облака окончательно ломается на блочных хранилищах и межзональном egress. Гарантированные 30 000 IOPS на io2 или gp3 с высоким лимитом операций обходятся в месяц дороже, чем разовый закуп двух корпоративных U.3 NVMe накопителей с ресурсом 3 DWPD. K3s на bare-metal позволяет отдавать подам сырые диски через Local Path Provisioner или собирать распределенное хранилище на Rook-Ceph с прямой PCI-пропускной способностью. Вы убираете из бюджета наценку гиперскейлера за эмуляцию дискового контроллера и плату за внутренний сетевой трафик. Переход на bare-metal K3s требует инженерной зрелости: вы сами отвечаете за драйверы, жизненный цикл ядра Linux (включая своевременный патчинг уязвимостей масштаба Pedit COW), тюнинг sysctl и настройку WireGuard mesh для связывания площадок. Но в обмен вы получаете точное планирование ресурсов без эффекта noisy neighbors, полный контроль над NUMA-топологией процессора и предсказуемую юнит-экономику без внезапных счетов за облачный трафик. Практические схемы сборки bare-metal узлов, регламенты оптимизации сетевого стека ядра и архитектуру K3s для высоконагруженных систем мы регулярно публиуем на https://ftops.space.
Дефолтные настройки ImageGC в Kubernetes рассчитаны на гиперскейлеры и ноды с сотнями гигабайт памяти. На небольших VPS с диском 20-40 ГБ стандартный параметр imageGCHighThresholdPercent=85 выставляет смертельную ловушку: сборка мусора начинается только тогда, когда на диске остается 3-5 ГБ. В условиях интенсивного деплоя или роста ephemeral-storage локальная файловая система забивается быстрее, чем kubelet успевает запустить цикл очистки containerd. При достижении порога нода мгновенно получает taint DiskPressure. Kubelet начинает хаотично эвиктить поды, ломая консенсус K3s и переводя файловую систему бюджетного VPS в read-only из-за I/O-ограничений провайдера. Проблема усугубляется тем, что сборщик не трогает образы, созданные меньше чем imageMinimumGCAge назад (по умолчанию 2 минуты), а старые логи контейнеров не входят в зону ответственности ImageGC. Для стабильной работы мелких узлов дисковую гигиену нужно переводить в жесткий режим через конфигурацию K3s (/etc/rancher/k3s/config....
Дефолтные настройки ImageGC в Kubernetes рассчитаны на гиперскейлеры и ноды с сотнями гигабайт памяти. На небольших VPS с диском 20-40 ГБ стандартный параметр imageGCHighThresholdPercent=85 выставляет смертельную ловушку: сборка мусора начинается только тогда, когда на диске остается 3-5 ГБ. В условиях интенсивного деплоя или роста ephemeral-storage локальная файловая система забивается быстрее, чем kubelet успевает запустить цикл очистки containerd. При достижении порога нода мгновенно получает taint DiskPressure. Kubelet начинает хаотично эвиктить поды, ломая консенсус K3s и переводя файловую систему бюджетного VPS в read-only из-за I/O-ограничений провайдера. Проблема усугубляется тем, что сборщик не трогает образы, созданные меньше чем imageMinimumGCAge назад (по умолчанию 2 минуты), а старые логи контейнеров не входят в зону ответственности ImageGC. Для стабильной работы мелких узлов дисковую гигиену нужно переводить в жесткий режим через конфигурацию K3s (/etc/rancher/k3s/config.yaml): kubelet-arg: - image-gc-high-threshold=60 - image-gc-low-threshold=45 - image-minimum-gc-age=1m - eviction-hard=nodefs.available<10%,nodefs.inodesFree<5% Дополнительно зафиксируйте SystemMaxUse=1G в journald.conf и ограничьте размер логов контейнеров через max-size в containerd. На малых объемах управление памятью строится не от пиковых нагрузок, а от физической скорости выедания диска. Разбор оптимизации Bare-Metal и K3s стека читайте на https://ftops.space.
На сетевых интерфейсах 10G+ при высокоинтенсивном трафике классическая проблема фильтрации заключается не только в скорости прохождения пакета по цепочке, но и в поведении подсистемы при динамическом изменении правил. Когда автоматизированные системы защиты, IPS или сетевые контроллеры пытаются оперативно заблокировать атаки или обновить адреса, legacy-стек iptables блокирует весь пайплайн. Каждое изменение в iptables требует полного копирования монолитного массива правил из пространства пользователя в ядро через iptables mutex. На мультигигабитных каналах это приводит к сбросу кешей процессора, cache line bouncing между NUMA-узлами и микроскопическим задержкам, вызывающим потерю пакетов в сетевых очередях NIC. Архитектура nftables решает эту проблему за счет переноса логики в специализированную виртуальную машину ядра (nftvm) и применения нативных структур данных: - Атомарные транзакции: обновления передаются через netlink-сообщения коммитом конкретных элементов, без перезагрузки вс...
На сетевых интерфейсах 10G+ при высокоинтенсивном трафике классическая проблема фильтрации заключается не только в скорости прохождения пакета по цепочке, но и в поведении подсистемы при динамическом изменении правил. Когда автоматизированные системы защиты, IPS или сетевые контроллеры пытаются оперативно заблокировать атаки или обновить адреса, legacy-стек iptables блокирует весь пайплайн. Каждое изменение в iptables требует полного копирования монолитного массива правил из пространства пользователя в ядро через iptables mutex. На мультигигабитных каналах это приводит к сбросу кешей процессора, cache line bouncing между NUMA-узлами и микроскопическим задержкам, вызывающим потерю пакетов в сетевых очередях NIC. Архитектура nftables решает эту проблему за счет переноса логики в специализированную виртуальную машину ядра (nftvm) и применения нативных структур данных: - Атомарные транзакции: обновления передаются через netlink-сообщения коммитом конкретных элементов, без перезагрузки всей таблицы и без заморозки проходящего трафика. - Поиск за O(1): вместо последовательного прогона пакета по сотням правил iptables используются встроенные сеты и мапы на базе хэш-таблиц и rbtree. - Оптимизация памяти: динамические списки IP-адресов подгружаются прямо в структуры ядра без вызова пересборки графа правил. Для высоконагруженных bare-metal маршрутизаторов и пограничных узлов K3s полный отказ от iptables в пользу нативного nftables избавляет сетевой стек от просадок производительности при постоянной смене правил фильтрации. Практические разборы оптимизации сетевого стека ядра и архитектуры устойчивых сервисов выложены на https://ftops.space.
Настройка сетевого стека ядра под высокий RPS в bare-metal окружении часто превращается в карго-культ. Инженеры прописывают net.core.somaxconn = 65535 в sysctl.conf, но забывают, что ядро Linux берет минимальное значение между somaxconn и аргументом backlog в системном вызове listen(). Если Nginx, Envoy или Go-сервис скомпилирован с дефолтным backlog 512, ядро срежет очередь listen-сокета до 512. При микроспайке входящих TCP-соединений очередь переполняется, и ядро начинает молча выбрасывать SYN-пакеты, создавая искусственные таймауты у клиентов. Второй источник частых аварий — некорректная работа с TIMEWAIT сокетами при высокой плотности исходящих соединений. Параметр net.ipv4.tcptwreuse позволяет ядру повторно использовать сокеты в состоянии TIMEWAIT, но только если на обеих сторонах включены RFC 1323 timestamps через net.ipv4.tcptimestamps = 1. Если ради выигрыша CPU отключить tcptimestamps, tcptwreuse просто перестает работать, приводя к исчерпанию локальных портов (ephemer...
Настройка сетевого стека ядра под высокий RPS в bare-metal окружении часто превращается в карго-культ. Инженеры прописывают net.core.somaxconn = 65535 в sysctl.conf, но забывают, что ядро Linux берет минимальное значение между somaxconn и аргументом backlog в системном вызове listen(). Если Nginx, Envoy или Go-сервис скомпилирован с дефолтным backlog 512, ядро срежет очередь listen-сокета до 512. При микроспайке входящих TCP-соединений очередь переполняется, и ядро начинает молча выбрасывать SYN-пакеты, создавая искусственные таймауты у клиентов. Второй источник частых аварий — некорректная работа с TIME_WAIT сокетами при высокой плотности исходящих соединений. Параметр net.ipv4.tcp_tw_reuse позволяет ядру повторно использовать сокеты в состоянии TIME_WAIT, но только если на обеих сторонах включены RFC 1323 timestamps через net.ipv4.tcp_timestamps = 1. Если ради выигрыша CPU отключить tcp_timestamps, tcp_tw_reuse просто перестает работать, приводя к исчерпанию локальных портов (ephemeral port exhaustion). При этом параметр tcp_tw_recycle из ядра давно удален за порчу трафика за NAT, но до сих пор встречается в устаревших инструкциях. Даже идеальный сетевой стек бесполезен, если сервис упирается в файловые дескрипторы. Каждый сетевой сокет в Linux — это файловый дескриптор. Общий лимит sysctl fs.file-max определяет емкость всей системы, но для конкретного процесса определяющим является ulimit. В дистрибутивах с systemd параметры из limits.conf игнорируются для демонов. Без явно прописанного LimitNOFILE=1048576 в unit-файле K3s, Nginx или ingress-контроллера сервис остановит прием новых соединений с ошибкой EMFILE (Too many open files) задолго до исчерпания RAM. Правильный тюнинг ядра требует сквозного аудита: от настроек самого приложения (backlog) и лимитов systemd (LimitNOFILE) до sysctl (somaxconn, tcp_max_syn_backlog, tcp_tw_reuse) и параметров ring-буферов сетевой карты. Настройка одного параметра в отрыве от цепочки всегда приводит к падению под нагрузкой. Практические регламенты отладки bare-metal инфраструктуры и сетевого стека ядра разбираем на https://ftops.space.
Периодические задержки ответов микросервисов ровно в 5 секунд — классический симптом race condition в подсистеме netfilter Linux. В Kubernetes при отправке параллельных DNS-запросов по протоколу UDP несколько подов на одной ноде одновременно обращаются к ClusterIP сервиса CoreDNS. Таблица conntrack пытается выполнить DNAT для двух идентичных потоков до завершения инициализации записи, из-за чего ядро молча отбрасывает один из пакетов. Повторная отправка пакета клиентом происходит только по истечении пятисекундного таймаута glibc. Инженерное решение этой проблемы заключается в разворачивании NodeLocal DNSCache. Компонент запускается как DaemonSet на каждой ноде кластера и поднимает виртуальный IP-адрес (обычно 169.254.20.10) на интерфейсе loopback. Это меняет механику обработки трафика на физическом узле: - Запросы приложений перенаправляются на локальный сокет, исключая прохождение через цепочки DNAT iptables. - Для локального DNS-трафика включается правило NOTRACK в таблице raw, полно...
Периодические задержки ответов микросервисов ровно в 5 секунд — классический симптом race condition в подсистеме netfilter Linux. В Kubernetes при отправке параллельных DNS-запросов по протоколу UDP несколько подов на одной ноде одновременно обращаются к ClusterIP сервиса CoreDNS. Таблица conntrack пытается выполнить DNAT для двух идентичных потоков до завершения инициализации записи, из-за чего ядро молча отбрасывает один из пакетов. Повторная отправка пакета клиентом происходит только по истечении пятисекундного таймаута glibc. Инженерное решение этой проблемы заключается в разворачивании NodeLocal DNSCache. Компонент запускается как DaemonSet на каждой ноде кластера и поднимает виртуальный IP-адрес (обычно 169.254.20.10) на интерфейсе loopback. Это меняет механику обработки трафика на физическом узле: - Запросы приложений перенаправляются на локальный сокет, исключая прохождение через цепочки DNAT iptables. - Для локального DNS-трафика включается правило NOTRACK в таблице raw, полностью разгружая таблицу conntrack. - Связь локального кэша с центральным CoreDNS переводится на надежные постоянные TCP-соединения. При внедрении схемы на голом железе и в K3s критично соблюдать регламент настройки. Ошибки чаще всего возникают при изменении флага cluster-dns в kubelet без обновления dnsPolicy у существующих подов, а также при конфликтах с сетевыми плагинами. Если в системе используется nftables или WireGuard mesh, локальные адреса 169.254.20.10 должны быть явно исключены из маршрутизации туннеля и правил фильтрации. Низкий latency сетевого стека Kubernetes на высоком RPS достигается предсказуемостью маршрута пакета, а не бесконечным увеличением ресурсов CoreDNS. Разборы конфигураций сетевого ядра и архитектурные решения для Bare-Metal кластеров собраны на https://ftops.space.
Утренний статус и чекап инфраструктуры
Утренний health check — это не зеленая галочка в дашборде. Сначала проверяю доступность нод, затем связность WireGuard mesh и только после этого доверяю прикладным метрикам. Нода, которая отвечает на ping, но потеряла маршрут до соседей, уже неисправна.
Минимальный порядок:
- Состояние всех нод кластера и системных сервисов;
- Handshake WireGuard и возраст последнего обмена;
- Маршруты между сегментами, DNS и доступность контрольных endpoint;
- Алерты без подтвержденного recovery;
- Расхождение времени, заполнение дисков и ошибки ядра.
Главное правило — zero silent failures. Мониторинг должен показывать не только "up", но и что именно перестало работать, через какой путь и как давно. Если health check не проверяет реальный рабочий маршрут, он проверяет иллюзию доступности.
Чекап не заменяет наблюдение: после первичной проверки смотрю динамику ошибок и последние изменения конфигурации. Подробные практики отказоустойчивой инфраструктуры — https://ftops.space
#ftops #devops #linux #freebsd #sre #инфраструктура
Утренний health check — это не зеленая галочка в дашборде. Сначала проверяю доступность нод, затем связность WireGuard mesh и только после этого доверяю прикладным метрикам. Нода, которая отвечает на ping, но потеряла маршрут до соседей, уже неисправна.
Минимальный порядок:
- Состояние всех нод кластера и системных сервисов;
- Handshake WireGuard и возраст последнего обмена;
- Маршруты между сегментами, DNS и доступность контрольных endpoint;
- Алерты без подтвержденного recovery;
- Расхождение времени, заполнение дисков и ошибки ядра.
Главное правило — zero silent failures. Мониторинг должен показывать не только "up", но и что именно перестало работать, через какой путь и как давно. Если health check не проверяет реальный рабочий маршрут, он проверяет иллюзию доступности.
Чекап не заменяет наблюдение: после первичной проверки смотрю динамику ошибок и последние изменения конфигурации. Подробные практики отказоустойчивой инфраструктуры — https://ftops.space
#ftops #devops #linux #freebsd #sre #инфраструктура
Сравнивать bare-metal K3s с облаком по цене виртуального ядра бессмысленно. Считайте полный юнит: электроэнергия, аренда стойки, диски, запасные узлы, время инженера и стоимость недоступности. У гиперскейлера к этому добавляются egress, cross-zone и managed-control-plane сборы. Для latency измеряйте не средний ping, а p95/p99 от клиента до pod: физический NIC, CNI, kube-proxy, overlay, балансировщик и соседние зоны. На собственных серверах проще удержать маршрут коротким, но сложнее обеспечить N+1, замену диска и независимое питание. Практическая модель для K3s: - выделить критичные сервисы на отдельные ноды; - держать capacity headroom 30–40%; - считать стоимость часа простоя отдельно от железа; - проверять latency после каждого изменения CNI и topology spread. Подробные разборы bare-metal, K3s и сетевой инженерии: https://ftops.space
🧭 Навигатор по материалам канала
Используйте теги для быстрого поиска нужной фактуры:
#постмортем — Разборы реальных аварий
Анатомия сбоев по единому стандарту: Симптом ➔ Ложная гипотеза ➔ Что показал tcpdump/dmesg ➔ Архитектурное исправление.
— Как Happy Eyeballs (RFC 6555) и чистый Go-резолвер уронили кластерный инференс AI.
— BGP-петля транзитного оператора на 450 мс, которую мониторинг принял за OOM Killer.
— Паника Kubelet ImageGC при пороге 80% на VPS с диском 20 ГБ.
— Залипание WireGuard-пиров после смены NAT и лечение через FDB.
#архитектура — Схемы сетей, оверлеи и отказоустойчивость
Чертежи межсерверного взаимодействия, маршрутизация и обход сетевых аномалий.
— Двуххабовая топология AmneziaWG (Forest ➔ Failover Hub Pumpkin) с обходом блокировок UDP.
— Policy routing, fwmark и чистый европейский egress через туннели awg-goog.
— DNAT-трансляция устаревших подсетей внутри Cloudflare Zero Trust туннелей.
— Разделение control-plane и worker-нод в условиях жесткого DPI.
#экономика — Трезвая математика TCO (Bare-Metal vs Cloud)
Реальные расчеты расходов, скрытые налоги облачных провайдеров и границы применимости.
— 17 нод на K3s за €48/мес против аналогичного сетапа в AWS EKS за $540.
— «Налог на лень»: сколько на самом деле стоят AWS NAT Gateway и межзональный трафик.
— Инженерный налог: почему дешевое железо требует строгих сторожевых таймеров (watchdogs).
#паттерны — Конфиги, проверенные в продакшене
Готовые сниппеты, systemd-юниты, скрипты гигиены и правила фильтрации.
— Юнит аварийного блокирования неотфильтрованного IPv6 для Go-бинарников.
— Blackhole для QUIC (UDP/443) в Xray и Hysteria2 для спасения длинных gRPC-сессий.
— Автоматический watchdog туннелей с pre-armed rollback таймерами.
— Сжатие ротированных логов (gzip -9) и чистка containerd без простоя подов.
──────
Используйте теги для быстрого поиска нужной фактуры:
#постмортем — Разборы реальных аварий
Анатомия сбоев по единому стандарту: Симптом ➔ Ложная гипотеза ➔ Что показал tcpdump/dmesg ➔ Архитектурное исправление.
— Как Happy Eyeballs (RFC 6555) и чистый Go-резолвер уронили кластерный инференс AI.
— BGP-петля транзитного оператора на 450 мс, которую мониторинг принял за OOM Killer.
— Паника Kubelet ImageGC при пороге 80% на VPS с диском 20 ГБ.
— Залипание WireGuard-пиров после смены NAT и лечение через FDB.
#архитектура — Схемы сетей, оверлеи и отказоустойчивость
Чертежи межсерверного взаимодействия, маршрутизация и обход сетевых аномалий.
— Двуххабовая топология AmneziaWG (Forest ➔ Failover Hub Pumpkin) с обходом блокировок UDP.
— Policy routing, fwmark и чистый европейский egress через туннели awg-goog.
— DNAT-трансляция устаревших подсетей внутри Cloudflare Zero Trust туннелей.
— Разделение control-plane и worker-нод в условиях жесткого DPI.
#экономика — Трезвая математика TCO (Bare-Metal vs Cloud)
Реальные расчеты расходов, скрытые налоги облачных провайдеров и границы применимости.
— 17 нод на K3s за €48/мес против аналогичного сетапа в AWS EKS за $540.
— «Налог на лень»: сколько на самом деле стоят AWS NAT Gateway и межзональный трафик.
— Инженерный налог: почему дешевое железо требует строгих сторожевых таймеров (watchdogs).
#паттерны — Конфиги, проверенные в продакшене
Готовые сниппеты, systemd-юниты, скрипты гигиены и правила фильтрации.
— Юнит аварийного блокирования неотфильтрованного IPv6 для Go-бинарников.
— Blackhole для QUIC (UDP/443) в Xray и Hysteria2 для спасения длинных gRPC-сессий.
— Автоматический watchdog туннелей с pre-armed rollback таймерами.
— Сжатие ротированных логов (gzip -9) и чистка containerd без простоя подов.
──────
Ошибочная вера в скорость современных NVMe-накопителей заставляет системных инженеров включать привычный swap-файл на диске для страховки от OOM. На распределенных нодах K3s это приводит к деградации: при всплеске нагрузки kswapd начинает сбрасывать неактивные анонимные страницы на диск. Даже при микронных задержках NVMe очередь блокировок в block layer ядра моментально возрастает. Поток direct reclaim замораживает системные вызовы, контейнерный рантайм пропускает heartbeat, а Kubernetes помечает рабочий узел как NotReady. Отказ от дискового свопа в пользу Zram кардинально меняет механики ядра Linux. Zram создает виртуальное сжатое блочное устройство непосредственно в RAM, используя алгоритмы LZ4 или ZSTD. При сбросе страниц ядро выполняет сжатие памяти в CPU за единицы микросекунд, избегая обращения к дисковой шине и физическим накопителям. В результате пропадает I/O wait, а подсистема управления памятью продолжает работать с детерминированной задержкой. Конфигурация Zram требует пере...
Ошибочная вера в скорость современных NVMe-накопителей заставляет системных инженеров включать привычный swap-файл на диске для страховки от OOM. На распределенных нодах K3s это приводит к деградации: при всплеске нагрузки kswapd начинает сбрасывать неактивные анонимные страницы на диск. Даже при микронных задержках NVMe очередь блокировок в block layer ядра моментально возрастает. Поток direct reclaim замораживает системные вызовы, контейнерный рантайм пропускает heartbeat, а Kubernetes помечает рабочий узел как NotReady. Отказ от дискового свопа в пользу Zram кардинально меняет механики ядра Linux. Zram создает виртуальное сжатое блочное устройство непосредственно в RAM, используя алгоритмы LZ4 или ZSTD. При сбросе страниц ядро выполняет сжатие памяти в CPU за единицы микросекунд, избегая обращения к дисковой шине и физическим накопителям. В результате пропадает I/O wait, а подсистема управления памятью продолжает работать с детерминированной задержкой. Конфигурация Zram требует пересмотра классического тюнинга ядра: - vm.swappiness установите в значение 180 или 200. Это заставляет ядро агрессивно вытеснять анонимную память в сжатый Zram, освобождая несжатую RAM под кеши файловой системы. - vm.watermarkboostfactor сбросьте в 0 для предотвращения ухода ядра в глубокую рекультивацию страниц при кратковременных спайках. - Алгоритм сжатия выбирайте LZ4 для минимальной нагрузки на vCPU или ZSTD для максимальной плотности упакованной памяти. Полный отказ от физических дисков в цепочке своппинга переводит управление дефицитом памяти из области медленного storage I/O в область быстрых процессоров. Тюнинг bare-metal инфраструктуры и сетевого стека ядра разбираем на https://ftops.space.
TCP BBR vs Cubic: почему алгоритм перегрузки решает больше, чем железо
Cubic управляет окном перегрузки по потерям пакетов. В датацентре это терпимо: потери редки, round-trip time предсказуем. На WAN-линках с буферизацией на транзитных узлах (bufferbloat) Cubic раздувает окно до потерь, потом резко режет его вдвое. Итог: пилообразный throughput и латентность, которая прыгает в 3-5 раз от базовой.
BBR строит модель канала иначе. Он оценивает максимальную пропускную способность (BtlBw) и минимальный RTT, и удерживает окно ровно там, где канал заполнен без очереди. Потери для него — шум, а не сигнал. На линках с 1% случайных потерь BBR даёт в 2-25 раз больший throughput, чем Cubic, в зависимости от RTT и глубины буфера на пути.
Включается в одну строку:
sysctl -w net.ipv4.tcpcongestioncontrol=bbr
sysctl -w net.core.defaultqdisc=fq
fq (fair queue) обязателен: без него BBR не может корректно зондировать канал. Дополнительно для высоконагруженного шлюза:
net.core.rmemma...
Cubic управляет окном перегрузки по потерям пакетов. В датацентре это терпимо: потери редки, round-trip time предсказуем. На WAN-линках с буферизацией на транзитных узлах (bufferbloat) Cubic раздувает окно до потерь, потом резко режет его вдвое. Итог: пилообразный throughput и латентность, которая прыгает в 3-5 раз от базовой.
BBR строит модель канала иначе. Он оценивает максимальную пропускную способность (BtlBw) и минимальный RTT, и удерживает окно ровно там, где канал заполнен без очереди. Потери для него — шум, а не сигнал. На линках с 1% случайных потерь BBR даёт в 2-25 раз больший throughput, чем Cubic, в зависимости от RTT и глубины буфера на пути.
Включается в одну строку:
sysctl -w net.ipv4.tcpcongestioncontrol=bbr
sysctl -w net.core.defaultqdisc=fq
fq (fair queue) обязателен: без него BBR не может корректно зондировать канал. Дополнительно для высоконагруженного шлюза:
net.core.rmemma...
TCP BBR vs Cubic: почему алгоритм перегрузки решает больше, чем железо
Cubic управляет окном перегрузки по потерям пакетов. В датацентре это терпимо: потери редки, round-trip time предсказуем. На WAN-линках с буферизацией на транзитных узлах (bufferbloat) Cubic раздувает окно до потерь, потом резко режет его вдвое. Итог: пилообразный throughput и латентность, которая прыгает в 3-5 раз от базовой.
BBR строит модель канала иначе. Он оценивает максимальную пропускную способность (BtlBw) и минимальный RTT, и удерживает окно ровно там, где канал заполнен без очереди. Потери для него — шум, а не сигнал. На линках с 1% случайных потерь BBR даёт в 2-25 раз больший throughput, чем Cubic, в зависимости от RTT и глубины буфера на пути.
Включается в одну строку:
sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
fq (fair queue) обязателен: без него BBR не может корректно зондировать канал. Дополнительно для высоконагруженного шлюза:
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_fastopen = 3
Отдельная история — ethtool и прерывания. ethtool -G ethX rx 4096 увеличивает ring buffer, снижая потери при burst-трафике. Но ethtool -s ethX speed 1000 duplex full autoneg off на живом порту может мгновенно сбросить линк — интерфейс уходит в re-negotiation. На production это означает потерю сессий. Всегда проверяй, что autoneg на обоих концах ведёт себя одинаково, прежде чем трогать скорость вручную.
eBPF и XDP добавляют ещё один уровень: с XDP_DROP на входе NIC ты фильтруешь мусор до аллокации skb. На 10G линке это разница между 14 Mpps wire rate и провалом в kernel stack, который упирается в ~3-4 Mpps на ядро без DPDK.
https://ftops.space
Cubic управляет окном перегрузки по потерям пакетов. В датацентре это терпимо: потери редки, round-trip time предсказуем. На WAN-линках с буферизацией на транзитных узлах (bufferbloat) Cubic раздувает окно до потерь, потом резко режет его вдвое. Итог: пилообразный throughput и латентность, которая прыгает в 3-5 раз от базовой.
BBR строит модель канала иначе. Он оценивает максимальную пропускную способность (BtlBw) и минимальный RTT, и удерживает окно ровно там, где канал заполнен без очереди. Потери для него — шум, а не сигнал. На линках с 1% случайных потерь BBR даёт в 2-25 раз больший throughput, чем Cubic, в зависимости от RTT и глубины буфера на пути.
Включается в одну строку:
sysctl -w net.ipv4.tcp_congestion_control=bbr
sysctl -w net.core.default_qdisc=fq
fq (fair queue) обязателен: без него BBR не может корректно зондировать канал. Дополнительно для высоконагруженного шлюза:
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.ipv4.tcp_fastopen = 3
Отдельная история — ethtool и прерывания. ethtool -G ethX rx 4096 увеличивает ring buffer, снижая потери при burst-трафике. Но ethtool -s ethX speed 1000 duplex full autoneg off на живом порту может мгновенно сбросить линк — интерфейс уходит в re-negotiation. На production это означает потерю сессий. Всегда проверяй, что autoneg на обоих концах ведёт себя одинаково, прежде чем трогать скорость вручную.
eBPF и XDP добавляют ещё один уровень: с XDP_DROP на входе NIC ты фильтруешь мусор до аллокации skb. На 10G линке это разница между 14 Mpps wire rate и провалом в kernel stack, который упирается в ~3-4 Mpps на ядро без DPDK.
https://ftops.space