本文适用于 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(如下图),被保护的命名空间等。
先礼后兵法:
# 用自己的配置删除自己
$ 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
# 以上方法较为危险,绝不可以在生产环境尝试
总结
本文为一些删除资源的经验总结,还有一些有雀资源删除方法没有写出来,但愿不要再遇到删不掉的资源。
本文所有操作都有可能 造成严重的数据丢失或者 集群崩溃。 请勿随意尝试。
如果不是因为无奈谁又喜欢暴力呢。
参考文献
我也忘了以前看谁的博客了,就感谢所有人吧