本文适用于 K8s 及 K8s为核心的所有集群。


引言

在使用K8s时,有时候会遇到资源无法删除问题,就需要一些强制删除的手段。

: 强制删除不应随意使用,尤其是在生产环境。

:本文只注重暴力美学,不对任何强制删除导致的后果负责。

警告: 以下操作均可能会导致数据丢失或集群崩溃,请勿在生产环境尝试。

警告: 以下操作均可能会导致数据丢失或集群崩溃,请勿在生产环境尝试。

警告: 以下操作均可能会导致数据丢失或集群崩溃,请勿在生产环境尝试。


常用删除手段

K8s常用资源总结

  • namespace
  • pod
  • deployment
  • configmap
  • secret
  • pv/pvc
  • .....

常见删除方法

以删除pod为例,

以下方式也适用于:configmap, secret, service, deployment, replicaset, service account 等资源


# 获取特点命名空间的pod
$ kubectl get -n namespace pod pod-name

# 删除特定命名空间的pod
$ kubectl delete -n namespace pod pod-name

# 删除特定命名空间内所以pod
$ kubectl delete -n namespace pod --all

# 删除所有命名空间的所有pod (虽然不像 'rm -rf /' 那么完美,但也基本能暂时摧毁一个集群)
# 这命令理论上存在,但没验证过,有需要的小伙伴自行尝试
$ kubectl delete pod -A --all

# 暴力删除特定命名空间的pod
# 仅增加 --force 参数即可
$ kubectl delete pod -n namespace pod-name --force

# 立即删除
# 增加 --grace-period=0 参数,代表立即删除资源而不等待任何时间
# 通常 --grace-period=0 与 --force 一起用
$ kubectl delete pod -n namespace pod-name --grace-period=0 --force

以上的命令基本可以完全删除一个POD

: pod 删除后可能会被deployment或者 replicaset 等资源重新创建。

删除PV/PVC

PV和PVC主要目的是为了存应用数据,因此会有保护机制,通常强制删除的pod的pv会被保护起来。

若强制删除PVC,PV也会被保护,常用的delete方法无法删除PV。

# 查看PV
# PV 不分命名空间
$ kubectl get pv

# 删除PV
$ kubectl delete pv pv-name

# 如无法删除,可以增加 --grace-period=0 和 --force 参数尝试
# 但如果正常删除方法没用的话,加这俩参数大概率也会没用
$ kubectl delete pv pv-name --grace-period=0 --force

# 如PV与PVC绑定,直接删除PV必然会失败
# 查看PV是否绑定(可以在第一条命令查看,或者 kubectl get pvc -n namespace 查看)
# 因此 PV与 PVC需要解绑
$ kubectl patch pv pv-name -p '{"spec":{"claimRef":null}}'
# 然后再执行正常的删除命令

# 如果以上的方法还是无法删除,请看下面的方法


删除一些特殊资源
  • 例如: 被保护的pv(如下图),被保护的命名空间等。

Kubernetes 资源强制删除方法总结_统信有雀

先礼后兵法:

# 用自己的配置删除自己
$ kubectl get namespace namespace-name -o json | kubectl delete -f -
# 如果没用就往下看吧
 # 查看某个资源是不是被 finalizers 庇佑
 # 主要以PV为例
 $ kubectl get pv pv-name -ojsonpath='{.metadata.finalizers}'
 
 # 如果以上命令输出不为空,那就执行以下命令手动清除
 $ kubectl patch pv pv-name -p '{"metadata":{"finalizers":[]}}' --type=merge
 
 # 经过以上命令pv可以通过正常途径删除(如果已经执行过删除命令,那么上条命令会直接删除pv)

也遇到过无法patch 修改 finalizers 的情况,因此还有一种通过apiserver删除的方法。

# 本方法通过proxy暴露api地址,然后再进行类似于patch的操作。

# 先建一个测试用命名空间
$ NAMESPACE=test-ns
$ kubectl create ns ${NAMESPACE}

# 获取命名空间的yaml配置,存到临时文件 temp.json, 并清空 finalizers (依赖jq,不想装可以手动改)
$ kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json

# 打开proxy代理,默认端口就行
$ kubectl proxy &

# 提交修改后的yaml
$ curl -k \
	-H "Content-Type: application/json" \
	-X PUT \
  --data-binary @temp.json \
  127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize



一些老赖资源的删除

不针对特定资源,K8s内的绝大部分资源可以被以下方法(etcd大法)暴力删除。

# 以命名空间为例
# 先建一个测试命名空间测试
$ kubectl create ns test-ns

# 能力有限,无法复现无法删除的命名空间(留给有缘人遇见吧)
# 此处直接以本方法强制删除
# 先走进etcd容器
$ kubectl exec -it -n kube-system etcd-xxxxx sh

# 这里需要指定证书
# endpoints 为各个master节点的ip,如果有多个那就多写上,单master可以省略这个参数
# 各个证书的路径在所以集群应该是一致的,除非版本差异,如需了解详情那就看看文档吧
# --insecure-skip-tls-verify=true 这个参数可以跳过证书认证,但我这里没成功
# namespace 可以替换成任意想删除的k8s资源
# test-ns 可以替换成 自己的资源名称
$  ETCDCTL_API=3 etcdctl \
	--endpoints=https://10.100.5.233:2379 \
  --cacert="/etc/kubernetes/pki/etcd/ca.crt" \
  --cert="/etc/kubernetes/pki/etcd/server.crt" \
  --key="/etc/kubernetes/pki/etcd/server.key" \
  del registry/namespace/test-ns

# 以上方法较为危险,绝不可以在生产环境尝试


总结

本文为一些删除资源的经验总结,还有一些有雀资源删除方法没有写出来,但愿不要再遇到删不掉的资源。

本文所有操作都有可能 造成严重的数据丢失或者 集群崩溃。 请勿随意尝试。

如果不是因为无奈谁又喜欢暴力呢。

参考文献

我也忘了以前看谁的博客了,就感谢所有人吧