Osegi
Софт·2 мин чтения

Ubuntu 26.04: обновление ядра с AppArmor ломает контейнеры

Патч безопасности в ядре Ubuntu 26.04 изменил стекирование профилей AppArmor. В контейнерах блокируются сигналы, зависают gosu, PostgreSQL и поды Percona.

Server rack with terminal output showing AppArmor denied signal errors from a container running on an Ubuntu host.
Фото: Хабр

Патч безопасности в ядре Ubuntu 26.04 способен неожиданно положить продакшен с контейнерами. Из-за изменения в AppArmor процессы внутри контейнера получают Permission denied при отправке сигналов, даже собственным процессам с тем же uid. Затронуты Kubernetes, k3s, RKE2 и хосты Docker.

Как проявляется сбой

Проблема возникает на Ubuntu 26.04 или на ядрах с бэкпортом из 7.0.0-41+, включая облачные сборки linux-aws и linux-azure. Нужны ещё два условия: включённый kernel.apparmor_restrict_unprivileged_unconfined=1 (в 26.04 это значение по умолчанию) и containerd либо Docker со стандартным профилем AppArmor.

В журнале ядра появляются записи вида apparmor="DENIED" operation="signal" с peer="cri-containerd.apparmor.d//&unconfined". PostgreSQL выдаёт could not signal for checkpoint: Permission denied, а gosu и любой Go-бинарь с вызовом setuid крутится на 100% CPU: сервис не стартует, логов нет. Автор разбирает случай, когда после изменения ресурсов нод в кластере Kubernetes не поднялись поды PXC (Percona Operator for MySQL), а затем приложение так и не стало Ready.

Причина

С февраля 2025 года в Ubuntu включён параметр, не позволяющий unconfined-процессу без CAP_MAC_OVERRIDE просто сменить профиль: новый профиль накладывается стеком поверх unconfined. Коммит 08c2f7c8d4b1 (CVE-2026-90231) закрыл обход этого ограничения и стал применять принудительный стек и при exec.

runc сначала сбрасывает capabilities, затем делает exec процесса контейнера. В итоге каждый контейнер со стандартным профилем работает под меткой cri-containerd.apparmor.d//&unconfined (в Docker — docker-default//&unconfined). В шаблоне профиля containerd сигналы разрешены только для точного имени cri-containerd.apparmor.d, составная метка под правило не попадает, и ядро отказывает любому сигналу между процессами и потоками одного контейнера.

Обходные пути и хронология

Быстрое решение — отключить AppArmor в CR PerconaXtraDBCluster либо послать сигнал с ноды от root, найдя host-PID через crictl inspect. По данным автора, последнее незатронутое ядро — linux 7.0.0-38.38. Версия 7.0.0-42.42 попала в resolute-security, и её ставит unattended-upgrades; в 7.0.0-43.43 симптомы сохраняются, 7.0.0-44.44 находится в proposed. Открыты LP #2172422 и containerd#14485, исправление профиля предложено в PR #14487. В данных есть небольшое расхождение: часть отчётов называет первой плохой версией 7.0.0-41, часть проверяла только -42.

Приложения, на которые стоит взглянуть

SUMO: числовая головоломка

Выбирайте нужные клетки, складывайте, достигайте цели. Легко понять, сложно освоить. Бесплатно, для любого возраста.

Теги:ubuntuapparmorkubernetescontainerdlinux kerneldocker

Ещё за этот день

Показать все →

Ещё в рубрике: Софт

Показать все →