kubectl delete k8s资源删除不掉,怎么办

DevOpSec
• 阅读 921

来源: DevOpSec公众号 作者: DevOpSec

背景

工作需要经常执行部署升级k8s资源,偶尔会遇到kubectl delete k8s资源卡主,资源状态处于Terminating状态。

这是为什么呢?下面我们来看看执行kubectl delete 操作命令的执行过程,了解其原理后我们具体实践一下。

delete原理

kubectl delete 是 Kubernetes 命令行工具(kubectl)提供的一个命令,用于删除 Kubernetes 集群中的资源对象。当您运行 kubectl delete 命令时,它会与 Kubernetes API 服务器通信,并按照指定的删除选项和参数来执行删除操作。

kubectl delete命令执行原理:

  1. 建立与 Kubernetes API 服务器的连接:kubectl 命令与 Kubernetes API 服务器建立连接,使用配置文件中指定的 API 服务器地址和认证凭据进行身份验证。

  2. 解析命令参数和选项:kubectl 解析命令行中指定的资源类型、名称、命名空间和其他选项。例如,kubectl delete pod my-pod -n my-namespace 命令将解析为删除名为 my-pod 的 Pod 对象,位于 my-namespace 命名空间下。

  3. 发送删除请求:kubectl 构建一个删除请求,其中包含要删除的资源的相关信息。它将这个请求发送到 Kubernetes API 服务器的相应端点(例如 /api/v1/namespaces/my-namespace/pods/my-pod)。

  4. 鉴权和认证:API 服务器接收到删除请求后,会进行鉴权和认证验证,以确保执行该操作的用户具有足够的权限。

  5. 处理删除请求:API 服务器根据请求中的信息,找到要删除的资源对象,并根据指定的删除选项执行相应的操作。删除选项可以是立即删除、先进行软删除(即将对象标记为 "Terminating")并等待终结器处理完成后再删除,或者是执行一些预定义的清理逻辑。

  6. 更新资源状态:如果资源对象成功删除,API 服务器将更新集群中的状态,以反映该资源的删除操作。

  7. 返回结果:API 服务器将删除操作的结果返回给 kubectl 命令行工具。

  8. 输出结果:kubectl 命令行工具将接收到的结果输出到终端,以供用户查看。这可能包括成功删除的资源信息、删除错误的错误消息等。

从上面执行步骤上来看,阻止删除的步骤出现在第五步,为了保护资源不被删除或者优雅的删除,会设计Finalizers终结器,终结器为执行介绍资源不会被删掉。

通过kubectl delete删不掉的资源通过kubectl delete --grace-period=0 --force 进行尝试

--grace-period=0:这个选项指定了删除资源的优雅期(grace period)。优雅期是一个时间段,用于等待资源对象自行终止和清理,以便在删除之前完成相关的关闭和清理操作。通过将 --grace-period 设置为 0,表示不等待优雅期,而是立即删除资源。

--force:这个选项用于强制删除资源对象,即忽略任何可能存在的依赖关系和终止过程。使用 --force 选项会立即删除资源对象,而不会等待资源进行清理或终止操作。

注意: --force 选项只会强制删除资源对象本身,但不会跳过 finalizers 的执行。当执行删除命令时,Kubernetes API Server 会检查资源对象是否具有 finalizers,并在删除之前确保执行相应的操作。因此,即使使用 --force 选项,也无法绕过 finalizers 的逻辑。

后面实践会介绍跳过finalizers的办法和万能删除资源的方法。

下面先介绍一下Owner ReferencesFinalizers终结器,让我们进一步理解他们怎么影响delete操作的。

Owner References 和 Finalizers 介绍

在 Kubernetes 中,Owner References 和 Finalizers 是两个关键的机制,用于管理资源之间的所有权和确保资源的安全删除。

Owner References(所有者引用):Owner References 是一种机制,用于建立资源之间的所有权关系。通过在一个资源对象中设置 Owner References,您可以指定该资源拥有另一个资源,并建立它们之间的父子关系。当一个资源是另一个资源的所有者时,它将负责管理其子资源的生命周期。例如,当一个 Deployment 对象是一个 Pod 对象的所有者时,删除 Deployment 对象将自动删除其关联的 Pod 对象。

管理关联资源的生命周期:通过设置 Owner References,您可以管理资源之间的父子关系,并确保当父资源删除时,与之相关的子资源也会被删除。

Finalizers(终结器):Finalizers 是一种机制,用于控制资源删除的过程。当资源对象被删除时,Kubernetes 控制器将检查该资源的 Finalizers 列表。如果资源具有 Finalizers,则它们表示在删除资源之前必须执行的特定操作或条件。只有当资源的 Finalizers 列表为空时,Kubernetes 才会真正删除该资源。这个机制可以确保在资源删除之前完成一些清理工作,比如释放相关的资源或发送通知。

执行资源删除前的清理工作:通过添加 Finalizers,您可以确保在资源删除之前执行特定的清理工作。例如,您可以释放与资源关联的存储卷或发送通知,以确保资源的安全删除。

介绍完枯燥原理和两种机制,下面我们来看一看愉快的实践部分。

实践

1. 删除pod,删除不了

Owner References的例子:执行kubectl delete pod podname -n my-namespace删除pod后又创建了一个pod,这pod死活删不掉,删除又从新创建

查看一下pod的describe , kubectl -n my-namespace describe pod podname

Name:             podname
Namespace:        release
Priority:         0
Service Account:  default
Node:             192.168.1.18
Start Time:       Wed, 24 May 2023 15:21:13 +0800
Labels:           app.kubernetes.io/name=xxxx
                  rollouts-pod-template-hash=7897c56fd9
Annotations:      cni.projectcalico.org/containerID: 876ba395a9631524d0c465bcfef0de4420e06e190927431c55cda271fe1cb128
                  cni.projectcalico.org/podIP: 10.233.97.25/32
                  cni.projectcalico.org/podIPs: 10.233.97.25/32
Status:           Running
IP:               10.234.97.25
IPs:
  IP:           10.234.97.25
Controlled By:  ReplicaSet/xxxx-7897c56fd9

...

可以看到Controlled By ReplicaSet/xxxx-7897c56fd9,这个pod是被RS xxxx-7897c56fd9创建出来的,他的Owner References是RS

那我们再看看这个RS资源是谁创建的kubectl describe -n my-namespace rs xxxx-7897c56fd9

Name:           xxxx-7897c56fd9
Namespace:      release
Selector:       app.kubernetes.io/name=xxxx,rollouts-pod-template-hash=7897c56fd9
Labels:         app.kubernetes.io/name=xxxx
                rollouts-pod-template-hash=7897c56fd9
Annotations:    rollout.argoproj.io/desired-replicas: 3
                rollout.argoproj.io/revision: 9
Controlled By:  Rollout/xxxx

...

到这里就水落石出了,这个RS xxxx-7897c56fd9 是由Rollout xxxx定义的。argo Rollout 是定义pod的workload,kubectl describe -n my-namespace rollout xxxx 它没有被其他控制器控制。

所以删除rollout资源既可以把pod删除kubectl -n my-namespace delete rollout xxxx

看到这里相信你对rollout控制器又加深了一点印象,在rollout资源文件里定义了replicas: 3 期望的pod副本是3,实际运行中如果副本低于3,控制器就会拉起新的pod使其满足yaml文件里定期的期望数量。

2. 删除svc,删除不了

正常删除 kubectl delete svc -n my-namespace mysvc 回车后,命令卡主

强制删除试试 kubectl delete svc n my-namespace mysvc --grace-period=0 --force Warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.

service "mysvc" force deleted 悲剧的是,命令也是卡主,删除不成功。

执行describe查看一下svc如下

kubectl describe svc -n my-namespace mysvc

apiVersion: v1
kind: Service
metadata:
  annotations:
    eip.openelb.kubesphere.io/v1alpha2: eip-pool
    ....
    lb.kubesphere.io/v1alpha1: openelb
    protocol.openelb.kubesphere.io/v1alpha1: layer2
  creationTimestamp: "2023-05-31T03:23:08Z"
  finalizers:
  - finalizer.lb.kubesphere.io/v1alpha1
  labels:
    app.kubernetes.io/name: mysvc
  name: mysvc
  namespace: release
  resourceVersion: "14704212"
  uid: 1644e3bc-f6bd-4e6e-a911-512ce30321ae

我们发现svc有finalizers,是finalizers阻止了删除svc

finalizers:
  - finalizer.lb.kubesphere.io/v1alpha1

导致finalizers执行不成功的原因是已经删除了finalizers执行依赖的资源,执行删除svc时finalizers的操作不满足条件,阻塞了删除。

解决办法: kubectl edit svc -n my-namespace mysvc 删除下面的两行

finalizers:
  - finalizer.lb.kubesphere.io/v1alpha1

再次执行删除svc,这时候你发现mysvc已经成功删除。

注意:这样可以绕过 finalizers,并强制删除资源对象。在跳过 finalizers 的情况下,可能会导致一些未完成的操作或资源泄漏。确保在执行这样的操作之前,对其可能产生的后果有充分的了解,并谨慎操作。

作者这里出现是因为卸载openelb后,finalizers执行依赖的资源又依赖我卸载的openelb,所有绕过 finalizers,并强制删除资源对象,是没问题的。

3. 删除namespace,删除不了

执行kubectl delete ns my-namespace 卡半天,查看ns状态一直是Terminating。

kubectl get all -n my-namespace 显示没有被删除的资源。

执行kubectl delete namespace my-namespace --grace-period=0 --force也无济于事。

kubectl get ns my-namespace -o yaml 查看也没有Finalizers阻止。

是不是我们还有资源在my-namespace里没有删掉呢?我们通过下面命令查看一下该namespace里所有资源

kubectl api-resources --verbs=list --namespaced -o name|xargs -n1 kubectl get --show-kind --ignore-not-found -n y-namespace

通过上面命令执行我们发现该namespace还有很多资源,逐一删除上面显示资源后,my-namespace 被删除成功。

4. 万能删除法

这个是粗暴的解决办法,轻易不要使用,直接操作etcd,不会考虑k8s资源是否释放。

在etcd节点上执行:

删除ns my-namespace

etcdctl del /registry/namespaces/my-namespace

删除pod test-test-0

etcdctl del /registry/pods/my-namespace/test-test-0

注:etcd集群数最好要备份。

执行 etcdctl del /registry/namespaces/my-namespace 命令删除命名空间(namespace)时,只会删除 etcd 存储中与该命名空间相关的键值对,而不会直接删除 Kubernetes API Server 中的资源对象(如 CRD、CustomResourceDefinition)。

总结,资源删除不掉原因和解决办法:

  1. 因为资源本身被父资源管理,删除父资源即可删除该资源。

  2. 资源有Finalizers 没有执行结束,可以强制跳过Finalizers对资源进行删除。

  3. 删除namespace里包含了其他隐式资源,需要把该namespace里所有资源找出删除,然后再删除namespace。

  4. 直接操作etcd,删除k8s资源。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
3年前
PIC中档单片机汇编指令详解(5)
位操作指令详述BCF数据寄存器指定位清0语法形式:BCFf,b操作数:f为数据寄存器的低7位地址(0x00~0x7F)B为数据位编号(0~7)执行时间:一个指令周期执行过程:使数据寄存器f的的b位清0状态标志影响:无说明:该指令可对任何数据寄存器的任意一个位置清0,常用于标志位的设定和清除,或者把某一管脚置成低电平。指
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
3年前
Eclipse插件开发_学习_00_资源帖
一、官方资料 1.eclipseapi(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fhelp.eclipse.org%2Fmars%2Findex.jsp%3Ftopic%3D%252Forg.eclipse.platform.doc.isv%252Fguide%2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
DevOpSec DevOpSec
1年前
lxcfs容器资源视图隔离 for k8s
k8s版本1.25.6,业务k8s容器化,虚机里进程迁移到容器里后,运维在执行freemtop等命令排查问题时一脸迷惑,显示内存还有很多结果pod的容器被oom或CPU资源显示很多核且空闲很多资源进程却运行很慢,我们看到的资源视图是物理机的而非我们做了限定pod里容器的资源,这给研发和运维排查问题带来一定的干扰。
DevOpSec
DevOpSec
Lv1
懂开发的运维,懂安全的运维。公众号:DevOpSec
文章
57
粉丝
6
获赞
26