「Bug」Pod/Namespace 无法删除,卡在 Terminating 状态
修改了 Deployment 后,旧的 Pod 被 Terminated,新的 Pod 被启动。
然后问题就出现了,旧 Pod 一直处于 Exited: Terminated 状态,无法删除。
因为我们使用了 hostPort,端口一直被这个旧 Pod 占用,新 Pod 就无法启动,一直 Pending.
通过 kubectl describe pod <pod-name>
查看:
...
Annotations: cni.projectcalico.org/podIP: 100.103.53.8/32
Status: Terminating (lasts 29h)
Termination Grace Period: 5s
IP:
IPs: <none>
...
Conditions:
Type Status
Initialized True
Ready False
ContainersReady False
PodScheduled True
Volumes:
test-token-d4d2k:
Type: Secret (a volume populated by a Secret)
SecretName: test-token-d4d2k
Optional: false
QoS Class: Burstable
Node-Selectors: kubernetes.io/hostname=xxxxxx
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events: <none>
显示终止状态持续了 29h: Status: Terminating (lasts 29h)
原因分析
目前尚不清楚原因,通过 docker ps -a | grep <pod-name>
查看,发现该容器已经处于 Exited
状态,也就是说容易已经死掉了。
但是容器只是 Exited 了,没有被删除, Pod 也一直卡在 Terminating 状态。
网上询问同道,说这种情况可能是容器相关的其他资源(数据卷之类的东西)无法删除,导致容器一直卡在这个状态。
下次好好排查一下看看。
更新:问题找到了,见文章Kubernetes 常见错误、原因及处理方法 - Pod 无法删除
解决方法
方法一
使用 kubectl 命令:
kubectl delete pods <pod> --grace-period=0 --force
方法二
使用 docker 命令:
- 手动登录到对应的节点,通过 docker ps -a | grep
查找到已经 Exited 的容器 - 然后
docker rm -f <container-id>
手动删除掉它。
现在再进 kubernetes,发现旧 Pod 已经消失了。
Namespace 无法删除
网上搜到的这类问题,貌似都是 monitoring
名字空间的。这是 kube-prometheus 常用的名字空间。
无法删除的原因也是某些资源无法被释放。可通过手动删除 namespace 配置中的析构器(spec.finalizer,在名字空间生命周期结束前会生成的配置项),这样名字空间就会直接被删除了。
# 编辑名字空间的配置
kubectl edit namespace <ns-name>
# 将 spec.finalizers 改成空列表 []
如果上述方法也无法删除名字空间,就只能直接从 etcd 中删除掉它了。方法如下:
# 登录到 etcd 容器中,执行如下命令:
export ETCDCTL_API=3
cd /etc/kubernetes/pki/etcd/
# 列出所有名字空间
etcdctl --cacert ca.crt --cert peer.crt --key peer.key get /registry/namespaces --prefix --keys-only
# (谨慎操作!!!)强制删除名字空间 `monitoring`。这可能导致相关资源无法被 GC!
etcdctl --cacert ca.crt --cert peer.crt --key peer.key del /registry/namespaces/monitoring