18 czerwca 2026 r. projekt containerd opublikował zestaw wydań bezpieczeństwa dla linii 1.7, 2.0, 2.1, 2.2 i 2.3. Sprawa jest istotna nie dlatego, że dotyczy kolejnej biblioteki w łańcuchu zależności, lecz dlatego, że uderza w warstwę uruchamiania kontenerów na Linuksie: Container Runtime Interface, czyli CRI, używany przez Kubernetes do komunikacji z runtime’em kontenerowym. 25 czerwca 2026 r. Canonical opublikował własny komunikat USN-8472-1 dla Ubuntu, obejmujący m.in. Ubuntu 26.04 LTS, 25.10, 24.04 LTS, 22.04 LTS oraz 20.04 LTS w ESM Apps. To wystarczająco mocny sygnał, że problem nie jest akademicki i powinien trafić do bieżącego okna serwisowego klastrów.

W centrum sprawy jest pięć identyfikatorów CVE: CVE-2026-50195, CVE-2026-53488, CVE-2026-53492, CVE-2026-53489 i CVE-2026-47262. Dwa pierwsze są szczególnie nieprzyjemne z punktu widzenia platform inżynieryjnych, gdzie wiele zespołów współdzieli te same pule workerów Kubernetes. Jedna podatność dotyczy zatrucia lokalnego cache’u obrazów przy imporcie checkpointu, druga przepuszczania etykiet z konfiguracji obrazu do kontenera bez odpowiedniej walidacji. W praktyce oznacza to, że zaufanie do obrazu, taga i polityki pobierania może okazać się słabsze, niż zakładał zespół platformowy.
Co dokładnie się wydarzyło 18 czerwca 2026 r.
containerd udostępnił poprawione wersje: 1.7.33, 2.0.10, 2.1.9, 2.2.5 oraz 2.3.2. W zależności od gałęzi nie wszystkie podatności dotyczą każdej wersji, ale praktyczny wniosek jest prosty: jeżeli w środowisku działa containerd z serii 1.7 albo 2.x sprzed powyższych wydań, należy zaplanować aktualizację. Nie wystarczy sprawdzić wersji Dockera na hostach developerskich. W klastrach Kubernetes trzeba sprawdzić runtime widoczny dla kubeleta oraz pakiet zainstalowany na samym węźle.
W komunikacie AWS z 18 czerwca 2026 r. wskazano, że containerd jest wykorzystywany przez Kubernetes za pośrednictwem CRI oraz stanowi element usług takich jak Amazon EKS, Amazon ECS, AWS Fargate, Bottlerocket i Amazon Linux. To ważne również poza AWS, bo ten sam model ryzyka występuje w środowiskach on-premises, w prywatnych chmurach i w samodzielnie utrzymywanych workerach Linuksa. Jeżeli organizacja korzysta z zarządzanego klastra, część odpowiedzialności spada na dostawcę. Jeżeli jednak używa self-managed nodes, własnych obrazów AMI, własnych szablonów cloud-init albo nodów bare metal, aktualizacja runtime’u pozostaje zadaniem administratora.
Pięć CVE w praktyce: nie tylko „kolejny DoS”

Najbardziej alarmująca jest CVE-2026-50195. Dotyczy procesu importu checkpointu w CRI. Według opisu upstream containerd nie walidował prawidłowo referencji obrazów zapisanych w konfiguracji checkpoint image. Atakujący z uprawnieniami do tworzenia podów mógł przygotować checkpoint, który wymuszał pobranie złośliwego obrazu i przypisanie go do lokalnego taga na węźle. Jeżeli inny pod na tym samym węźle korzystał później z takiego taga z polityką IfNotPresent albo Never, mógł uruchomić nie ten obraz, którego oczekiwał operator. W środowiskach multi-tenant to uderza w jeden z podstawowych skrótów myślowych: „tag jest już na node, więc jest bezpiecznie”.
CVE-2026-53488 jest równie istotna, bo nie wymaga włączenia checkpoint/restore. Problem polega na tym, że etykiety z konfiguracji obrazu, czyli m.in. instrukcje LABEL z Dockerfile, mogły być przenoszone do kontenera bez walidacji. Jeżeli dodatkowy komponent lub plugin wykorzystuje te etykiety do operacji po stronie hosta, złośliwy obraz może doprowadzić do wykonania polecenia na hoście. To typowa podatność z kategorii „dane opisowe przestają być tylko opisem”. Administratorzy często filtrują entrypoint, użytkownika, capabilities i mounty, ale dużo rzadziej traktują metadane obrazu jako powierzchnię ataku.
CVE-2026-53492 dotyczy CDI, czyli Container Device Interface. Przy odtwarzaniu kontenera z checkpointu containerd ufał adnotacjom CDI z niezaufanych metadanych checkpoint image. W efekcie użytkownik z możliwością tworzenia podów mógł obejść standardowe ograniczenia alokacji urządzeń w Kubernetes i wstrzyknąć konfigurację dotyczącą urządzeń lub mountów hosta, o ile node miał włączone CDI oraz pasujące specyfikacje hosta. To szczególnie ważne dla klastrów GPU, laboratoriów ML, środowisk edge i hostów, gdzie CDI służy do udostępniania sprzętu kontenerom.
CVE-2026-53489 dotyczy ścieżek symbolicznych przy przywracaniu logu container.log z checkpointu. Skutek opisany przez projekt containerd to możliwość odczytu dowolnego pliku z hosta przez mechanizm kubectl logs. To brzmi mniej spektakularnie niż wykonanie kodu, ale w praktyce może oznaczać wyciek tokenów, konfiguracji runtime’u, sekretów pozostawionych na hoście albo danych diagnostycznych, które później pomagają w dalszym ruchu bocznym.
CVE-2026-47262 to podatność DoS wywoływana przez specjalnie przygotowany obraz. Podczas tworzenia kontenera z takiego obrazu może dojść do nadmiernego zużycia pamięci i ubicia procesu containerd przez OOM. Na pojedynczym serwerze developerskim kończy się to awarią Dockera lub runtime’u. Na workerze Kubernetes może to oznaczać problemy z uruchamianiem i zarządzaniem podami oraz lawinę zdarzeń w kubelecie.
Dlaczego to ważne dla administratorów Linuksa
containerd bywa niewidoczny, dopóki działa poprawnie. Administratorzy widzą Deploymenty, DaemonSety, Helm chart, ingress, CNI i storage class, ale runtime kontenerowy często traktowany jest jako element bazowego obrazu noda. Czerwcowe poprawki przypominają, że to właśnie runtime jest granicą między obrazem kontenera a jądrem Linuksa, systemd, cgroups, mountami, urządzeniami i lokalnym cache’em warstw. Błąd w tej warstwie może ominąć część zabezpieczeń budowanych wyżej.
Najbardziej narażone są środowiska, w których:
- wiele zespołów może tworzyć pody na tych samych workerach,
- dopuszczone są obrazy spoza ściśle kontrolowanego rejestru,
- stosowana jest polityka
imagePullPolicy: IfNotPresentdla tagów innych niż niezmienne digesty, - używane są funkcje checkpoint/restore lub eksperymenty z migracją kontenerów,
- włączono CDI, np. dla GPU, akceleratorów lub specjalistycznych urządzeń,
- worker nodes są utrzymywane samodzielnie, poza pełnym cyklem aktualizacji dostawcy chmury.
Jak szybko sprawdzić, co działa na node’ach
Pierwszy krok to inwentaryzacja. W Kubernetes można zacząć od wersji runtime’u zgłaszanej przez nody. Następnie warto wejść na reprezentatywne hosty i sprawdzić pakiety systemowe. W praktyce dobrze jest zebrać wyniki do CMDB, arkusza awaryjnego albo systemu inventory, bo problem dotyczy nie tylko jednego klastra produkcyjnego, ale też środowisk CI, staging, lab i runnerów budujących obrazy.
kubectl get nodes -o custom-columns='NODE:.metadata.name,RUNTIME:.status.nodeInfo.containerRuntimeVersion,KERNEL:.status.nodeInfo.kernelVersion,OS:.status.nodeInfo.osImage'
# Na wybranym węźle Linuksa:
containerd --version || true
ctr version || true
systemctl status containerd --no-pager
# Debian/Ubuntu:
dpkg -l | grep -E 'containerd|containerd.io'
apt-cache policy containerd containerd.io
# RHEL/Fedora/Alma/Rocky/Amazon Linux:
rpm -qa | grep -E '^containerd|containerd.io'
dnf info containerd containerd.io 2>/dev/null
Jeżeli w wyniku widzisz containerd starszy niż 1.7.33, 2.0.10, 2.1.9, 2.2.5 lub 2.3.2, traktuj węzeł jako wymagający działania. Na Ubuntu komunikat z 25 czerwca 2026 r. wskazuje poprawione pakiety m.in. dla Ubuntu 26.04 LTS: 2.2.2-0ubuntu1.1, dla Ubuntu 25.10: 2.2.1-0ubuntu1~25.10.2, dla Ubuntu 24.04 LTS: 2.2.1-0ubuntu1~24.04.3 oraz dla Ubuntu 22.04 LTS: 2.2.1-0ubuntu1~22.04.2. Warto więc porównywać nie tylko numer upstream, ale też numer paczki dostarczony przez dystrybucję.
Bezpieczna aktualizacja węzłów Kubernetes
Restart containerd na działającym workerze nie jest operacją, którą warto wykonywać „z palca” na całym klastrze. Najbezpieczniejszy schemat to rotacja node po node: cordon, drain, aktualizacja pakietu, restart usługi, kontrola kubeleta i dopiero uncordon. Jeżeli platforma ma autoscaler, node pools albo mechanizm rolling replacement, często lepiej zbudować nowy obraz bazowy i wymienić nody niż łatać każdy host ręcznie.
NODE=worker-01
kubectl cordon "$NODE"
kubectl drain "$NODE" --ignore-daemonsets --delete-emptydir-data --grace-period=60 --timeout=10m
# Ubuntu/Debian na hoście:
sudo apt-get update
sudo apt-get install --only-upgrade containerd containerd.io
sudo systemctl restart containerd
sudo systemctl restart kubelet
sudo systemctl is-active containerd kubelet
kubectl uncordon "$NODE"
kubectl get node "$NODE" -o wide
W środowiskach produkcyjnych należy dodać testy smoke: uruchomienie prostego poda, pobranie obrazu z firmowego registry, sprawdzenie logów przez kubectl logs, test DaemonSetów bezpieczeństwa i weryfikację workloadów używających urządzeń przez CDI. Jeżeli klaster obsługuje GPU, aktualizacja powinna obejmować osobny test pluginu urządzeń, bo CVE-2026-53492 bezpośrednio dotyka relacji między CDI, metadanymi checkpointu i kontrolą zasobów.
Tymczasowe ograniczenia, gdy patch musi poczekać
Nie każde środowisko może zostać zaktualizowane w ciągu kilku godzin. Jeżeli obowiązuje change freeze, wymagana jest certyfikacja obrazu noda albo dostawca jeszcze nie dostarczył paczek, warto wdrożyć ograniczenia kompensacyjne. Nie zastępują one aktualizacji, ale zmniejszają prawdopodobieństwo skutecznego ataku.
- Wymuś używanie zaufanych rejestrów obrazów przez admission controller, np. Kyverno, OPA Gatekeeper albo polityki dostawcy chmury.
- Preferuj obrazy pinowane digestem
sha256:zamiast ruchomych tagów, szczególnie przyIfNotPresent. - Ogranicz prawo tworzenia podów w namespace’ach współdzielonych i przejrzyj role RBAC dla kont serwisowych CI/CD.
- Jeżeli checkpoint/restore nie jest używane, zablokuj procesy i procedury operacyjne, które dopuszczają odtwarzanie kontenerów z niezaufanych checkpointów.
- Jeżeli CDI nie jest wymagane na danym typie noda, usuń lub tymczasowo przenieś specyfikacje z
/etc/cdii/var/run/cdi, zgodnie z zaleceniami upstream dla CVE-2026-53492. - Włącz alerty na restarty containerd, zdarzenia OOM oraz nietypowe błędy kubeleta związane z runtime API.
Co zmienić w standardach platformy
Ten incydent jest dobrym argumentem za odejściem od luźnego używania tagów typu latest, dev czy stable w klastrach współdzielonych. Zatrucie cache’u obrazu ma największą siłę wtedy, gdy platforma ufa lokalnej kopii i nie wymusza jednoznacznej identyfikacji artefaktu. Digesty, podpisy obrazów, polityki admission i skanowanie SBOM nie są dodatkami „enterprise”, tylko praktyczną ochroną przed tym, że metadane i cache runtime’u zostaną potraktowane jako źródło prawdy.
Warto też rozdzielać pule node’ów według poziomu zaufania. Workloady developerskie, build runners, eksperymenty ML z dostępem do GPU i usługi produkcyjne z danymi klientów nie powinny bezrefleksyjnie lądować na tych samych workerach. Podatności w containerd z czerwca 2026 r. pokazują, że granica izolacji w Kubernetes to nie tylko namespace i NetworkPolicy. To również to, kto może zaplanować poda na danym hoście, jaki obraz może pobrać runtime i jakie lokalne artefakty zostaną później użyte przez inne workloady.
Krótkie podsumowanie praktyczne
Do 30 czerwca 2026 r. administratorzy powinni mieć co najmniej pełną listę wersji containerd na workerach, runnerach CI i hostach developerskich. Priorytetem jest aktualizacja do wydań 1.7.33, 2.0.10, 2.1.9, 2.2.5 lub 2.3.2 albo do poprawionych paczek dystrybucyjnych, takich jak te opublikowane przez Ubuntu 25 czerwca 2026 r. Jeżeli aktualizacja wymaga okna serwisowego, należy ograniczyć zaufanie do obrazów, checkpointów i CDI oraz przejrzeć RBAC dla użytkowników mogących tworzyć pody. Najważniejsza lekcja jest prosta: runtime kontenerowy to element bezpieczeństwa Linuksa, a nie tylko demon od uruchamiania obrazów.
