跑路但不拆楼:如何安全卸载 ArgoCD 且保留所有业务应用
🏗️ 核心概念:非级联删除 (Non-Cascading Deletion)
Section titled “🏗️ 核心概念:非级联删除 (Non-Cascading Deletion)”在赛博堡垒中,有时我们只想重装或卸载 ArgoCD 本身(比如迁移 GitOps 工具,或者清理测试环境),但绝不希望它把正在运行的业务应用(比如我们的存储大坝、可视化面板)一起删掉。
ArgoCD 在部署应用时,默认会给资源打上一个叫 resources-finalizer.argocd.argoproj.io 的终结器(相当于一根引爆线)。如果你直接执行 kubectl delete namespace argocd,它会顺着这根线把底层真实的 Pod 和 Service 全部“爆破”掉,甚至会导致整个命名空间卡死在 Terminating 状态。
要做到**“监工跑路,大楼照常营业”**,我们必须在拆除指挥中心前,偷偷剪断所有的引爆线。
✂️ 无损拆除流程 (Safe Teardown Steps)
Section titled “✂️ 无损拆除流程 (Safe Teardown Steps)”为了绝对的安全,我们将采用**“暗杀级”**施工法:先切断监工的大脑,再从容拆除。
步骤 1:瘫痪指挥中心大脑 (停止控制器)
Section titled “步骤 1:瘫痪指挥中心大脑 (停止控制器)”这是应对复杂 GitOps 架构最关键的一步。我们必须先把 ArgoCD 的应用控制器副本数缩容为 0,让其失去对集群状态的监听和自愈能力。
kubectl scale statefulset argocd-application-controller -n argocd --replicas=0(💡 监理提示:执行后,ArgoCD 变成了“瞎子和聋子”,绝对不会再产生任何反扑动作。)
步骤 2:从容剪断所有应用的“引爆线”
Section titled “步骤 2:从容剪断所有应用的“引爆线””大脑死机后,我们就可以毫无顾忌地强制抹除所有 Application 对象的 Finalizer。
打开终端,执行这行“批量剪线”脚本:
kubectl get apps -n argocd -o name | xargs -I {} kubectl patch {} -n argocd -p '{"metadata": {"finalizers": null}}' --type merge(💡 监理提示:执行完后,这些应用就已经彻底脱离 ArgoCD 的“同归于尽”机制了。)
步骤 3:销毁 GitOps 档案 (删除 Application 对象)
Section titled “步骤 3:销毁 GitOps 档案 (删除 Application 对象)”既然引爆线已经没了,且没有控制器来阻挠,我们现在就可以安全地删掉 ArgoCD 里的那些“项目档案”了。
kubectl delete apps --all -n argocd这条命令会瞬间执行完毕,而你集群里的真实业务应用完全不会受到任何影响,它们已经变成了 K8s 的原生脱管应用。
步骤 4:拆除主体建筑 (反向执行安装脚本)
Section titled “步骤 4:拆除主体建筑 (反向执行安装脚本)”清空了档案后,我们就可以按图索骥,用当初浇筑时的官方图纸进行反向拆除,把 ArgoCD 的 Redis 缓存、API 服务等组件清理掉:
kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml步骤 5:深度清理残骸 (删除 CRD 与命名空间)
Section titled “步骤 5:深度清理残骸 (删除 CRD 与命名空间)”最后一步,把划拨给 ArgoCD 的专属园区,以及它留在 K8s 底层的那些自定义资源定义(CRD)连根拔起。
1. 彻底粉碎专属 CRD: (⚠️ 警告:这会删除全集群所有命名空间下的 ArgoCD 相关资源,确保你没有其他的 ArgoCD 实例在使用它们!)
kubectl delete crd applications.argoproj.io appprojects.argoproj.io applicationsets.argoproj.io2. 抹平命名空间:
kubectl delete namespace argocd🧰 进阶排障:应对“强拆”中的钉子户 (Troubleshooting)
Section titled “🧰 进阶排障:应对“强拆”中的钉子户 (Troubleshooting)”在实际的集群拆迁中,K8s 的垃圾回收机制偶尔会发生死锁。如果你在执行上述步骤时卡住了,请使用以下“重火力”工程手段。
1. 漏网之鱼:AppProject 的终结器卡死
Section titled “1. 漏网之鱼:AppProject 的终结器卡死”除了 Application,ArgoCD 的“项目对象” (AppProject) 也带有防删机制。如果你发现删除一直卡住,请再补上这一刀:
# 剪断所有项目的引爆线kubectl get appprojects -n argocd -o name | xargs -I {} kubectl patch {} -n argocd --type json -p='[{"op": "remove", "path": "/metadata/finalizers"}]' 2>/dev/null2. 清扫游荡的幽灵:全局权限残留
Section titled “2. 清扫游荡的幽灵:全局权限残留”ArgoCD 拥有控制整个集群的极高权限,这意味着它创建的某些 ClusterRole 是不受命名空间限制的。拆除后,我们可以用标签(Label)进行一次全局扫荡:
kubectl delete clusterrole -l app.kubernetes.io/part-of=argocd 2>/dev/nullkubectl delete clusterrolebinding -l app.kubernetes.io/part-of=argocd 2>/dev/null3. 终极黑魔法:强杀卡死的 Namespace
Section titled “3. 终极黑魔法:强杀卡死的 Namespace”如果所有的图纸都已经清理完毕,但最后执行 kubectl delete namespace argocd 时依然无限卡在 Terminating 状态。这意味着 K8s 底层的 API Server 陷入了死循环,通常是因为残留的无法解析的资源阻塞了垃圾回收。
请掏出这段极其危险但也极其有效的 API 强制注销指令(需要宿主机已安装 jq 工具):
kubectl get namespace argocd -o json | \ jq '.spec.finalizers = []' | \ kubectl replace --raw "/api/v1/namespaces/argocd/finalize" -f -这条指令会直接绕过正常的垃圾回收流程,粗暴地把该园区的终结器全部清空,Namespace 瞬间就会灰飞烟灭!
🎉 验收:自由的业务大楼
Section titled “🎉 验收:自由的业务大楼”至此,ArgoCD 已经被你彻底从集群中抹除,你可以使用 kubectl get pods -A 巡查一圈。
你会发现,argocd 命名空间已经彻底消失,且没有任何幽灵权限残留。但你之前通过它部署的真实业务,依然在各自的命名空间里稳健运行。现在,你可以随时重新安装一个崭新的 ArgoCD,再把它们重新“收编”回流水线中!