草庐IT

K8s无法删除状态为terminating的pod解决方法

风清一片 2024-01-26 原文
  1. pod删除

每当删除namespace或pod 等一些Kubernetes资源时,有时资源状态会卡在terminating,很长时间无法删除,甚至有时增加–force flag(强制删除)之后还是无法正常删除。这时就需要edit该资源,将字段finalizers设置为null,之后Kubernetes资源就正常删除了。

当删除pod时有时会卡住,pod状态变为terminating,无法删除pod

(1)强制删除

kubectl delete pod xxx -n xxx --force --grace-period=0
(2)如果强制删除还不行,设置finalizers为空

(如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过replace的方式进行更新。kubernetes还提供了一种在容器运行时,直接对容器进行修改的方式,就是patch命令。)

kubectl patch pod xxx -n xxx -p ‘{“metadata”:{“finalizers”:null}}’
这样pod就可以删除了。

推荐内容

  1. k8s删除流程
    基本的delete命令状态图:

尽管此操作很简单,但其他因素可能会干扰删除,包括finalizers和owner references。

K8s 中对象删除基本流程如下:

(1)客户端提交删除请求到 API Server(可选传递 GracePeriodSeconds 参数)
(2)API Server 做 Graceful Deletion 检查(若对象实现了
RESTGracefulDeleteStrategy 接口,会调用对应的实现并返回是否需要进行 Graceful 删除)
(3)API Server 检查 Finalizers 并结合是否需要进行 graceful 删除,来决定是否立即删除对象(若对象需要进行 graceful 删除,更新
metadata.DeletionGracePeriodSecond 和metadata.DeletionTimestamp 字段,不从存储中删除对象;若对象不需要进行 Graceful 删除时
:metadata.Finalizers 为空,直接删除。metadata.Finalizers 不为空,不删除,只更新
metadata.DeletionTimestamp。

2.1 finalizers介绍
Finalizers 字段属于 Kubernetes GC 垃圾收集器,是一种删除拦截机制,能够让控制器实现异步的删除前(Pre-delete)回调。其存在于任何一个资源对象的 Meta中,在 k8s 源码中声明为 []string,该 Slice 的内容为需要执行的拦截器名称。

常见用途:

(1)控制器在对象刚创建时,在 metadata.finalizers 写入一个自定义字符串
(2)APIServer 在 metadata.finalizers 数组不为空时,不会删除对象。此逻辑是硬性,对所有对象生效。
(3)当有客户端删除对象时,控制器可以发现对象出于删除状态,然后执行相应的 pre-delete 逻辑。执行完成后,将之前写入的自定义字符串移除。
(4)当所有控制器都将各自写入到 metadata.finalizers 的字符串移除后。API Server 就自动将对象删除。
注:若对象同时实现了 graceful 删除策略,删除请求需要满足 GracefulPeriodSeconds = 0 条件

2.2 Graceful Deletion

APIServer 在处理 Pod 删除请求时,会根据 pod 的
pod.Spec.TerminationGracePeriodSeconds 和 deleteOptions.GracefulPeriodSeconds 综合判断,是否进行 Graceful 删除。若是,并判断最终的 GracefulPeriodSeconds 该设置为多少。

(1)当删除请求选项中有设置 GracefulPeriodSeconds,以选项中为准。若没有,使用
pod.Spec.TerminationGracePeriodSeconds 。若 pod.Spec.TerminationGracePeriodSeconds 也没有设置,使用默认值 0 。

(2)当 Pod 没有调度,或者已经结束(无论成功还是失败)。GracePeriodSeconds 都重置为 0.

GracePeriodSeconds 为 0 表示不进行优雅删除。非 0 表示进行优雅删除。Pod 的默认优雅删除时间为 30 s ,在对象创建时配置在
pod.Spec.TerminationGracePeriodSeconds 字段。

优雅删除的目的是给予 Kubelet 一定时间对 Pod 实行优雅退出。在用户对 Pod 执行 Delete 操作时,Pod 对象不会立即从 API Server 删除,而只是进入 Termination 阶段。Kubelet 会对运行中的 Pod 的容器发送 TERM 信号,通知其退出。并执行用户配置的 preStop hooks 逻辑。当优雅时间过了之后,再开始使用 KILL 信号尝试强制杀容器。

当 kubelet 将 Pod 清理干净后,就会使用 GracefulPeriodSeconds==0 的参数执行删除操作。

因为 Pod 实现优雅删除目的是为了给予 Kubelet 时间做资源清理操作,所以这也是为什么在设置 GracePeriodSeconds 阶段,若 Pod 没有被调度或者已经退出,也就可以直接允许立即删除 (GracePeriodSeconds = 0)。

注:

理解该流程可以结合 Kubernetes 官网的 Pod Termination 说明:https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods
对象第一次执行优雅删除操作时,会将当时 GracefulPeriodSeconds 配置在 metadata.DeletionGracefulPeriodSeconds 字段。
Deletion 操作在 API Server 是不可回退的操作。metadata.DeletionTimestamp 设置后不可更改,metadata.DeletionGracefulPeriodSeconds 只能减小,不能增加。
2.3对象无法删除的原因
在了解以上机制后,对象无法删除无外乎以下两个原因:

对象存在 finalizers,关联的控制器故障未能执行或执行 finalizer 函数卡住比如namespace控制器无法删除完空间内所有的对象,特别是在使用 aggregated apiserver 时,第三方 apiserver 服务故障导致无法删除其对象。此时,需要会恢复第三方 apiserver 服务或移除该 apiserver 的聚合,具体选择哪种方案需根据实际情况而定。集群内安装的控制器给一些对象增加了自定义 finalizers ,未删除完 fianlizers 就下线了该控制器,导致这些 fianlizers 没有控制器来移除他们。此时,需要恢复该控制器会手动移除 finalizers,具体选择哪种方案根据实际情况而定。
对象需要优雅删除,但执行者不能完成删除。比如 Pod 因为 kubelet 无法下线节点上 node 容器、存储卷而无法删除。比较常见有以下原因:kubelet 无法通过 container runtime 杀死进程。比如进程进入 D (Uninterruptible) 状态,container runtime 或操作内核遇到 bug 等。对于进程进入 D 状态,若能恢复照成 D 的故障,比如恢复关联的外设访问等,能解决问题。若不能,或者是因为后者内核 bug,一般并不能走正常流程让 kubelet 杀死进程。一般需要重启操作系统才能解决。kubelet 进程停止或者 node 失去联系。 该情况下,并没有 kubelet 运行或者运行中的 kubelet 与 apiserver 已经断开,无法收到 pod 需要删除下线的消息。所以,没有执行者来进行优雅删除。该情况下,需要恢复节点以及 kubelet 的运行即可。
两种机制都有强制跳过的方案:

删除 finalizers ,让关联的逻辑不需要执行
kubelet delete --force --grace-period 0 直接删除
但应仅当关联清理工作已经不重要或已手动执行时,才可选择。不然容易照成数据、状态不一致等。

有关K8s无法删除状态为terminating的pod解决方法的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  6. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  7. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  8. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  9. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  10. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

    我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

随机推荐