### 1、前言 在Rancher环境中,Longhorn作为一款优秀的分布式存储解决方案,为容器化应用提供了持久化存储的支持。然而,随着业务的发展或技术的更新,我们可能需要对Longhorn进行卸载。 ### 2、缘起 #### 2.1 出现的现象 按照正常流程是可以卸载掉的,如果有人为的操作就会存在问题,在没卸载完成就开始删除命名空间,就会存在问题。或者有手动修改的过程。 按照常规方法 kubectl delete -f,然后就开始无限的死锁。 kubectl delete删除了大部分的资源,但是有一些东西卡着,例如:longhorn-manager处于Terminating状态、crd/engineimages.longhorn.io里面有一个东西删不掉、nodes.longhorn.io里面有一个node没有ready、nodes状态不正确导致命名空间longhorn-system无法删除。 然后开始尝试恢复,kubectl apply -f再执行了一次,提示命名空间已经处于Terminating状态,无法往里面创建pod这些资源。 期间我通过kubectl delete po instance-manager-r-8239ccb0 --force --grace-period=0强制删除了longhorn-manager和crd/engineimages.longhorn.io,命名空间依赖nodes.longhorn.io里面的状态变成ready,强制删除nodes.longhorn.io又会提示webhook内部错误(改动nodes.longhorn.io这个对象似乎会给longhorn-conversion-webhook发送请求),但是longhorn-conversion-webhook已经没了,所以,算是死锁了吧。 最终我找到了上面的命令,把Terminating状态的命名空间强制删掉了,然后再kubectl apply -f去创建一个新的命名空间,这样子就能往这个命名空间里面启动一个longhorn-conversion-webhook之后,打破死锁的条件之一。 #### 2.2 存在的问题 在Kubernetes的轻量级发行版K3s中安装Longhorn服务时,我们可能会遇到一些棘手的问题。其中一个常见的问题就是在尝试删除一个已安装的Longhorn服务时,发现相关的namespaces无法被正确删除。即使执行了删除命令,Pod内容虽然被删除,但命名空间的删除状态却一直处于”terminating”状态。这种情况可能会影响到我们的系统稳定性,甚至阻碍我们对服务的重新部署。 #### 2.3 原因分析 1. **Finalizer问题**:在Kubernetes中,Finalizer是一种保护机制,它可以阻止对象被删除,直到Finalizer被移除。如果一个资源对象被标记为”finalizers”,那么只有当这个finalizer被正确移除后,该资源对象才能被成功删除。在Longhorn服务的namespaces中,可能存在一些finalizer没有被正确移除,从而导致namespaces无法被删除。 2. **资源泄漏**:在某些情况下,Longhorn服务可能创建了一些没有被正确清理的资源,如Volume、StatefulSet等。这些资源在被删除之前,会阻止相关的namespaces被删除。 #### 2.4 解决方案和思路 1. **检查并移除Finalizer**:首先,我们需要检查Longhorn服务的namespaces中是否存在Finalizer。可以通过执行kubectl get namespaces -o yaml命令来查看。如果发现有Finalizer存在,可以尝试手动编辑namespaces,将其移除,然后再次尝试删除。 2. **清理遗留资源**:如果Finalizer不存在或者移除后问题仍未解决,那么可能是由于Longhorn服务创建的资源没有被正确清理。在这种情况下,我们需要找到并手动删除这些资源。可以使用kubectl get all --all-namespaces命令来查看所有的资源,然后逐一检查是否有Longhorn服务创建的资源存在。如果有,使用相应的删除命令将其删除。 3. **使用kubectl delete命令的—force选项**:在某些情况下,即使资源存在Finalizer或遗漏,我们也可以尝试使用kubectl delete命令的--force选项来强制删除namespaces。但请注意,这种方法可能会导致数据丢失,因此在使用前一定要谨慎考虑。 #### 2.5 注意事项 - 在执行任何删除操作前,一定要确保备份了重要的数据,以防止数据丢失。 - 在删除namespaces前,最好先了解其内部的结构和依赖关系,以免误删其他重要的资源。 - 如果问题仍然存在,建议查看K3s和Longhorn的官方文档或寻求社区的帮助,以获取更多的信息和支持。 #### 2.5 官方卸载方式 [https://longhorn.io/docs/1.6.1/deploy/uninstall/](https://longhorn.io/docs/1.6.1/deploy/uninstall/) ### 3、解决方案 #### 3.1 释放terminating状态命名空间 命名空间根据情况设定 **方法一: ** 编写脚本请求形式将对应命名空间中的 finalizers 去掉,使其能够被释放掉。 ```bash ( NAMESPACE=longhorn-system kubectl proxy & kubectl get namespace $NAMESPACE -o json |jq '.spec = {"finalizers":[]}' >temp.json curl -k -H "Content-Type: application/json" -X PUT --data-binary @temp.json 127.0.0.1:8001/api/v1/namespaces/$NAMESPACE/finalize ) ``` > 注意:这里依赖一个jq,需要自行安装,homebrew就直接brew install jq就行了,Ubuntu可以sudo apt-get install jq -y **方法二:** 命令行操作将命名空间的 finalizers 去掉,使其能够被释放掉。 ```bash kubectl get ns longhorn-system --output=json | jq '.items[] | select(.metadata.finalizers!=null) | .metadata.name' | xargs -I {} kubectl patch ns {} -n jdcloud-sec --type='json' -p='[{"op": "remove", "path": "/metadata/finalizers"}]' ``` #### 3.2 释放longhorn CRD 资源 ![image.png](https://cdn.nlark.com/yuque/0/2024/png/25652709/1712854145646-c56313f4-3cf7-4072-a173-5bc27ce8ee71.png#averageHue=%23151515&clientId=u246a44ad-b3e0-4&from=paste&height=488&id=ued135d4b&originHeight=976&originWidth=1530&originalType=binary&ratio=2&rotation=0&showTitle=false&size=280403&status=done&style=none&taskId=u506a394d-e113-4951-8483-8d2fb1ee70d&title=&width=765) ```bash kubectl get crd | grep long | awk '{print $1}' | xargs -I{} kubectl patch crd {} --type merge -p '{"metadata":{"finalizers":null}}' ``` #### 3.3 重建namespace ```bash kubectl create ns longhorn-system ``` #### 3.4 执行卸载命令 **helm 方式 卸载:** ```bash helm uninstall longhorn -n longhorn-system ``` **kubectl 命令行形式:** ```bash # 创建一个删除器 kubectl create -f https://raw.githubusercontent.com/longhorn/longhorn/master/uninstall/uninstall.yaml # 上一步提示需要设置这个确认标记为true,用这个命令修改一下 kubectl -n longhorn-system edit settings.longhorn.io deleting-confirmation-flag # 删除器会按照正确的流程删除组件,然后我们就删除一开始apply的东西,主要是删除不会导致死锁的组件以及crd定义 kubectl delete -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml # 等待删除器完成之后,移除删除器本身 kubectl delete -f https://raw.githubusercontent.com/longhorn/longhorn/master/uninstall/uninstall.yaml ``` #### 3.5 删除命名空间下所有POD ```bash kubectl delete all --all -n longhorn-system --grace-period=0 --force --wait=false || true ``` #### 3.6 删除命名空间 ```bash kubectl delete ns longhorn-system ``` ### 4、参考文件 - [k3s longhron](https://docs.rancher.cn/docs/k3s/storage/_index/#%E8%AE%BE%E7%BD%AE-longhorn) - [uninstall longhorn](https://longhorn.io/docs/1.6.1/deploy/uninstall/)