本文介紹為Pod注入Sidecar后,Pod處于init crash狀態的問題現象、問題原因和解決方案。

問題現象

為Pod注入Sidecar之后,執行以下命令,查看Pod狀態,發現Pod處于init crash的狀態。

kubectl get pod

預期輸出:

NAME                 READY       STATUS                    RESTARTS        AGE
details-v1-u****     0/2         Init:Error                1               12h
productpage-n****    0/2         Init:CrashLoopBackOff     3               12h

然后執行以下命令,查看istio-init容器日志。

kubectl --kubeconfig=${USER_KUBECONFIG} -c istio-init logs ${pod}

預期輸出:

......
......
-A ISTIO_OUTPUT -d 127.0.**.**/32 -j RETURN
-A ISTIO_OUTPUT -d 192.168.0.1/32 -j RETURN
-A ISTIO_OUTPUT -j ISTIO_REDIRECT
COMMIT
2022-03-23T06:42:21.179567Z    info    Running command: iptables-restore --noflush /tmp/iptables-rules-1648017741179373856.txt4205119933
2022-03-23T06:42:21.185698Z    error    Command error output: xtables other problem: line 2 failed
2022-03-23T06:42:21.185720Z    error    Failed to execute: iptables-restore --noflush /tmp/iptables-rules-1648017741179373856.txt4205119933, exit status 1

可以看到istio-init容器日志包含Failed to execute: iptables-restore信息。

問題原因

檢查是否曾經手動通過docker container rm/docker container prune/docker system prune等命令清理了已經退出的istio-init容器,或者是否存在清理容器的相應的定時任務。

清理已退出的istio-init容器,會導致K8s檢測到Pod關聯的容器不存在,此時K8s會重新啟動被刪除的容器。由于之前已創建了iptables規則,istio-init容器不能再次執行iptables規則,導致新啟動的istio-init容器設置iptables規則失敗而崩潰。

解決方案

您需要重建Pod,重建后,服務的Pod將恢復正常狀態。

如果您下次仍然要使用命令或定時任務腳本清理數據,需要注意以下事項:
  • 如果您需要使用命令清理數據,您需要在批量清理數據命令中過濾istio-init容器,防止istio-init容器被清理。
    docker system prune --filter "label!=io.kubernetes.container.name=istio-init"
  • 如果您需要使用定時任務腳本清理istio-init容器,您需要在定時任務腳本中將docker system prune命令修改為以下命令,過濾istio-init容器,防止istio-init容器被清理。
    docker system prune --filter "label!=io.kubernetes.container.name=istio-init"