Ubuntu 26.04 の Docker で Postgres が起動しない:「docker-default//&unconfined」
Linux カーネルの AppArmor の修正(08c2f7c8d4b1、「apparmor: fix unconfined user namespace restriction forced stack」)が、Ubuntu 26.04 の新しいカーネルと Debian 13 の 6.12.115 に入りました。Ubuntu は kernel.apparmor_restrict_unprivileged_unconfined=1 を最初から有効にしていて、これがあるとカーネルはコンテナのプロファイルを重ねるようになりました。プロセスは docker-default ではなく docker-default//&unconfined として動きます。Docker の既定のプロファイルは、docker-default という名前の相手にしかシグナルを送らせないので、同じコンテナのプロセスどうしでシグナルを送れなくなります(moby #54099、未解決)。
どう見えるか
- 公式の
postgresやmariadbのイメージが起動したまま何も書きません。エントリポイントのgosuが CPU 100% で回り続けます。ワークフローでは、ヘルスチェックのあるサービスコンテナがいつまでも healthy にならず、ジョブはService container postgres failed.・空のログ・Failed to initialize container postgres:17・One or more containers failed to start.で終わります。 gosuを使わない場合:pg_ctl: could not send stop signal (PID: 47): Permission deniedやcould not signal for checkpoint: Permission denied。docker buildのステップの Node.js:Next.js がビルドのワーカーを止めるところでError: kill EACCES(runs-on #116)。- ホストのカーネルのログ:
apparmor="DENIED" operation="signal" ... profile="docker-default" comm="gosu" ... peer="docker-default//&unconfined"。
gosu は Go で書かれていて、Go はスレッドごとにシグナルを送ってすべてのスレッドのユーザーを変えます。そのシグナルが断られると待ち続けるので、コンテナは落ちずに止まったままになります。
報告のあった環境
7.0.0-42-genericの Ubuntu 26.04(moby #54099 の VMware の VM)と、7.0.0-1016-aws(runs-on の11月2日のイメージ。7.0.0-1014-awsの10月21日のイメージは問題なし)。ある k3s のクラスターは、ワーカーが 7.0.0-38 から 7.0.0-42 で再起動したときに止まりました(seichi_infra #6671)。- カーネルを 6.12.113 から 6.12.115 に上げた Debian 13(moby #54099 のコメント)。
- containerd と Kubernetes の既定のプロファイルにも同じ規則があります(containerd #14485)。
つまり GitHub Actions では、これらのカーネルで動くセルフホストのランナーと、他社のランナーのイメージで起きます。GitHub がホストするランナー(イメージ 20261026、ubuntu-24.04 と ubuntu-26.04 のどちらもカーネル 7.0.0-1017-azure)では、11月4日の時点で報告はありません。
ホストを確かめる
uname -r sysctl kernel.apparmor_restrict_unprivileged_unconfined docker run --rm busybox:1.36 sh -c 'cat /proc/self/attr/current; sleep 30 & kill -TERM $! && echo SIGNAL_OK || echo SIGNAL_DENIED'
当てはまるホストでは docker-default//&unconfined (enforce) と SIGNAL_DENIED が出ます。
コンテナ1つの直し方:AppArmor のプロファイルを外す
services:
postgres:
image: postgres:17
options: >-
--security-opt apparmor=unconfined
--health-cmd pg_isready
--health-interval 5s
ワークフローの外なら docker run --security-opt apparmor=unconfined です。ジョブのコンテナなら、container: の下に同じオプションを書きます。ホストはそのままで、そのコンテナだけ AppArmor を外します。シグナルを断っているのは seccomp ではないので、--security-opt seccomp=unconfined では直りません。
ホストの直し方:sysctl
echo 'kernel.apparmor_restrict_unprivileged_unconfined = 0' | sudo tee /etc/sysctl.d/99-container-signals.conf sudo sysctl --system
コンテナは docker-default のままになり、またシグナルを送り合えます。runs-on では、ある利用者がイメージの preinstall のステップで同じ sysctl を設定して、ビルドが通るようになりました(runs-on #116)。Ubuntu がわざと有効にしている制限を切ることになるので、できるならコンテナごとのオプションを使います。
ほかの手
- containerd と Kubernetes:既定のプロファイルのシグナルと ptrace の規則に
peer=<プロファイル>//&*を足すプルリクエストがあります(containerd #14487、未マージ)。そのプロファイルを自分でノードに読み込んでいる運用者もいます。Pod ごとなら、セキュリティコンテキストのappArmorProfile: {type: Unconfined}です。 - 前のカーネルで起動して固定する(Ubuntu 26.04 なら 7.0.0-38)。あとのカーネルにはセキュリティの修正が入っているので、数日だけの手です。
見分け方
- 同じイメージで
bash -c 'echo ok'は動き、gosu postgres idが止まるなら、これです。 bwrapの中のサンドボックスが「No permissions to create a new namespace」で落ちるのは、別の AppArmor のプロファイルbwrap-userns-restrictです(Ubuntu 26.04 の bubblewrap)。- どのカーネルでも同じように落ちるサービスコンテナは、たいていヘルスチェックか環境変数の問題です。「Service container ... failed」のグループのログを見ます。ログが空なら、これを疑います。
ほかの 26.04 の失敗
- Ubuntu 26.04 で WebdriverIO のすべてのワーカーが「Error: write EINVAL」:v9 はワーカーを
xvfb-runから起動し、26.04 のものは IPC のチャネルを引き継ぎません。9.33.1 で直りましたが、npm のlatestのタグはまだそこを指していません。 - Ubuntu 26.04 でビルドしたあとの「version `GLIBC_2.43' not found」:glibc が 2.43 なので、そこでビルドしたバイナリは
GLIBC_2.42やGLIBC_2.43を求めて Ubuntu 24.04・Debian 13 やそれより古い環境で起動しないことがあります。リリースは古いイメージでビルドし、CI で下限を確かめます。 - Ubuntu 26.04 の bubblewrap:
bwrapの中のサンドボックスが、AppArmor のbwrap-userns-restrictの下で落ちます。 - Ubuntu 26.04 の「client version ... is too old」:Docker 29 は API 1.40 より古いクライアントを断るので、古い Testcontainers は「Could not find a valid Docker environment」で落ちます。
- Ubuntu 26.04 の apt:名前が変わった・無くなったパッケージ。
- 「coreutils: unknown program」:基本のコマンドのほとんどが uutils です。
失敗したジョブを IntelliJ IDEA から見るなら
Pipeline Inbox for GitHub Actions Workflows は、Lesstep が作っている JetBrains IDE(2024.1 以降)のプラグインです。すべてのリポジトリの実行を、ジョブ・ステップと一緒に IDE のツールウィンドウに並べ、いまのブランチの実行はステータスバーに出ます。読むのは無料、失敗したジョブの再実行・キャンセル・ワークフローの実行・デプロイのレビューは Pro(月 US$1.50・30日の無料試用つき)です。
GitHub と GitHub Actions は GitHub, Inc. の商標、Ubuntu は Canonical Ltd. の商標、Debian は Software in the Public Interest, Inc. の登録商標、Docker は Docker, Inc. の商標、PostgreSQL は PostgreSQL Community Association の登録商標、IntelliJ IDEA は JetBrains s.r.o. の商標です。このページは GitHub, Inc.・Canonical・Software in the Public Interest・Docker, Inc.・PostgreSQL のプロジェクト・JetBrains のいずれとも提携しておらず、承認も受けていません。
ほかに:「The ubuntu-latest label will migrate to Ubuntu 26」 · Ubuntu 26.04 の bubblewrap · IntelliJ IDEA で使える GitHub Actions のプラグインの比較 · English