每当删除 namespace 或 pod 等一些 Kubernetes 资源时,有时资源状态会卡在 Terminating,很长时间无法删除,甚至有时增加 --force grace-period=0 之后还是无法正常删除。这时就需要 edit 该资源,或者将该资源导出为 json(通过调用原生接口进行删除), 将 finalizers 字段设置为 [],之后 Kubernetes 资源就正常删除了。

root@1nd1009:~/kubesphere# kubectget namespace
NAME                              STATUS        AGE
kubesphere-controls-system        Active        5m43s
kubesphere-logging-system         Terminating   11d
kubesphere-monitoring-federated   Active        5m41s
kubesphere-monitoring-system      Active        5m42s
kubesphere-system                 Active        6m42s

logging这个 namespace 一直处于Terminating状态,一般情况下强删是删不掉的,强删的方法如下:

# kubectl delete ns kubesphere-logging-system --force --grace-period=0

如果删不掉,就参考下面的方法

edit进入logging命名空间查找finalizers 字段删除查到的第一个键和值

kubectl edit ns kubesphere-logging-system

65236bd88fda4236bee2df054e7091b1.png

进去后,查找finalizers 字段删除查到的第一个键和值,保存退出后,处于Terminating状态的ns便没有了。

方法三,

导出当前命名空间json

kubectl get namespace kubesphere-logging-system -o json > temp.json
 

打开导出的json文件,并将spec字段设置为空,如下最终结果

8c24e9b1e92f454581087f9ac9665d33.png

调用 api-server 接口进行删除

打开一个新的终端,或者把下面的命令放到后台执行

kubectl proxy --port=8081


通过调用接口发送请求的方式进行删除,

curl -k -H "Content-Type:application/json" -X PUT --data-binary @temp.json http://127.0.0.1:8081/api/v1/namespaces/kubesphere-logging-system/finalize
 

  • temp.json 是我们导出的文件
  • kubesphere-logging-system 是需要删除的命名空间

最后再次检查命名空间,Terminating状态已被删除 。

Finalizers 终结器

Finalizers 是由字符串组成的数组,当 Finalizers 字段中存在元素时,相关资源不允许被删除,Finalizers 是 Kubernetes 资源删除流程中的一种拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调,在对象删除之前执行相应的逻辑。

Finalizers 可以防止意外删除集群所依赖的、用于正常运作的资源。 Kubernetes 中有些原生的资源对象会被自动加上 Finalizers 标签,例如 PVC 和 PV 分别原生自带 kubernetes.io/pvc-protection 和 kubernetes.io/pv-protection 的 Finalizers 标签,以保证持久化存储不被误删,避免挂载了存储的的工作负载产生问题。假如你试图删除一个仍被 Pod 使用的 PVC,该资源不会被立即删除, 它将进入 Terminating 状态,直到 PVC 不再挂载到 Pod 上时, Kubernetes 才清除这个对象。

Kubernetes 对象的删除过程

当删除一个对象时,其对应的控制器并不会真正执行删除对象的操作,在 Kubernetes 中对象的回收操作是由 GarbageCollectorController (垃圾收集器)负责的,其作用就是当删除一个对象时,会根据指定的删除策略回收该对象及其依赖对象。删除的具体过程如下:

发出删除命令后 Kubernetes 会将该对象标记为待删除,但不会真的删除对象,具体做法是将对象的 metadata.deletionTimestamp 字段设置为当前时间戳,这使得对象处于只读状态(除了修改 finalizers 字段)。

当 metadata.deletionTimestamp 字段非空时,负责监视该对象的各个控制器会执行对应的 Finalizer 动作,每个 Finalizer 动作完成后,就会从 Finalizers 列表中删除对应的 Finalizer

一旦 Finalizers 列表为空时,就意味着所有 Finalizer 都被执行过了,垃圾收集器会最终删除该对象。

Finalizers 可以防止意外删除集群所依赖的、用于正常运作的资源。

Finalizers 是 Kubernetes 资源删除流程中的一种拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调,在对象删除之前执行相应的逻辑。

一旦 Finalizers 列表为空时,就意味着所有 Finalizer 都被执行过了,垃圾回收器会最终删除该对象。

附属对象有一个 metadata.ownerReferences 字段,用于引用其属主对象。

Kubernetes 中有 3 种删除策略,Foreground 和 Background 是级联删除,Orphan 是非级联删除。Foreground 先删除附属对象,再删除属主对象;Background 先删除属主对象,再删除附属对象。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐