Kubernetes で Pod が Terminating のまま残る理由と対策

May 17, 2024, 8:02 AM
Raspberry Pi 5 x Ubuntu 24.04 LTS  のノードで、deploy を restart しても古いPodがTerminatingのまま残ってしまうという現象が起こり困ったので調べました。
(Ubuntu では全て起こるかも?)

状況

root@master-01:~# kubectl get pod -n microai -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
api-microai-jp-589684f88d-6vrvm 1/1 Running 0 6h29m 10.0.8.5 worker-05 <none> <none>
api-microai-jp-589684f88d-mqgf4 1/1 Running 0 6h29m 10.0.8.6 worker-05 <none> <none>
microai-jp-6c575b5766-hd8vq 1/1 Running 0 14m 10.0.9.3 worker-04 <none> <none>
microai-jp-6c575b5766-sm6j2 1/1 Running 0 14m 10.0.8.13 worker-05 <none> <none>
microai-jp-6cff65f59c-hs9db 1/1 Terminating 0 6h29m 10.0.8.4 worker-05 <none> <none>
microai-jp-6cff65f59c-wtfjr 1/1 Terminating 0 6h29m 10.0.8.7 worker-05 <none> <none>

ログ抜粋

root@master-01:~# kubectl describe pods microai-jp-6cff65f59c-hs9db -n microai
:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Killing 6m57s (x13 over 15m) kubelet Stopping container microai-jp
Warning FailedKillPod 4m59s (x14 over 14m) kubelet error killing pod: [failed to "KillContainer" for "microai-jp" with KillContainerError: "rpc error: code = Unknown desc = failed to kill container \"9accdff4e5d8ff3101562c97a20fdd6b42deb0f5a78aa53179786ccd5b54770c\": unknown error after kill: runc did not terminate successfully: exit status 1: unable to signal init: permission denied\n: unknown", failed to "KillPodSandbox" for "fbf73cfe-a304-484c-9437-115378e67987" with KillPodSandboxError: "rpc error: code = Unknown desc = failed to stop container \"9accdff4e5d8ff3101562c97a20fdd6b42deb0f5a78aa53179786ccd5b54770c\": failed to kill container \"9accdff4e5d8ff3101562c97a20fdd6b42deb0f5a78aa53179786ccd5b54770c\": unknown error after kill: runc did not terminate successfully: exit status 1: unable to signal init: permission denied\n: unknown"]

ログを見ると
unknown error after kill: runc did not terminate successfully: exit status 1: unable to signal init: permission denied
となっており、runc に許可がないとのこと

結論

ノード側でAppArmorの設定が必要でした。
かなり緩めの設定にしたので、もっと調べて適切にするべきかもしれません。
※ https://github.com/gardener/gardener-extension-os-suse-chost/issues/42#issuecomment-942131746 が正しい設定かも

ノード側で実施すること

root@worker-05:~# nano /etc/apparmor.d/cri-containerd.apparmor.d

ファイルがない場合は、新規でつくります。

#include <tunables/global>
profile cri-containerd.apparmor.d flags=(attach_disconnected,mediate_deleted) {
# 共通の設定
#include <abstractions/base>

/** rwixk,

# ネットワーク操作
network raw,
network bind,
network inet stream,

# キャパビリティ
capability kill,
capability net_bind_service,
capability net_admin,

# 特定のプロセスへのシグナル送信を許可
signal (receive send) peer=unconfined,
signal (send,receive) peer=runc,
}
上記をペースとします。

root@worker-05:~# apparmor_parser -r /etc/apparmor.d/cri-containerd.apparmor.d
設定を適用

マスター側で削除確認

root@master-01:~# kubectl get pod -n microai -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
api-microai-jp-589684f88d-6vrvm 1/1 Running 0 7h53m 10.0.8.5 worker-05 <none> <none>
api-microai-jp-589684f88d-mqgf4 1/1 Running 0 7h53m 10.0.8.6 worker-05 <none> <none>
microai-jp-6c575b5766-hd8vq 1/1 Running 0 99m 10.0.9.3 worker-04 <none> <none>
microai-jp-6c575b5766-sm6j2 1/1 Running 0 98m 10.0.8.13 worker-05 <none> <none>
正しく削除されています🍺

詳細なログの見方

root@worker-05:~# dmesg | grep apparmor

[28013.195657] audit: type=1400 audit(1715119219.174:10970): apparmor="DENIED" operation="exec" class="file" profile="cri-containerd.apparmor.d" name="/health/..2024_05_07_14_39_08.1278436459/ping_readiness_local_and_master.sh" pid=922238 comm="sh" requested_mask="x" denied_mask="x" fsuid=1004 ouid=0
[28013.577569] audit: type=1400 audit(1715119219.556:10971): apparmor="DENIED" operation="signal" class="signal" profile="cri-containerd.apparmor.d" pid=922239 comm="runc" requested_mask="receive" denied_mask="receive" signal=kill peer="runc"
このように、AppArmor が拒否してきている詳細が見れます。
これを見て1つ1つ対応してけば、必要最低限な設定変更ができると思います。

AppArmor とは

AppArmor(Application Armor)とは、Linux Security Modulesの一種である。各プログラムにセキュリティプロファイルを結びつけ、できることに制限をかける。ネットワークアクセス、Raw socket アクセス、ファイルへの読み書き実行などを制限できる。強制アクセス制御モデルを提供することで、Unixの伝統的な任意アクセス制御モデルを補う。バージョン2.6.36からLinuxのメインラインに含まれており、2009年からカノニカルが開発をサポートしている。


microAI を公開しましたmicroAI を公開しました
Raspberry Pi に 4inch モニターを付けてサーバーを監視するRaspberry Pi に 4inch モニターを付けてサーバーを監視する