Bruce Blog Bruce Blog
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航

Bruce Tao

运维界的该溜子
首页
  • CentOS
  • Ubuntu-Debian
  • 系统网络
  • 系统辅助工具
  • MySQL
  • Redis
  • Mongodb
  • Docker基础
  • Container基础
  • Kubernetes

    • Kubernetes基础
    • Kubernetes辅助
  • Container-Network
  • Jenkins
  • Gitlab
  • ArgoCD
  • Ansible
  • Terraform
  • AWS
  • MQ
  • NGINX
  • JumpServer
  • 基础
  • 函数模块
  • 框架
  • 基础

    • Golang环境
    • 语法
    • 数据类型与运算符
    • 分支语句
    • 循环语句
    • 数组
    • 切片
    • Map
    • String
    • 函数
    • 包的管理
    • 指针
    • 结构体
    • Go语言中的OOP
    • 方法和接口
    • 错误处理
  • Go进阶

    • Go进阶
  • Go框架

    • Go框架
  • Golang辅助

    • Golang辅助
  • CSS
  • HTML
  • JavaScript
  • 前端辅助
  • 常用命令
  • 性能监控工具
  • Windows下Docker使用
  • 日常学习
  • 其他导航
  • Docker

  • Container

  • Kubernetes

    • Kubernetes基础

    • Kubernetes辅助

      • terminating的pod、pv、pvc无法删除解决方法
        • kubernetes部署minio对象存储
    • Container-Network

    • Containers
    • Kubernetes
    • Kubernetes辅助
    Bruce
    2022-12-20
    目录

    terminating的pod、pv、pvc无法删除解决方法

    # 一、pod删除

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

    强制删除

    kubectl delete pod pod_name -n namespace_name --force --grace-period=0
    
    1

    如果强制删除还不行,设置finalizers为空

    • 如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过replace的方式进行更新.kubernetes还提供了一种在容器运行时,直接对容器进行修改的方式,就是patch命令.
    kubectl patch pod pod_name -n namespace_name -p '{"metadata":{"finalizers":null}}'
    
    1
    # 从ETCD中删除源数据
    • 不推荐
    # 删除default namespace下的pod名为pod-to-be-deleted-0
        ETCDCTL_API=3 etcdctl del /registry/pods/default/pod-to-be-deleted-0
        
        # 删除需要删除的NAMESPACE
        etcdctl del /registry/namespaces/NAMESPACENAME</pre>
    
    1
    2
    3
    4
    5

    # 二、删除pv/pvc

    # 强制删除
    kubectl delete pv pv_name --force --grace-period=0
    kubectl delete pvc pvc_name -n namespace_name --force --grace-period=0
    
    # finalizers
    kubectl patch pv pv-nfs-gysl -p '{"metadata":{"finalizers":null}}'
    kubectl patch pvc minio-pvc -p '{"metadata":{"finalizers": []}}' --type=merge -n minio
    
    
    1
    2
    3
    4
    5
    6
    7
    8

    # 三、k8s删除流程

    基本的delete命令状态图

    image-20221219231726089

    尽管此操作很简单,但其他因素可能会干扰删除,包括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.
    # 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条件

    # 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的默认优雅删除时间为30s,在对象创建时配置在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只能减小,不能增加.
    # 对象无法删除的原因

    了解以上机制后,对象无法删除无外乎以下两个原因:

    • 对象存在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直接删除
    上次更新: 2024/04/09, 16:48:42
    Kubernetes基础
    kubernetes部署minio对象存储

    ← Kubernetes基础 kubernetes部署minio对象存储→

    最近更新
    01
    AWS NAT-NetWork-Firwalld配置(一)
    04-09
    02
    AWS NAT-NetWork-Firwalld配置(二)
    04-09
    03
    kubernetes部署minio对象存储
    01-18
    更多文章>
    Theme by Vdoing | Copyright © 2019-2024 Bruce Tao Blog Space | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式