Skip to content

DevLog

ArgoCD 密码重置:如何恢复遗忘的 admin 登录凭证

在日常运维中,如果遗忘了 ArgoCD Web 面板中 admin 账户的自定义登录密码,将导致无法通过图形界面管理应用。

ArgoCD 将 admin 账户的密码哈希值存储在名为 argocd-secret 的 Kubernetes Secret 资源中。当我们在 UI 界面修改密码时,系统实际上是在更新该 Secret 内部的 admin.password 字段。如果该字段被清空或移除,ArgoCD 将自动回退,允许使用系统在初始化时生成的默认密码进行登录。

基于这一底层逻辑,我们可以通过命令行强制重置密码状态。


请确保你的终端已连接到目标 K3s 集群,且具备操作 argocd 命名空间的高级权限。

使用 kubectl patch 命令,强行从存储配置的 Secret 中剔除自定义密码记录。这相当于清除了系统中后续添加的身份验证覆写规则。

Terminal window
kubectl patch secret argocd-secret -n argocd --type=json -p='[{"op": "remove", "path": "/data/admin.password"}]'

执行成功后,终端应返回 secret/argocd-secret patched

密码字段移除后,需要重启 ArgoCD 的前端 Server 组件,使其强制重新读取底层的 Secret 状态。

Terminal window
kubectl rollout restart deploy argocd-server -n argocd

等待几秒钟,确保新的 Pod 成功启动并接管流量。

此时,ArgoCD 已经回退到出厂安全状态。我们需要从专门存储初始密码的 Secret (argocd-initial-admin-secret) 中提取密码的 Base64 原文并进行解码。

Terminal window
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo

请复制终端输出的这串随机字符串,这是你目前的唯一登录凭证。

  1. 浏览器访问你的 ArgoCD 面板。
  2. 账号输入 admin,密码粘贴刚刚提取的初始字符串。
  3. 登录成功后,导航至页面左侧的 User Info 选项卡。
  4. 点击 Update Password,输入当前密码(初始密码)并设定一个新的、已妥善记录的自定义密码。

完全卸载 ArgoCD:级联删除与集群环境重置

核心概念:级联删除 (Cascading Deletion)

Section titled “核心概念:级联删除 (Cascading Deletion)”

在 GitOps 架构中,如果需要彻底重置测试环境或完全弃用当前的部署方案,我们需要将 ArgoCD 及其部署的所有业务应用一并清理。

ArgoCD 在创建 Application 资源时,默认会注入 resources-finalizer.argocd.argoproj.io 终结器 (Finalizer)。当执行删除操作时,ArgoCD 控制器会根据该终结器,主动向集群发送指令,依次删除该应用所关联的全部底层资源(如 Deployment、Service、ConfigMap 等)。这就是级联删除

为了实现彻底卸载,我们必须保留这些终结器,并让 ArgoCD 控制器先完成全部业务资源的回收,然后再卸载 ArgoCD 自身组件。


步骤 1:触发业务资源的级联删除

Section titled “步骤 1:触发业务资源的级联删除”

首先,直接删除 argocd 命名空间下的所有 Application 资源。 警告:此操作不可逆。执行后,由 ArgoCD 管理的所有实际业务(如 Portainer、数据库等集群应用)将立即开始停止并被销毁。

Terminal window
kubectl delete applications --all -n argocd

由于涉及大量底层资源的终止与销毁,该过程可能需要数分钟。通过以下命令实时监控 Application 的状态:

Terminal window
kubectl get applications -n argocd -w

当命令输出为空,或提示 No resources found in argocd namespace. 时,表明所有被托管的业务资源已彻底清理完毕。

业务资源清理完成后,使用当初部署时相同的官方清单反向卸载 ArgoCD 控制器及相关组件:

Terminal window
kubectl delete -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

步骤 4:清理底层全局资源 (CRD 与命名空间)

Section titled “步骤 4:清理底层全局资源 (CRD 与命名空间)”

最后,删除遗留的自定义资源定义 (CRD) 和专属命名空间。

1. 删除专属 CRD: (注意:如果集群内还有其他命名空间在使用 ArgoCD,请勿执行此步骤)

Terminal window
kubectl delete crd applications.argoproj.io applicationsets.argoproj.io appprojects.argoproj.io 2>/dev/null

2. 删除命名空间:

Terminal window
kubectl delete namespace argocd

如果在上述流程中遇到命令卡死或资源无法删除的情况,请参考以下处理方案:

如果 kubectl delete applications 长时间无响应,通常是因为某些底层资源(如持久化存储卷)无法正常释放,导致 ArgoCD 控制器无法完成终结器逻辑。 可以通过强制移除 Finalizer 来跳过等待:

Terminal window
kubectl get apps -n argocd -o name | xargs -I {} kubectl patch {} -n argocd -p '{"metadata": {"finalizers": null}}' --type merge

如果最后一步删除 argocd 命名空间时一直卡在 Terminating 状态,说明 Kubernetes API 垃圾回收遭遇死锁。可使用 API 强制注销指令直接清除(需确保已安装 jq 工具):

Terminal window
kubectl get namespace argocd -o json | \
jq '.spec.finalizers = []' | \
kubectl replace --raw "/api/v1/namespaces/argocd/finalize" -f -

完成以上步骤后,执行 kubectl get all -A,确认集群内已无相关组件残留,集群状态重置完成。

拆除赛博防盗门:如何安全卸载 Sealed Secrets

🏗️ 拆迁前的致命警告 (The OwnerReference Trap)

Section titled “🏗️ 拆迁前的致命警告 (The OwnerReference Trap)”

在动用挖掘机之前,包工头必须先弄清楚 Kubernetes 底层极其冷酷的垃圾回收逻辑:属主引用 (OwnerReferences)

当我们使用 Sealed Secrets 时,Controller 会读取我们提交的乱码 (SealedSecret 资源),并在同命名空间下生成一个真实的密码 (Secret 资源)。 在这个过程中,Controller 会给真实的 Secret 打上一个烙印:“你的主人是那个 SealedSecret”。

致命后果: 如果你直接卸载 Sealed Secrets 并删除了它的 CRD(自定义资源定义),集群里所有的 SealedSecret 会瞬间消失。K8s 垃圾回收器一看“主人死了”,就会把底层真实的 Secret 全部一起拉去陪葬。 你的数据库、网盘、可视化面板会在下一次重启时,因为找不到密码而全部崩溃瘫痪!


🔐 第一阶段:跑路前的保命操作 (备份主密钥)

Section titled “🔐 第一阶段:跑路前的保命操作 (备份主密钥)”

无论你是想重装集群,还是想迁移到其他加密方案(如 SOPS 或 External Secrets),备份主密钥都是重中之重。丢失了这把私钥,你存在 GitHub 上的所有加密乱码将永远变成解不开的死数据。

打开终端,从系统核心区 (kube-system) 提取你的主密钥并保存到本地安全的地方:

Terminal window
# 提取带有特定标签的主密钥 Secret,并导出为 YAML
kubectl get secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > sealed-secrets-master-key-backup.yaml

✂️ 第二阶段:无损剥离与拆除 (Safe Teardown)

Section titled “✂️ 第二阶段:无损剥离与拆除 (Safe Teardown)”

如果你希望在卸载 Sealed Secrets 之后,集群里的应用依然能拿着现有的明文密码继续运行(无损拆除),你需要遵循以下步骤。

步骤 1:解除密码的“主仆契约”

Section titled “步骤 1:解除密码的“主仆契约””

我们需要切断真实 SecretSealedSecret 之间的属主绑定。这可以通过批量 Patch 抹除 ownerReferences 来实现(需要宿主机安装 jq 工具)。

执行以下硬核除名脚本(遍历所有命名空间):

Terminal window
# 找出所有由 SealedSecret 生成的真实 Secret,并切断它们的从属关系
kubectl get secrets --all-namespaces -o json | jq '.items[] | select(.metadata.ownerReferences != null) | select(.metadata.ownerReferences[].kind == "SealedSecret") | .metadata.namespace + " " + .metadata.name' | tr -d '"' | while read -r ns name; do
echo "正在解放密码: $ns / $name"
kubectl patch secret $name -n $ns --type=json -p='[{"op": "remove", "path": "/metadata/ownerReferences"}]'
done

执行完毕后,所有的业务密码都变成了自由的 K8s 原生对象,不再受 Sealed Secrets 牵连。

步骤 2:纯手工物理强拆解密守卫

Section titled “步骤 2:纯手工物理强拆解密守卫”

既然密码已经自由,且我们准备对集群进行彻底重置,我们就不再依赖任何自动化工具,直接使用 K8s 原生命令进行“物理强拆”。

我们需要把部署在核心区 (kube-system) 的 Controller、Service 以及配套的 RBAC 权限全部清理干净。为了精准打击且不误伤其他核心组件,我们利用标签 (Label) 进行批量扫荡:

Terminal window
# 1. 拆除运行中的核心建筑(Pod、Service、Deployment 等)
kubectl delete all -l app.kubernetes.io/name=sealed-secrets -n kube-system
# 2. 清扫遗留的系统权限(Role、ClusterRole 等),不留任何幽灵后门
kubectl delete clusterrole,clusterrolebinding -l app.kubernetes.io/name=sealed-secrets 2>/dev/null
kubectl delete role,rolebinding -l app.kubernetes.io/name=sealed-secrets -n kube-system 2>/dev/null

(💡 监理提示:如果你当初是直接使用原生的 helm install 命令安装的,这里也可以更优雅地使用 helm uninstall sealed-secrets -n kube-system 一键卸载。但使用上述的标签扫荡法作为兜底,是最为彻底的。)

为了保证赛博堡垒的绝对干净,我们需要把底层的 CRD 协议和留存的主密钥彻底铲平。

1. 销毁加密协议图纸 (CRD):

Terminal window
# 这会删除集群中所有的 SealedSecret 乱码对象,但因为我们在步骤 1 解除了绑定,真实 Secret 不会受影响
kubectl delete crd sealedsecrets.bitnami.com

2. 销毁集群中的主密钥: 虽然 Controller 死了,但主密钥可能还静静地躺在 kube-system 里。

Terminal window
kubectl delete secret -n kube-system -l sealedsecrets.bitnami.com/sealed-secrets-key

巡查集群状态:

Terminal window
kubectl get pods -n kube-system | grep sealed

如果没有任何输出,恭喜你!这扇“赛博防盗门”已经被你完美拆除,而且大楼里的所有业务都在照常营业。

跑路但不拆楼:如何安全卸载 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,让其失去对集群状态的监听和自愈能力。

Terminal window
kubectl scale statefulset argocd-application-controller -n argocd --replicas=0

(💡 监理提示:执行后,ArgoCD 变成了“瞎子和聋子”,绝对不会再产生任何反扑动作。)

步骤 2:从容剪断所有应用的“引爆线”

Section titled “步骤 2:从容剪断所有应用的“引爆线””

大脑死机后,我们就可以毫无顾忌地强制抹除所有 Application 对象的 Finalizer。

打开终端,执行这行“批量剪线”脚本:

Terminal window
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 里的那些“项目档案”了。

Terminal window
kubectl delete apps --all -n argocd

这条命令会瞬间执行完毕,而你集群里的真实业务应用完全不会受到任何影响,它们已经变成了 K8s 的原生脱管应用。

步骤 4:拆除主体建筑 (反向执行安装脚本)

Section titled “步骤 4:拆除主体建筑 (反向执行安装脚本)”

清空了档案后,我们就可以按图索骥,用当初浇筑时的官方图纸进行反向拆除,把 ArgoCD 的 Redis 缓存、API 服务等组件清理掉:

Terminal window
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 实例在使用它们!)

Terminal window
kubectl delete crd applications.argoproj.io appprojects.argoproj.io applicationsets.argoproj.io

2. 抹平命名空间:

Terminal window
kubectl delete namespace argocd

🧰 进阶排障:应对“强拆”中的钉子户 (Troubleshooting)

Section titled “🧰 进阶排障:应对“强拆”中的钉子户 (Troubleshooting)”

在实际的集群拆迁中,K8s 的垃圾回收机制偶尔会发生死锁。如果你在执行上述步骤时卡住了,请使用以下“重火力”工程手段。

1. 漏网之鱼:AppProject 的终结器卡死

Section titled “1. 漏网之鱼:AppProject 的终结器卡死”

除了 Application,ArgoCD 的“项目对象” (AppProject) 也带有防删机制。如果你发现删除一直卡住,请再补上这一刀:

Terminal window
# 剪断所有项目的引爆线
kubectl get appprojects -n argocd -o name | xargs -I {} kubectl patch {} -n argocd --type json -p='[{"op": "remove", "path": "/metadata/finalizers"}]' 2>/dev/null

2. 清扫游荡的幽灵:全局权限残留

Section titled “2. 清扫游荡的幽灵:全局权限残留”

ArgoCD 拥有控制整个集群的极高权限,这意味着它创建的某些 ClusterRole 是不受命名空间限制的。拆除后,我们可以用标签(Label)进行一次全局扫荡:

Terminal window
kubectl delete clusterrole -l app.kubernetes.io/part-of=argocd 2>/dev/null
kubectl delete clusterrolebinding -l app.kubernetes.io/part-of=argocd 2>/dev/null

3. 终极黑魔法:强杀卡死的 Namespace

Section titled “3. 终极黑魔法:强杀卡死的 Namespace”

如果所有的图纸都已经清理完毕,但最后执行 kubectl delete namespace argocd 时依然无限卡在 Terminating 状态。这意味着 K8s 底层的 API Server 陷入了死循环,通常是因为残留的无法解析的资源阻塞了垃圾回收。

请掏出这段极其危险但也极其有效的 API 强制注销指令(需要宿主机已安装 jq 工具):

Terminal window
kubectl get namespace argocd -o json | \
jq '.spec.finalizers = []' | \
kubectl replace --raw "/api/v1/namespaces/argocd/finalize" -f -

这条指令会直接绕过正常的垃圾回收流程,粗暴地把该园区的终结器全部清空,Namespace 瞬间就会灰飞烟灭!


至此,ArgoCD 已经被你彻底从集群中抹除,你可以使用 kubectl get pods -A 巡查一圈。

你会发现,argocd 命名空间已经彻底消失,且没有任何幽灵权限残留。但你之前通过它部署的真实业务,依然在各自的命名空间里稳健运行。现在,你可以随时重新安装一个崭新的 ArgoCD,再把它们重新“收编”回流水线中!

赛博拆迁办:Headlamp 与网络组件的无痕卸载

在赛博工地里,会建高楼只是基本功,懂得如何干净利落地拆除才是老手的自我修养。Kubernetes 集群就像有洁癖的强迫症患者,如果留下一堆不再使用的孤儿资源(Orphaned Resources),不仅占用节点性能,还可能引发潜在的安全和网络冲突。

今天,“赛博拆迁办”正式进场。我们将按照“逆向工程”的逻辑,把上一篇部署的 Headlamp 仪表盘、权限通行证以及“四大天王” Service 全部连根拔起,做到真正的拔线走人、片甲不留

拆除之前,一定要确认我们即将操作的命名空间(Namespace)和资源名称,避免误伤友军。我们将要清理的内容包含:

  1. Helm 部署的 my-headlamp 实例。
  2. 手搓的管理员权限(ServiceAccount、Secret、ClusterRoleBinding)。
  3. 网络压测时留下的四大 Service。

我们将利用之前保留的“施工图纸(YAML文件)”来进行反向拆除。这也是 GitOps 理念的一大优势:图纸即状态。当你想要销毁什么,只需将 apply 换成 delete

  1. 卸载核心建筑:移除 Headlamp 应用

    既然当初是用对讲机(Helm)呼叫的空投,现在也用它来撤场。执行以下命令,Helm 会自动分析并清理属于 my-headlamp 的所有关联资源(如 Deployment、内置 Service 等)。

    Terminal window
    helm uninstall my-headlamp --namespace kube-system

    预期输出:release "my-headlamp" uninstalled。此时监控室的主体结构已坍塌。

  2. 拔除网络管线:销毁“四大天王” Service

    LoadBalancer 还在占用发牌员的内网 IP,NodePort 还在宿主机上开着洞。果断切断它们,归还给 Cilium:

    Terminal window
    kubectl delete -f all-services.yaml

    (如果你之前没保存文件,也可以像拆除权限那样,直接指定名字进行强制拆除:)

    Terminal window
    # 备用方案(无图纸强制拆除)
    kubectl delete svc headlamp-nodeport headlamp-loadbalancer fake-headlamp-ext -n kube-system

    预期输出会显示这几个 Service 被 deleted。Cilium 会瞬间感知并回收底层的 L2 ARP 广播和跨节点端口映射。

  3. 吊销上帝通行证:清理 RBAC 与 Secret

    虽然应用不在了,但我们手搓的集群最高权限账号还留在 kube-system 里。这在安全规范中是绝对的“高危隐患”。直接拿原图纸反向操作:

    Terminal window
    kubectl delete -f headlamp-admin.yaml

    (如果你之前没保存文件,也可以用命令行逐个击破:)

    Terminal window
    # 备用方案(无图纸强制拆除)
    kubectl delete clusterrolebinding headlamp-admin
    kubectl delete serviceaccount headlamp-admin -n kube-system
    kubectl delete secret headlamp-admin-token -n kube-system
  4. 清理仓库图纸源 (可选)

    如果你是个极致的强迫症,希望本地电脑也不留痕迹,可以把 Headlamp 的 Helm 仓库源从本地一并删掉:

    Terminal window
    helm repo remove headlamp

老规矩,拆完必须验收。执行以下命令,看看现场有没有留下垃圾:

Terminal window
# 检查 Pod 是否已销毁
kubectl get pods -n kube-system | grep headlamp
# 检查网络 Service 是否已清理
kubectl get svc -n kube-system | grep headlamp
# 检查越权角色绑定是否已吊销
kubectl get clusterrolebinding | grep headlamp

如果上面三条命令敲下去,什么也没有输出,恭喜你,这片赛博空地已经彻底清理干净,网络拓扑也恢复到了最纯粹的状态。

包工头语录:能够随时随地一键搭建,也能胸有成竹一键销毁,才是掌控 Kubernetes 的终极自由!准备好这片干净的土地,我们要准备迎接下一个重磅工程了。