Библиотека девопса | DevOps, SRE, Sysadmin
10.4K subscribers
1.91K photos
76 videos
5 files
3.33K links
Все самое полезное для девопсера в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/25874ec4

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/6798b4e4509aba56522d1787
Download Telegram
🔄 Вышел LXQt 2.4.0

20 апреля команда LXQt выпустила версию 2.4.0. Это исправление ошибок и чистка кода, но есть и заметные улучшения в нескольких компонентах.

Управление питанием

В lxqt-powermanagement появился отдельный таймаут на отключение монитора для режимов AC и батареи. Интерфейс настроек стал чище — лишние опции убрали из выпадающих списков.

Панель и звук

Плагин громкости в lxqt-panel получил горизонтальный layout. Теперь он показывает все доступные аудиовыходы, а громкость нужного можно менять прямо колесом мыши на иконке в панели.

Ещё в версии 2.3.3 поправили фильтр в «Fancy menu» — поиск теперь приоритизирует совпадения с начала строки. Например, fir всегда покажет Firefox первым.

Файловый менеджер

В диалоге сохранения файла PCManFM-Qt имя файла теперь сразу выделено — можно переименовать без лишних кликов. На Wayland починили консистентность отображения элементов рабочего стола при работе с несколькими мониторами.

Сессии

Настройки для X11 и Wayland-сессий разделили в lxqt-config-session. Wayland-раздел виден только если установлен lxqt-wayland-session. Главное меню теперь открывается и на Wayland через lxqt-qdbus openmenu.

Терминал

В QTerminal улучшили поиск: теперь подсвечиваются все совпадения сразу. Починили URL-паттерн, из-за которого ссылки со скобками давали 404. Добавили тему Nord и шорткат для кнопки «keep open» в режиме выпадающего терминала.

Уведомления

Транзитные уведомления, например заголовки треков из плеера, больше не сохраняются когда включён режим «Не беспокоить».

Требования к версии Qt не изменились. Cборка на Debian Trixie и производных по-прежнему работает.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
⭐️ Kubernetes v1.36: User Namespaces теперь стабильны

В Kubernetes v1.36 поддержка User Namespaces для подов получила статус General Availability. Это только Linux-функция, но она закрывает давнюю проблему безопасности контейнерных workload'ов.

Что за проблема

Когда контейнер работает от root-пользователя, при побеге из sandbox он получает root-привилегии на хост-ноде. Это значит, что один скомпрометированный под потенциально открывает доступ ко всему узлу. Десятки уязвимостей класса HIGH и CRITICAL можно было эксплуатировать именно через это.

Что делает User Namespaces

User Namespaces изолируют пользователя внутри контейнера от пользователя на хосте. Процесс, который видит себя как root (UID 0) внутри контейнера, на хосте отображается в непривилегированного пользователя. Так, даже при побеге из контейнера, атакующий не получит прав на ноде.

Второй важный момент: с hostUsers: false возможности вроде CAP_NET_ADMIN становятся namespaced. Это значит, что они дают административные права только над ресурсами внутри контейнера, не затрагивая хост. Раньше такой сценарий требовал запуска полностью привилегированного контейнера.

Как включить

Одно поле в манифесте пода:
apiVersion: v1
kind: Pod
metadata:
name: my-app
spec:
hostUsers: false
containers:
- name: app
image: my-app:latest


Этого достаточно, чтобы под получил собственное изолированное пространство UID/GID.

Что важно учитывать

Требования к среде: Linux-нода с поддержкой user namespaces в ядре, а также совместимый container runtime (containerd >= 1.7, CRI-O >= 1.25).

Диапазон UID/GID для каждого пода должен быть кратен 65536 и начинаться с числа >= 65536. Начиная с v1.33 это можно настроить через KubeletConfiguration:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
userNamespaces:
idsPerPod: 65536


До v1.33 значение было жёстко задано и равно 65536.

Изменения в Pod Security Standards

Для подов с hostUsers: false Kubernetes ослабляет ряд ограничений PSS. Поля, которые обычно блокируются в Baseline и Restricted, становятся допустимыми, потому что root внутри такого пода никогда не отображается в реальный root на хосте.

Работа над этой функцией началась около 10 лет назад. В alpha она вошла в v1.25, в v1.33 была включена по умолчанию, а в v1.36 получила статус стабильной.


📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM
4👍3
📎 docker compose для виртуальных машин

Если вы когда-нибудь поднимали стек из нескольких ВМ на KVM, то знаете, как это выглядит на практике: XML-конфиги libvirt, ручная настройка сетей, отдельные cloud-init-образы для каждой машины. И всё это нужно держать в голове или раскидывать по скриптам.

holos решает именно эту проблему. Он берёт синтаксис, знакомый по docker compose, и применяет его к настоящим виртуальным машинам на KVM/QEMU без libvirt, без XML, без сетевых мостов с root-доступом.

Что он делает

Вы описываете стек в holos.yaml. Каждый сервис — это ВМ со своим образом, ресурсами и cloud-init-конфигом. Поддерживаются зависимости между сервисами, проброс портов, монтирование директорий, реплики и healthcheck.

Пример:
name: my-stack

services:
db:
image: ubuntu:noble
vm:
vcpu: 2
memory_mb: 1024
cloud_init:
packages:
- postgresql
runcmd:
- systemctl enable postgresql
- systemctl start postgresql

web:
image: ubuntu:noble
replicas: 2
depends_on:
- db
ports:
- "8080:80"
cloud_init:
packages:
- nginx
runcmd:
- systemctl restart nginx


Затем одна команда:
holos up


И у вас работают две ВМ с nginx и одна с PostgreSQL, все видят друг друга по имени сервиса.

Как это работает внутри

Каждая ВМ получает два сетевых интерфейса: user-mode для проброса портов с хоста и socket multicast для L2-связи между машинами. Статические IP назначаются автоматически в подсети 10.10.0.0/24, а /etc/hosts прописывается через cloud-init. Ничего настраивать вручную не нужно.

Для хранения данных между перезапусками есть named volumes, они живут как qcow2-файлы и не удаляются при holos down.

volumes:
pgdata:
size: 20G

services:
db:
image: ubuntu:noble
volumes:
- pgdata:/var/lib/postgresql


Внутри гостевой системы том появляется как /dev/disk/by-id/virtio-vol-pgdata. cloud-init сам создаёт файловую систему и прописывает /etc/fstab при первом запуске.

Основные команды:
holos up              # запустить стек
holos down # остановить и удалить
holos ps # список запущенных проектов
holos exec web-0 # SSH в инстанс
holos logs web # логи сервиса
holos install --enable # автозапуск через systemd после ребута


Для SSH holos генерирует пару ключей для каждого проекта и инжектирует публичный ключ через cloud-init. Порт пробрасывается автоматически.

Поддержка GPU passthrough

Если нужно отдать физическую видеокарту виртуальной машине:
services:
ml:
image: ubuntu:noble
vm:
vcpu: 8
memory_mb: 16384
devices:
- pci: "01:00.0"
- pci: "01:00.1"


holos сам включает UEFI (OVMF), выставляет kernel-irqchip=on для совместимости с NVIDIA и создаёт отдельное хранилище EFI-переменных для каждого инстанса. Настройку IOMMU и привязку GPU к vfio-pci нужно сделать на хосте самостоятельно — holos devices --gpu поможет найти PCI-адреса.

Что нужно на хосте

/dev/kvm, qemu-system-x86_64, qemu-img и любой из инструментов для создания cloud-init ISO: cloud-localds, genisoimage, mkisofs или xorriso.

holos это не замена Kubernetes. Он не умеет в кластеры, live migration и service mesh. Его задача — сделать KVM удобным для одного хоста без операционной сложности оркестраторов. Если вам нужен воспроизводимый стек из нескольких ВМ на одной машине, это рабочий вариант.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻 Git 2.54: что нового

Большинство изменений это внутренние рефакторинги, но есть несколько вещей, которые меняют повседневную работу.

Экспериментальная команда git history

Появилась новая команда для переписывания истории. Пока экспериментальная, но уже умеет делать split — разбивать коммиты. Детали пока скудные, но команда явно будет развиваться.

git replay стал умнее

git replay теперь умеет три режима: pick, replay и новый revert. Плюс он научился пропускать коммиты, которые становятся пустыми после replay, и поддерживает replay вплоть до корневого коммита.

Хуки теперь можно настраивать в конфиге

Раньше хук — это скрипт в .git/hooks/. Теперь хуки можно определять прямо в конфигурации Git, в том числе централизованно. И запускать несколько хуков на одно событие. Это открывает нормальную возможность шарить хуки между командой без сторонних инструментов вроде husky.

git add -p стал удобнее

Два улучшения сразу: теперь видно текущий статус показываемого куска, и можно вернуться к файлу, который уже обработали. Для тех, кто активно использует интерактивное добавление, это заметное улучшение.

git status теперь сравнивает с несколькими ветками

Через конфиг status.compareBranches можно указать список веток, с которыми git status будет показывать сравнение. Удобно, если работаете с несколькими долгоживущими ветками одновременно.

git rebase получил --trailer

Новая опция позволяет добавлять трейлеры к коммитам прямо в процессе rebase. Больше не нужно делать это отдельным шагом через git interpret-trailers.

Исправления, которые стоит знать

git blame --ignore-revs с --color-lines давал неверную раскраску для соседних строк в одном коммите — починили. git log --graph --stat неправильно считал ширину цветного графика — тоже исправлено. git diff --stat путался с шириной путей, содержащих не-ASCII символы, — исправлено.

git maintenance меняет стратегию по умолчанию

Теперь по умолчанию используется стратегия geometric вместо прежней. Это влияет на то, как Git управляет packfile-ами в фоне. Если настраивали git maintenance вручную, стоит проверить, не изменилось ли поведение.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
🪟 Windows Server 2025 быстрее работает на ARM64

Джейсон Экерт, автор учебника по Windows Server для Cengage, готовил новое издание и параллельно решил проверить: а что если запустить те же виртуальные машины не на Intel, а на Snapdragon X Elite?

Официального ISO от Microsoft для ARM64 нет, поэтому образ он собрал через UUP dump прямо с серверов обновлений. Конфигурация VM была идентичной на обоих хостах: Active Directory, DNS, DHCP, IIS, File Services, RDS и другие стандартные роли. Итог его удивил: на ARM всё работало заметно отзывчивее.

Почему ARM оказался быстрее

Дело не в архитектуре как таковой, а в характере нагрузки. Серверные роли Windows Server генерируют много мелких, частых операций с CPU и диском. Такие задачи чувствительны к задержкам и context switching. Intel Core i9 работает по принципу boost/throttle: частота резко поднимается и потом снижается под нагрузкой. Snapdragon X Elite держит стабильные часоты без скачков.

В виртуализованной среде это особенно ощутимо. Hyper-V как планировщик получает предсказуемое оборудование и распределяет время CPU между VM без лишней вариативности.

Ещё один момент: ARM64-сборка Windows Server, судя по release notes, обходится без части legacy-слоёв совместимости. Более чистый бинарник, меньше накладных расходов.

Как он это проверял

В Performance Monitor на обоих хостах добавил три счётчика:
\Processor(_Total)\% Processor Time
\System\Processor Queue Length
\Hyper-V Hypervisor Virtual Processor(*)\CPU Wait Time Per Dispatch


Нагрузку создавал через PowerShell внутри VM:
1..8 | ForEach-Object {
while ($true) { Get-Process | Sort-Object CPU -Descending | Select-Object -First 5 | Out-Null }
}


На Snapdragon % Processor Time почти не колебался, Processor Queue Length держался на нуле, CPU Wait Time Per Dispatch был ровным. На Intel все три метрики давали заметные всплески.

Затем он прогнал Measure-Command на реальных операциях прямо внутри VM. Для IIS:
Measure-Command { 1..1000 | foreach { Invoke-WebRequest http://localhost -UseBasicParsing | Out-Null } }


Аналогично для DNS:
Resolve-DnsName "domainX.com" -Server 127.0.0.1 | Out-Null


Для Active Directory:
Get-ADUser -Filter * -ResultSetSize 1 | Out-Null


Для файлового I/O:
$path = "C:\TestFiles"
mkdir $path -ea 0

Measure-Command {
1..2000 | foreach {
$file = "$path\file$_.txt"
Set-Content $file "test"
Get-Content $file | Out-Null
Remove-Item $file
}
}


По всем тестам Snapdragon давал стабильный результат от прогона к прогону. Intel иногда обходил его в пике, но в среднем проигрывал.

Что с этим делать

Делайте своих ИИ-агентов. У нас как раз есть курс, но на него осталось всего 4 места. Успейте до 30 апреля!

👉 Регистрация здесь

➡️ Оригинал статьи

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#локализация
Please open Telegram to view this post
VIEW IN TELEGRAM
🗓️ Уже через пару часов стартует вебинар!

Тема:
Как эффективно управлять контекстным окном LLM в мультиагентных системах и не сливать бюджет на токены


Ждем вас сегодня в 19:00 по московскому времени. Не пропустите начало, будет много практики!

👉 Успей занять место
🔄 nxs-universal-chart 3.0

Вышла новая версия инструмента nxs-universal-chart от компании Nixys. Это универсальный Helm-чарт для деплоя приложений в Kubernetes и OpenShift.

Команды регулярно сталкиваются с необходимостью писать почти одинаковые чарты снова и снова. nxs-universal-chart решает это просто: один чарт на все случаи жизни. Каждый сервис деплоится через один и тот же чарт, а специфика настраивается через values-файлы.

Что появилось в версии 3.0

Главное изменение архитектуры: чарт переписан на базе модульных nuc-* sub-chart-ов. Они распространяются через OCI-реестр и подключаются как зависимости. Это позволяет обновлять отдельные части чарта без пересборки всего.

Добавлена поддержка Istio, KServe, KNative и Vault Secret Operator. Это делает чарт применимым не только для простых веб-сервисов, но и для AI-нагрузок и сервис-мешей.

Как попробовать:
helm repo add nixys https://registry.nixys.io/chartrepo/public
helm install my-release nixys/nxs-universal-chart -f values.yaml


Минимальный values.yaml для деплоя веб-приложения выглядит так:
deployments:
app:
containers:
app:
image: nginx
tag: stable
ports:
- containerPort: 80

services:
app:
ports:
- port: 80
targetPort: 80


Если у вас в кластере больше пяти похожих сервисов, а поддержка отдельных чартов начинает утомлять — стоит посмотреть.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
📎 Запускаем Inferno на 64-битных машинах

Inferno это распределённая операционная система, которую разработали в Bell Labs. Сегодня её развивает Vita Nuova под свободной лицензией.

Проблема была в том, что оригинальный Inferno рассчитан на 32-битные платформы. inferno64 это форк, который переносит систему на amd64 и arm64.

Что это такое

Программы для Inferno пишутся на языке Limbo — конкурентном языке с поддержкой CSP-каналов. Код компилируется в байт-код Dis, который исполняется на виртуальной машине emu. Это значит, что один и тот же код работает везде, где есть эмулятор.

Вся работа с ресурсами в Inferno идёт через файловую иерархию. Сеть, устройства, сервисы — всё открывается через обычные операции open, read, write, close. Протокол для этого тот же, что и в Plan 9 — 9P. Любой ресурс можно экспортировать по сети и подключить к пространству имён другого процесса.

Чем inferno64 отличается от оригинала

Форк фокусируется на трёх вещах: поддержка 64-битных платформ, работа JIT-компилятора для amd64 и байндинги к популярным библиотекам вроде SQLite. JIT для arm64 пока в разработке. Важный момент: dis-файлы из 64-битной версии несовместимы с оригинальным 32-битным dis.

Как собрать на Linux

Устанавливаем зависимости:
apt install libx11-dev libxext-dev linux-libc-dev


Собираем из корня репозитория:
export ROOT=<путь до inferno64>
export objtype=amd64
export PATH=$PATH:$ROOT/Linux/$objtype/bin
./makemk.sh
mk mkdirs
mk install


После сборки в Linux/amd64/bin появятся бинарники mk, iyacc, limbo и emu, а также весь скомпилированный dis-код. Запускаем эмулятор:
emu
; wm/wm&


Пахнет ли здесь ИИ? Возможно, но даже так это отличный форк. Делайте своих ИИ-агентов на нашем курсе и переписывайте старое ПО на новый лад. Осталось всего 4 места. Набор закрывается 30 апреля.

🔗 Успеть на обучение

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
😊 Топ-вакансий для девопсов за неделю

DevOps-инженер — от 200 000 ₽, удалёнка/офис в Санкт-Петербурге

ML SecOps — половина миллиона рублей, удалёнка/гибрид в Москве

DevOps / MLOps — от 350 000 ₽, удалёнка

➡️ Еще больше топовых вакансий — в нашем канале Devops Jobs

🐸Библиотека devops'a

#вакансия_недели
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥 4 привычки кодеров

Вот сколько общаюсь с разработчиками, постоянно слышу убеждение, что есть какой-то правильный способ писать софт. Все ищут секретную архитектуру, вылизывают паттерны, чтобы хоба и тимлид заплакал от счастья от твоего идеального кода.

но, я собрал 4 привычки адептов «чистого кода», (которые обычно все практикуют) 🤡

• Бесконечный рефакторинг рабочего кода.
Кажется, что так ты делаешь продукт лучше. Итог: жестко падаешь в перфекционизм. Переписываешь функцию по три раза, а бизнес ждет релиз. Закрываешь вкладку и в голове абсолютная пустота, время потрачено, а новых фичей ноль.

• Упарывание в сложную архитектуру

Сеньоры на ютубе обещают золотые горы, если внедрить микросервисы куда угодно. Итог: получаешь красивый overengineering-проект для мамы и 0 запущенных продуктов в срок, пока конкуренты клепают MVP на коленке.

• Душные споры на ревью
Неплохо, но как итог: ты пишешь полотна текста и тратишь часы на поиск глупой придирки к стилю, потому что банально фокус сместился с реальной задачи на эго.

• Ручная микро-оптимизация
Классика для тех, кто любит алгоритмы из универа. Итог: убиваешь дни жизни и выжимаешь миллисекунды, хотя бизнесу нужен был просто грязный, но рабочий скрипт еще вчера.

Проблема в том, что ни один из этих путей не дает самого главного - скорости и проверки гипотез. Реальному рынку плевать на твой идеальный код за 3 дня. Бизнес предпочтет код от ИИ-агента за 5 минут, который уже завтра начнет приносить деньги.

Хочешь обкатанный на нас лично и 100х учениках метод, как перестать кодить руками и начать делегировать задачи автономным системам?

👉 Заходи сюда, но у нас осталось всего 4 места, набор идет до завтрашнего дня.

P. S. Если интересно еще что-нибудь почитать от меня, то заходите в «Азбуку Айтишника», там я рассказываю об айти-базе, также у меня там есть бесплатный гайд на 15 глав по ии-агентам
Please open Telegram to view this post
VIEW IN TELEGRAM
👮‍♂️ Теневой бан на hh

HeadHunter внедряет обязательную верификацию через Госуслуги и электронные трудовые книжки. Те, кто не вписывается в официальную картину, рискуют просто исчезнуть из выдачи.

➡️ Почему эта система сработает, кто пострадает первым и что можно сделать сейчас

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a
Please open Telegram to view this post
VIEW IN TELEGRAM
🔄 KDE Plasma 6.7 получит раздельные рабочие столы для каждого монитора

Фича, которую просили с 2005 года, наконец появится в KDE Plasma 6.7.

Что было раньше

При переключении рабочего пространства в мультимониторной конфигурации KDE менял воркспейс сразу на всех экранах. Нельзя было зафиксировать на втором мониторе, например, документ или видео, пока на первом переключаешь задачи.

Причина была в ограничениях X11: стандарт EWMH предполагает один активный рабочий стол для всей системы, поэтому реализовать независимое поведение без поломок в приложениях было сложно.

Теперь можно переключать воркспейсы на основном мониторе, а второй экран будет оставаться на месте. Удобно, если держите на нём референс, дашборд или что-то постоянно открытое.

Что ещё войдёт в релиз

Помимо раздельных рабочих столов в Plasma 6.7 появится возможность снова перетаскивать приложения в виджете Quick Launch. Виджет Audio Volume будет корректно определять новое аудиоустройство при подключении.

Также в Kirigami добавили компонент Badge, который теперь используется в разных приложениях Plasma для единообразного оформления. Страницы приложений в Discover обновили, System Monitor теперь различает GPU по именам, а не номерам. В меню Kicker начали подсвечивать недавно установленные приложения.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
👨‍💻 Kubernetes v1.36: ресурсы подов в приостановленных Job теперь можно менять

В Kubernetes v1.36 фича MutablePodResourcesForSuspendedJobs перешла в бету и включена по умолчанию. Теперь можно менять CPU, память, GPU и другие ресурсы контейнеров прямо в шаблоне пода у приостановленного Job, без пересоздания.

Какую проблему это решает

Batch-задачи и ML-обучение часто запускаются через очереди — Kueue и подобные контроллеры. Очередь может решить, что Job нужно запустить с другим количеством GPU или памяти, исходя из текущей загрузки кластера. Раньше так не получалось: ресурсы в шаблоне пода были неизменяемы после создания Job. Единственный выход — удалить джобу и создать заново, теряя историю, статусы и метаданные.

Теперь это работает нативно: приостановил Job, поменял ресурсы, возобновил.

Как это работает

Фича снимает ограничение на изменение полей ресурсов в pod template, но только пока Job находится в состоянии suspend: true и у него нет активных подов (status.active == 0). Все остальные правила валидации остаются в силе: лимиты не могут быть меньше реквестов, extended resources указываются целыми числами.

Пример Job с изменёнными ресурсами перед запуском:
apiVersion: batch/v1
kind: Job
metadata:
name: training-job-example-abcd123
spec:
suspend: true
template:
spec:
containers:
- name: trainer
image: example-registry.example.com/training:2026-04-23T150405.678
resources:
requests:
cpu: "4"
memory: "16Gi"
example-hardware-vendor.com/gpu: "2"
limits:
cpu: "4"
memory: "16Gi"
example-hardware-vendor.com/gpu: "2"
restartPolicy: Never


Очередь меняет блок resources, затем снимает spec.suspend: false, и новые поды стартуют уже с обновлёнными ресурсами.

Что важно учесть

Если Job уже запускался и был приостановлен, нужно дождаться завершения всех активных подов. API-сервер отклонит изменения, пока status.active > 0.

Если у Job могут быть упавшие поды, стоит выставить podReplacementPolicy: Failed. Это гарантирует, что замещающие поды создадутся только после полного завершения предыдущих и не будет конкуренции за ресурсы.

Dynamic Resource Allocation (DRA) не затронут. resourceClaimTemplates остаются неизменяемыми. Если воркload использует DRA, claim templates нужно пересоздавать отдельно.

Как включить

В v1.36 фича работает без дополнительной конфигурации. На v1.35 нужно явно включить feature gate на kube-apiserver:
--feature-gates=MutablePodResourcesForSuspendedJobs=true


➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
🎮 Пять мини-игр пока llm думает

Пока LLM думает, билд собирается или файл загружается, пользователь смотрит в спиннер. Эту проблему решает react-waiting-game — React-компонент с пятью встроенными аркадными играми для экранов ожидания.

Что это

Библиотека без внешних зависимостей. Все игры нарисованы в стиле 1-bit pixel art на одном canvas. Управление одной кнопкой — клавиатура, мышь и тач работают одинаково. Компонент SSR-safe и сам ставится на паузу, если вкладка скрыта.

Пять игр на выбор:

- jellyfish — медуза плывёт вверх пока держишь кнопку, тонет когда отпускаешь
- runner — прыжки через кактусы и уклонение от птиц
- gravity — инверсия гравитации между шипами на полу и потолке
- invaders — авто-стрельба вправо, переключение между рядами нажатием
- rhythm — ноты летят в зону попадания, короткий тап или удержание в ритм

Все пять поддерживают комбо-множитель, бонус за near-miss, три пауэр-апа и пять достижений каждая.

Как использовать

Установка:
npm install react-waiting-game


Базовый пример:
import { WaitingArcade } from 'react-waiting-game';

function LoadingScreen() {
return <WaitingArcade game="runner" autoStart />;
}


Пример с LLM-запросом, игра появляется пока идёт ответ и исчезает когда он пришёл:
import { useState } from 'react';
import { WaitingArcade } from 'react-waiting-game';

function Chat() {
const [loading, setLoading] = useState(false);

async function ask() {
setLoading(true);
await fetch('/api/chat', { method: 'POST', body: '...' });
setLoading(false);
}

return (
<div>
<button onClick={ask} disabled={loading}>Ask</button>
{loading && (
<WaitingArcade
game="runner"
autoStart
persistHighScore
persistAchievements
/>
)}
</div>
);
}


Пропс paused позволяет поставить игру на паузу снаружи — удобно именно в тот момент, когда ответ пришёл и нужно переключить внимание пользователя.

Настройки

Цвет всего элемента меняется одним пропсом color. Скины переключаются через skin — у каждой игры свои варианты, например ninja или frog для runner, octopus для jellyfish. Лучший счёт и достижения сохраняются в localStorage если передать persistHighScore и persistAchievements.

Пример:
<WaitingArcade
game="jellyfish"
skin="octopus"
color="#4f46e5"
persistHighScore
persistAchievements
onGameOver={(score) => console.log('score:', score)}
/>


📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
2
❗️ Copy Fail: 732 байта до root на любом Linux

Найдена уязвимость в ядре Linux, которая позволяет непривилегированному пользователю получить права root. Никакого брутфорса, никаких гонок, а всего один Python-скрипт.

Что происходит

Уязвимость живёт на пересечении трёх компонентов ядра. AF_ALG — сокет, который открывает доступ к криптоподсистеме для любого пользователя без прав. splice() — системный вызов, который передаёт данные между файловыми дескрипторами без копирования, напрямую через ссылки на страницы кеша страниц. И authencesn — AEAD-шаблон для IPsec с поддержкой 64-битных порядковых номеров.

В 2017 году в algif_aead.c добавили оптимизацию: операции AEAD стали выполняться in-place, то есть req->src и req->dst указывают на один и тот же scatterlist. Когда пользователь через splice() подаёт файл в AF\_ALG сокет, страницы с кэшем страниц этого файла попадают прямо в записываемый scatterlist.

authencesn при расшифровании использует буфер назначения как временное хранилище для перестановки байт ESN. Конкретно — пишет 4 байта по смещению dst[assoclen + cryptlen], то есть за пределами легитимного буфера вывода. Эти байты он никогда не восстанавливает.

В итоге scatterwalk_map_and_copy доходит до страниц кэша страниц целевого файла и пишет туда 4 байта, которые контролирует атакующий. Операция возвращает ошибку (контрольная сумма не сходится — данные подделаны), но запись в кэш страниц уже произошла.

Что контролирует атакующий

Три параметра полностью в руках атакующего:

Первый — какой файл. Любой файл, доступный для чтения текущему пользователю.

Второй — какое смещение. Через параметры splice() и assoclen можно выбрать конкретные 4 байта внутри кэша страниц нужного файла.

Третий — какое значение. Записываемые байты берутся из байт 4–7 AAD, которые атакующий формирует сам через sendmsg().

Как выглядит эксплойт

Цель по умолчанию — /usr/bin/su, исполняемый файл с битом смены идентификатора пользователя, который есть на всех основных дистрибутивах:
a = socket.socket(38, 5, 0)  # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
# ... установить ключ, принять request socket u ...
u.sendmsg([b"A"*4 + payload_chunk], [cmsg_headers], MSG_MORE)
os.splice(target_fd, pipe_wr, offset)
os.splice(pipe_rd, alg_fd, offset)
u.recv(...) # вызывает decrypt → запись в page cache


Скрипт итерируется по 4-байтовым чанкам шелл-кода, записывает их в кэш страниц /usr/bin/su. Затем execve("/usr/bin/su") — ядро читает бинарь из кэша, запускает инжектированный код с UID 0.

Как закрыть

Патч убирает оптимизацию 2017 года и возвращает out-of-place операции для AEAD в algif_aead.c. Теперь req->src указывает на TX SGL, req->dst на RX SGL. Страницы page cache больше не попадают в записываемый scatterlist.

Для немедленного отключения вектора атаки, до обновления ядра, можно заблокировать модуль:
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null


Уязвимость существовала почти десять лет. Каждое из трёх изменений 2011, 2015 и 2017 годов было разумным по отдельности. Проблема возникла на их пересечении, и никто не связал их вместе.

Найдена уязвимость с помощью AI-инструмента Xint Code: исследователь сформулировал поверхность атаки, инструмент за час проанализировал криптоподсистему и выдал CVE-2026-31431 как наиболее критичную находку.

➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#разбор_полётов
Please open Telegram to view this post
VIEW IN TELEGRAM
6
👻 Ghostty уходит с GitHub

Митчелл Хашимото, создатель Vagrant и Terraform, объявил, что его терминал Ghostty переезжает с GitHub. Решение приняли после месяцев обсуждений, хотя крупный сбой 27 апреля 2026 года совпал по времени случайно.

Хашимото зарегистрирован на GitHub с февраля 2008 года, пользователь номер 1299. Восемнадцать лет он открывал платформу каждый день.

Последний месяц он вёл журнал, где отмечал дни, когда сбои GitHub мешали работе. Крестик стоит почти на каждой дате. В день написания поста GitHub Actions не работал около двух часов прямо во время ревью PR.

Проблема не в Git как таком. Инфраструктура вокруг него — issues, pull requests, Actions — стала нестабильной настолько, что мешает нормально делать работу каждый день.


➡️ Источник

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#пульс_индустрии
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2👏1
✍️ Архитектура, которую используют Cassandra, CockroachDB и Kafka

Термин «ничего общего» звучит просто, но за ним стоит фундаментальное решение о том, как узлы системы взаимодействуют друг с другом: у них разные конфиги или разные ноды? Может у них нет общей папки?

Вообще вопрос с собеса звучит так:
Что такое архитектура «ничего общего»


➡️ Как ответить на собесе

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#задача_со_звёздочкой
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🌐 Kubernetes v1.36: многоуровневая защита памяти через Memory QoS

Kubernetes v1.36 обновил механизм Memory QoS на узлах с cgroup v2. Теперь защита памяти назначается по уровням в зависимости от QoS-класса пода, а не по единому правилу для всех.

Какую проблему это решает

До этого у Kubernetes была одна беда: планировщик учитывал запросы памяти при размещении пода, но ядро Linux не знало ничего о том, что эта память «зарезервирована».

Под с requests: 512Mi мог потерять свою память под давлением так же легко, как под без каких-либо запросов вообще. В cgroup v1 это нельзя было исправить — там просто нет нужных инструментов.

cgroup v2 принесла два новых параметра: memory.min (жёсткая защита, ядро не тронет эту память ни при каких условиях) и memory.low (мягкая защита, ядро постарается не трогать, но может при крайней нехватке). Memory QoS использует оба.

Как это работает в v1.36

Политика называется TieredReservation и работает так.

Guaranteed-поды получают memory.min, равный requests. Ядро гарантирует эту память безусловно.
Burstable-поды получают memory.low, равный requests. Ядро постарается сохранить эту память, но при сильном давлении может забрать.
BestEffort-поды не получают никакой защиты.

Дополнительно для Burstable-подов kubelet выставляет memory.high — порог, при превышении которого начинается троттлинг. Считается по формуле:
memory.high = requests + 0.9 * (limits - requests)


Это даёт 10% «буфер» до жёсткого лимита memory.max, чтобы под не уходил в OOM kill резко.

Как включить

Функция находится в alpha и по умолчанию выключена. Включается через feature gate в конфигурации kubelet:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
MemoryQoS: true


Дополнительно можно настроить политику резервирования через параметр memoryReservationPolicy. Если хотите отключить memory.min без отключения всей фичи — ставите Disabled. Если хотите убрать ранний троттлинг — memoryThrottlingFactor: 1.0.

Требования

Нужны Linux с cgroup v2 и ядро версии 5.9 или выше. На более старых ядрах есть баг: когда под упирается в memory.high, процесс зависает вместо того, чтобы двигаться к OOM kill. В v1.36 kubelet логирует предупреждение при старте, если ядро старше 5.9 и фича включена.

Поддержка со стороны CRI-рантайма тоже обязательна. Сейчас это containerd и CRI-O.

Что изменилось по сравнению с предыдущими версиями

В v1.27 была попытка перевести фичу в beta, но её заблокировал именно тот баг с livelock на старых ядрах. В v1.36 добавили метрики на уровне ноды, механизм отката (rollback reconciliation) и возможность тонкой настройки. Логика выставления memory.min тоже поправлена: раньше при requests = 0 memory.min мог выставляться некорректно, теперь сбрасывается в 0 явно.

➡️ Блог k8s

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека devops'a

#арсенал_инженера
Please open Telegram to view this post
VIEW IN TELEGRAM