<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Cyber Foreman | DevLog</title><description/><link>https://besthomelab.tech/</link><language>en</language><item><title>在 K8s/K3s 中为特定 Pod 分配独立物理 IP (Multus + Macvlan + VLAN)</title><link>https://besthomelab.tech/en/blog/macvlan-qb/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/macvlan-qb/</guid><pubDate>Wed, 06 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在构建 HomeLab 或企业内网时，我们经常会将服务部署在 K8s/K3s 集群中。默认情况下，集群内的出站流量会经过 CNI（如 Flannel 或 Cilium）的 SNAT 转换，源 IP 会变成宿主机的 Node IP。&lt;/p&gt;
&lt;p&gt;但在某些场景下（例如部署 qBittorrent 等 P2P 下载工具、需要被独立监控的服务，或者需要绕过网关透明代理的流量），我们需要让 Pod 拥有一个&lt;strong&gt;真实的局域网独立 IP&lt;/strong&gt;，并且可能还需要将其划分到**特定的 VLAN（如 VLAN 10）**中。&lt;/p&gt;
&lt;p&gt;本文将介绍如何使用 &lt;strong&gt;Multus CNI&lt;/strong&gt; 配合 &lt;strong&gt;Macvlan&lt;/strong&gt;，为特定的 Pod “插上一根直通物理局域网的网线”，并配置 OPNsense 网关实现流量直连。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;架构思路与生态兼容性&quot;&gt;架构思路与生态兼容性&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;本方案完美兼容硬核 HomeLab 常用的 &lt;strong&gt;Cilium CNI + kube-vip&lt;/strong&gt; 环境。各组件分工明确，互不冲突：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cilium (主 CNI &amp;#x26; Service LB)&lt;/strong&gt;：负责集群内 eBPF 流量管理与 Service LB IP 分配，为 Pod 提供基础的 &lt;code dir=&quot;auto&quot;&gt;eth0&lt;/code&gt; 网卡。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;kube-vip&lt;/strong&gt;：负责控制平面 API Server 的 VIP 漂移与高可用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multus + Macvlan (旁路直通)&lt;/strong&gt;：作为一个旁路插件，专门为指定的 Pod 塞入第二块物理网卡 &lt;code dir=&quot;auto&quot;&gt;net1&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ 核心避坑：IP 地址池必须严格隔离！&lt;/strong&gt;
必须确保 Macvlan 使用的静态 IP（本文以 &lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt; 为例），与 Cilium LB IPAM 池、kube-vip 的地址、以及 OPNsense 的 DHCP 池完全错开，避免产生 IP 冲突。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤一部署-multus-cni&quot;&gt;步骤一：部署 Multus CNI&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Multus 作为一个“元 CNI”，允许 Pod 挂载多块网卡。如果你的集群尚未安装，可以通过官方提供的 DaemonSet 一键安装（Thick 模式兼容性最好）：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apply&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset-thick.yml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;resources&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;daemonset&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-multus-ds&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-c&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-multus&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--limits=memory=512Mi&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--requests=memory=100Mi&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;等待所有 &lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt; 命名空间下的 &lt;code dir=&quot;auto&quot;&gt;multus&lt;/code&gt; Pod 处于 &lt;code dir=&quot;auto&quot;&gt;Running&lt;/code&gt; 状态即可。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤二创建网络附件定义-networkattachmentdefinition&quot;&gt;步骤二：创建网络附件定义 (NetworkAttachmentDefinition)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;我们需要创建一个 CRD 资源，告诉 K8s 如何划分这个直通的局域网。&lt;/p&gt;
&lt;p&gt;创建一个名为 &lt;code dir=&quot;auto&quot;&gt;macvlan-network.yaml&lt;/code&gt; 的文件。&lt;strong&gt;注意：该资源必须与目标 Pod 处于同一个 Namespace。&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 关于 VLAN 10 的特殊说明：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;情况 A（推荐 PVE 用户）：&lt;/strong&gt; 如果你在 PVE 虚拟机的硬件设置中，为该网卡配置了 &lt;code dir=&quot;auto&quot;&gt;VLAN Tag: 10&lt;/code&gt;，那么 K3s 系统内部的物理网卡（如 &lt;code dir=&quot;auto&quot;&gt;eth0&lt;/code&gt; 或 &lt;code dir=&quot;auto&quot;&gt;ens18&lt;/code&gt;）已经是解包后的 VLAN 10 网络了。下方配置中的 &lt;code dir=&quot;auto&quot;&gt;master&lt;/code&gt; 直接填 &lt;code dir=&quot;auto&quot;&gt;eth0&lt;/code&gt; 即可。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情况 B（Trunk 模式）：&lt;/strong&gt; 如果 PVE 传递的是 Trunk 口，你需要在 K3s 宿主机系统层面（如 Netplan 或 NetworkManager）先创建一个 VLAN 子接口 &lt;code dir=&quot;auto&quot;&gt;eth0.10&lt;/code&gt;，然后下方的 &lt;code dir=&quot;auto&quot;&gt;master&lt;/code&gt; 必须填入 &lt;code dir=&quot;auto&quot;&gt;eth0.10&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;macvlan-network.yaml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;k8s.cni.cncf.io/v1&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;NetworkAttachmentDefinition&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;macvlan-direct&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 必须替换为你的应用所在的 namespace&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# ⚠️ 核心提醒：下方 config 内的字符串会被解析为纯 JSON，绝对不能包含 &apos;#&apos; 注释。&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 所有的关键备注已经为你提取到此处，请根据这些提示修改下方 JSON 对应的值：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;#&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 1. master:      根据上方 VLAN 说明，替换为 eth0 或 eth0.10&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 2. subnet:      10.0.10.0/24 (VLAN 10 的真实网段)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 3. rangeStart:  10.0.10.101 (为 Pod 分配的静态独立 IP)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 4. rangeEnd:    10.0.10.101 (与 rangeStart 保持一致)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 5. gateway:     10.0.10.1 (VLAN 10 的网关)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 6. routes:      必须添加 0.0.0.0/0 的默认路由，否则无法访问外网 (Tracker 会报错)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;config&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;cniVersion&quot;: &quot;0.3.1&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;type&quot;: &quot;macvlan&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;master&quot;: &quot;eth0&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;mode&quot;: &quot;bridge&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;ipam&quot;: {&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;type&quot;: &quot;host-local&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;subnet&quot;: &quot;10.0.10.0/24&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;rangeStart&quot;: &quot;10.0.10.101&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;rangeEnd&quot;: &quot;10.0.10.101&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;gateway&quot;: &quot;10.0.10.1&quot;,&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&quot;routes&quot;: [&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;                &lt;/span&gt;&lt;/span&gt;&lt;span&gt;{ &quot;dst&quot;: &quot;0.0.0.0/0&quot;, &quot;gw&quot;: &quot;10.0.10.1&quot; }&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;        &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;应用此配置：&lt;code dir=&quot;auto&quot;&gt;kubectl apply -f macvlan-network.yaml&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤三修改应用的-deployment-配置&quot;&gt;步骤三：修改应用的 Deployment 配置&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在应用的 &lt;code dir=&quot;auto&quot;&gt;template.metadata.annotations&lt;/code&gt; 中声明使用刚刚创建的网络。同时，为了避免 DNS 流量黑洞，我们需要让该 Pod 绕过集群内部的 CoreDNS，直接使用公网 DNS。&lt;/p&gt;
&lt;p&gt;以部署 qBittorrent 为例：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;deployment.yaml&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;apps/v1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Deployment&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;qbittorrent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;replicas&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;selector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;matchLabels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;app&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;qbittorrent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;template&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;app&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;qbittorrent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;annotations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# 绑定前面创建的 Macvlan 网络&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;k8s.v1.cni.cncf.io/networks&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;macvlan-direct&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# 跳过 K8s CoreDNS，直接使用公网 DNS 解析 Tracker&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;dnsPolicy&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;None&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;dnsConfig&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;nameservers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;223.5.5.5&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;          &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;114.114.114.114&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# 必须固定节点，防止漂移导致物理网卡名称不匹配&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;nodeSelector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;k3s-worker-02&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;containers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;qbittorrent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;image&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;lscr.io/linuxserver/qbittorrent:latest&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;        &lt;/span&gt;&lt;span&gt;# ... 其他配置保持不变&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;重新部署后，进入 Pod 内部执行 &lt;code dir=&quot;auto&quot;&gt;ip a&lt;/code&gt;，你会发现它拥有了两张网卡：&lt;code dir=&quot;auto&quot;&gt;eth0&lt;/code&gt; (集群内部 IP) 和 &lt;code dir=&quot;auto&quot;&gt;net1&lt;/code&gt; (直连 VLAN 10 的 &lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt;)。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;关键一步：&lt;/strong&gt; 必须在应用的内部设置（如 qBittorrent 的高级设置 -&gt; 网络接口）中，&lt;strong&gt;强制将监听网络接口绑定为 &lt;code dir=&quot;auto&quot;&gt;net1&lt;/code&gt;&lt;/strong&gt;，确保流量不走 Cilium 的默认路由，而是真正从 Macvlan 发出。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤四在-opnsense-中设置-nat-豁免-do-not-nat&quot;&gt;步骤四：在 OPNsense 中设置 NAT 豁免 (Do not NAT)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;当 qB 绑定 &lt;code dir=&quot;auto&quot;&gt;net1&lt;/code&gt; 向外发送数据时，流量会到达 OPNsense 网关。由于 OPNsense 默认会对出站流量进行 NAT 伪装，我们需要对这个特定的 IP 进行“豁免”，让最外层的设备（如 OpenClash）能看到它的真实源 IP。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;进入设置菜单：&lt;/strong&gt; 登录 OPNsense，导航至 &lt;strong&gt;防火墙 (Firewall) -&gt; NAT -&gt; 出站 (Outbound)&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修改模式：&lt;/strong&gt; 将出站 NAT 模式修改为 &lt;strong&gt;混合出站 NAT 规则生成 (Hybrid outbound NAT rule generation)&lt;/strong&gt;，点击保存。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;添加豁免规则：&lt;/strong&gt; 点击右上角的 &lt;code dir=&quot;auto&quot;&gt;+&lt;/code&gt; 号添加一条新规则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关键配置项：&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不进行 NAT (Do not NAT)：&lt;/strong&gt; 必须勾选页面最上方这个复选框。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;接口 (Interface)：&lt;/strong&gt; 选择流量离开 OPNsense 去往上层网络（如光猫或旁路由）的接口，通常是 &lt;code dir=&quot;auto&quot;&gt;WAN&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TCP/IP 版本：&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;IPv4&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协议 (Protocol)：&lt;/strong&gt; &lt;code dir=&quot;auto&quot;&gt;any&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;源地址 (Source address)：&lt;/strong&gt; 下拉选择 &lt;code dir=&quot;auto&quot;&gt;单主机或网络 (Single host or Network)&lt;/code&gt;，并输入分配给 Pod 的独立 IP &lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt;，掩码选择 &lt;code dir=&quot;auto&quot;&gt;/32&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;转换/目标 (Translation / target)：&lt;/strong&gt; 保持默认（勾选了不进行 NAT 后，此项会失效）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;调整规则优先级：&lt;/strong&gt; 保存规则后，回到列表页。&lt;strong&gt;将这条新创建的豁免规则拖动到所有规则的最顶部&lt;/strong&gt;（确保它在常规的子网 NAT 规则之前生效），然后点击 &lt;strong&gt;应用更改 (Apply Changes)&lt;/strong&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤五配置透明代理直连-openclash&quot;&gt;步骤五：配置透明代理直连 (OpenClash)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;完成 NAT 豁免后，外部网络（包括旁路代理）就能直接识别到 &lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt; 这个源 IP 了。&lt;/p&gt;
&lt;p&gt;进入你的代理软件（如 OpenClash），在 &lt;strong&gt;访问控制 (Access Control) -&gt; 不走代理的局域网设备 (Not Proxy LAN IPs)&lt;/strong&gt; 中，将 &lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt; 加入列表。至此，你的 P2P 下载流量将完美绕过集群的网络虚拟化层和全局科学代理。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;步骤六访问方式变更与联动服务更新-arr&quot;&gt;步骤六：访问方式变更与联动服务更新 (*arr)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;当你为 Pod 加上了默认物理路由并绑定了网卡后，它已经彻底变成了一台插在局域网上的“实体机”。这会带来两个必须处理的变更：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;集群 Ingress / 域名访问失效：&lt;/strong&gt; 由于流量现在是从集群的 &lt;code dir=&quot;auto&quot;&gt;eth0&lt;/code&gt; 进，却从直连的 &lt;code dir=&quot;auto&quot;&gt;net1&lt;/code&gt; 出，这会导致严重的“异步路由”（Asymmetric Routing），使得原有的 Nginx/Traefik Ingress 域名访问或 NodePort 访问不断转圈超时。
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;解决方案：&lt;/strong&gt; 放弃域名和 NodePort 转发，以后请直接在浏览器输入分配的独立 IP 与端口（如 &lt;code dir=&quot;auto&quot;&gt;http://10.0.10.101:8080&lt;/code&gt;）来访问后台 WebUI。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新 Radarr / Sonarr 下载客户端：&lt;/strong&gt; 如果你使用了 Radarr、Sonarr 或 Prowlarr 等自动化追剧工具，由于 qBittorrent 的访问入口已经改变，你&lt;strong&gt;必须&lt;/strong&gt;前往这些工具的 &lt;code dir=&quot;auto&quot;&gt;设置 -&gt; 下载客户端 (Download Clients)&lt;/code&gt; 中，将 qBittorrent 的主机地址更新为新的独立 IP（&lt;code dir=&quot;auto&quot;&gt;10.0.10.101&lt;/code&gt;）。如果不更新，这些联动组件将无法把种子推送到下载器中。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;避坑指南疑难杂症排查&quot;&gt;避坑指南：疑难杂症排查&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;如果在配置过程中遇到 Pod 无法获取独立 IP 的情况，通常是由以下三个核心问题导致的：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-pve-虚拟化环境下的网卡限制&quot;&gt;1. PVE 虚拟化环境下的网卡限制&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你的 K3s 节点是运行在 Proxmox VE (PVE) 等虚拟化平台上的虚拟机，请务必注意以下两点限制：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;混杂模式与 MAC 地址过滤：&lt;/strong&gt; 进入 PVE 的虚拟机设置，找到 &lt;strong&gt;硬件 (Hardware) -&gt; 网络设备 (Network Device)&lt;/strong&gt;，双击打开编辑，&lt;strong&gt;关闭“防火墙 (Firewall)”选项&lt;/strong&gt;。如果开启该选项，PVE 会拦截 Macvlan 自动生成的非原生 MAC 地址，导致 Pod 无法联网。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VLAN 隔离问题：&lt;/strong&gt; 如果你在 Macvlan 层面使用的是子接口（如 &lt;code dir=&quot;auto&quot;&gt;eth0.10&lt;/code&gt;），请确保 PVE 分配给该虚拟机的网桥（Bridge）开启了 &lt;strong&gt;VLAN 感知 (VLAN aware)&lt;/strong&gt;，否则宿主机将会直接丢弃带有 VLAN Tag 的数据包。&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h3 id=&quot;2-cilium-独占模式导致-multus-失效&quot;&gt;2. Cilium 独占模式导致 Multus 失效&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你发现配置完全正确，但 Pod 依然只分配了 Cilium 的默认内部 IP，请登录宿主机检查 &lt;code dir=&quot;auto&quot;&gt;/etc/cni/net.d/&lt;/code&gt; 目录。如果你看到 &lt;code dir=&quot;auto&quot;&gt;00-multus.conf&lt;/code&gt; 被系统自动重命名为了 &lt;code dir=&quot;auto&quot;&gt;00-multus.conf.cilium_bak&lt;/code&gt;，这说明 Cilium 开启了“独占模式”，强行禁用了 Multus。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决办法：&lt;/strong&gt; 关闭 Cilium 的独占模式并重启相关组件抢回控制权：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 1. 修改 ConfigMap，关闭独占模式&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;configmap&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cilium-config&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;data&quot;:{&quot;cni-exclusive&quot;:&quot;false&quot;}}&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 2. 重启 Cilium 代理以应用新配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;daemonset&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cilium&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 3. 等待 Cilium 启动后，重启 Multus 使其重新生成 00-multus.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;daemonset&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-multus-ds&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-k3s-节点缺失官方-cni-基础插件&quot;&gt;3. K3s 节点缺失官方 CNI 基础插件&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;K3s 是一个极致精简的轻量级发行版，特别是配合 Cilium 使用时，宿主机的 &lt;code dir=&quot;auto&quot;&gt;/opt/cni/bin&lt;/code&gt; 目录下可能并没有预装 &lt;code dir=&quot;auto&quot;&gt;macvlan&lt;/code&gt; 等基础官方插件。此时 Multus 虽能正常工作，但在为 Pod 创建网络沙盒时会抛出如下报错：
&lt;code dir=&quot;auto&quot;&gt;failed to find plugin &quot;macvlan&quot; in path [/opt/cni/bin]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决办法：&lt;/strong&gt; SSH 登录到运行该 Pod 的 K3s 宿主机节点，手动下载并解压官方的标准 CNI 插件包：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 确保目录存在&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/opt/cni/bin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 下载官方 CNI 插件包 (此处以稳定的 v1.4.1 为例)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;wget&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://github.com/containernetworking/plugins/releases/download/v1.4.1/cni-plugins-linux-amd64-v1.4.1.tgz&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 将压缩包解压到 /opt/cni/bin 目录下&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-C&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/opt/cni/bin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-xzf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cni-plugins-linux-amd64-v1.4.1.tgz&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 重建失败的 Pod 即可正常挂载&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded><category>Kubernetes</category><category>K3s</category><category>qBittorrent</category><category>Network</category><category>OPNsense</category><category>Cilium</category><category>VLAN</category></item><item><title>K8s 存储踩坑记：强拆 Longhorn &apos;僵尸 Pod&apos; 钉子户</title><link>https://besthomelab.tech/en/blog/longhorn-pods/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/longhorn-pods/</guid><pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在折腾 K3s + Longhorn 搭建我的赛博影音堡垒时，我遇到了一个极其让人血压升高的玄学 Bug。&lt;/p&gt;
&lt;p&gt;整个流水线突然停工，应用 Pod 疯狂报错无法启动，而罪魁祸首，居然是一个在系统里“死活退不出来”的僵尸进程。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;-案发现场拔不掉的管子&quot;&gt;🚨 案发现场：拔不掉的管子&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;一切起因于我修改了媒体应用（Radarr/Sonarr）的配置文件并重新部署。新 Pod 迟迟无法启动，查看事件日志，赫然飘着那句经典的存储死锁报错：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;Multi-Attach error for volume ... Volume is already exclusively attached to one node and can&apos;t be attached to another&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;意思是：&lt;strong&gt;存储卷正被旧节点死死锁着，新 Pod 拿不到权限。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;顺藤摸瓜，我发现底层负责管理挂载的 &lt;code dir=&quot;auto&quot;&gt;longhorn-csi-plugin&lt;/code&gt; Pod 一直卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt;（正在终止）状态，时长超过了 20 分钟！查看它的详细日志，看到了这句致命的超时宣告：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;error killing pod: failed to &lt;/span&gt;&lt;span&gt;&quot;KillContainer&quot;&lt;/span&gt;&lt;span&gt; for &lt;/span&gt;&lt;span&gt;&quot;longhorn-liveness-probe&quot;&lt;/span&gt;&lt;span&gt; ... rpc &lt;/span&gt;&lt;span&gt;error:&lt;/span&gt;&lt;span&gt; code = DeadlineExceeded desc = context deadline exceeded&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;-赛博验尸报告为什么它杀不死&quot;&gt;🧠 赛博验尸报告：为什么它“杀不死”？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;表面上看是 Kubernetes 出了 Bug，但深入探究，这其实是 Linux 内核底层的自我保护机制导致的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;I/O 阻塞&lt;/strong&gt;：由于之前尝试跨网段挂载 NFS 导致了网络超时，底层的存储进程卡在了“等待磁盘响应”的状态。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内核级锁死 (D-state)&lt;/strong&gt;：在 Linux 中，当进程卡在底层 I/O 等待时，内核会将其标记为 &lt;strong&gt;不可中断睡眠 (Uninterruptible Sleep, D状态)&lt;/strong&gt;。在这个状态下，进程会无视任何外部信号（包括 &lt;code dir=&quot;auto&quot;&gt;kill -9&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kubelet 懵逼&lt;/strong&gt;：Kubernetes 的包工头 Kubelet 给容器引擎下达了“拔管”指令，但底层容器因为 D 状态根本不鸟它。Kubelet 苦等 2 分钟后无奈宣布超时（DeadlineExceeded），于是这个 Pod 就成了一个永远卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 的“钉子户”，并且牢牢霸占着 Longhorn 的存储锁。&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;h2 id=&quot;️-三板斧解决僵尸-pod&quot;&gt;🛠️ 三板斧解决僵尸 Pod&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;对付这种级别的钉子户，常规的清理已经没用了。必须采取暴力强拆手段。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第一板斧k8s-逻辑强抹除本次生效的绝招&quot;&gt;第一板斧：K8s 逻辑强抹除（本次生效的绝招）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;既然正常的优雅退出走不通，那就直接在 K8s 的记录本上把它强行划掉，不给任何宽限时间。&lt;/p&gt;
&lt;p&gt;执行以下命令强杀卡死的 Pod：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;卡住的Pod名称&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--force&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--grace-period=0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;效果&lt;/strong&gt;：命令敲下的瞬间，Pod 从列表中消失，Longhorn 控制平面终于意识到锁可以释放，随后新 Pod 瞬间挂载存储卷成功，业务恢复！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;h3 id=&quot;第二板斧重启底层容器引擎备用方案&quot;&gt;第二板斧：重启底层容器引擎（备用方案）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果在执行完第一步后，&lt;code dir=&quot;auto&quot;&gt;kubectl get pods&lt;/code&gt; 里确实没它了，但应用依然报 &lt;code dir=&quot;auto&quot;&gt;Multi-Attach error&lt;/code&gt;，说明底层 Linux 进程依然在霸占资源。此时需要重启 K3s 的 agent 服务来重置容器状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 登录出问题的 K3s 工作节点执行&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-agent&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 如果是主节点则执行 restart k3s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;第三板斧物理重启终极毁灭&quot;&gt;第三板斧：物理重启（终极毁灭）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果前两招都打完，存储依然处于死锁状态，说明 Linux 内核的 I/O 队列已经彻底崩溃。别犹豫，直接 &lt;code dir=&quot;auto&quot;&gt;sudo reboot&lt;/code&gt; 重启该节点所在的物理机或虚拟机，这是清理 D 状态进程最彻底的方案。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;-赛博包工头的总结&quot;&gt;💡 赛博包工头的总结&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;这次踩坑不仅让我深入理解了 Kubernetes 和底层操作系统的联动关系，也总结出了一条铁律：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在 HomeLab 环境中，对于独占存储（ReadWriteOnce）的单副本有状态应用（如 qBittorrent、数据库等），在 &lt;code dir=&quot;auto&quot;&gt;deployment.yaml&lt;/code&gt; 中务必将更新策略设置为重建！&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;replicas&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;strategy&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Recreate&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 强制先杀旧，再启新，绝不抢锁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;遇到 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 不要慌，找准病根，果断拔管！&lt;/p&gt;</content:encoded><category>Kubernetes</category><category>Longhorn</category><category>K3s</category><category>HomeLab</category></item><item><title>🚨 赛博排障实录：CNPG 密码“脑裂”与内核级破门指南</title><link>https://besthomelab.tech/en/blog/cnpg-brain-split/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/cnpg-brain-split/</guid><pubDate>Sat, 02 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;️-事故现场完美的图纸打不开的大门&quot;&gt;⚠️ 事故现场：完美的图纸，打不开的大门&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在部署 pgAdmin 接入 CloudNativePG (CNPG) 时，即便你严格遵守了 GitOps 的每一行配置，提取了最新的 K8s Secret 密码，依然可能遇到那个令人抓狂的报错：&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;pgAdmin 4 - Connection Error&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;FATAL: password authentication failed for user &quot;postgres&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;这种“钥匙（Secret）打不开自家大门（Database）”的现象，在 Operator 模式下被称为 &lt;strong&gt;“状态撕裂” (State Desync)&lt;/strong&gt;，俗称 &lt;strong&gt;“脑裂”&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-深度复盘为什么会被天坑算计&quot;&gt;🧠 深度复盘：为什么会被“天坑”算计？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;这本质上是 &lt;strong&gt;Kubernetes 的声明式状态&lt;/strong&gt; 与 &lt;strong&gt;数据库的物理持久化状态&lt;/strong&gt; 发生了脱节。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-cnpg-的一次性发卡机制&quot;&gt;1. CNPG 的“一次性”发卡机制&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;CNPG 管家只在集群 &lt;strong&gt;第一次初始化 (Bootstrap)&lt;/strong&gt; 的那一瞬间，会生成随机密码并同时写入 K8s Secret 和数据库底层引擎。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2-k8s-与物理存储-longhorn-的脱节&quot;&gt;2. K8s 与物理存储 (Longhorn) 的脱节&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你曾删除过 CNPG 实例但保留了 Longhorn 数据卷，当你再次拉起集群时：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;K8s 视角&lt;/strong&gt;：这是一个新任务，它会生成一个全新的 Secret（新钥匙）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Postgres 视角&lt;/strong&gt;：挂载旧硬盘后，它依然守着第一次建库时的旧密码（老锁芯）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结果&lt;/strong&gt;：外面显示的密码是 A，但门里认的密码是 B。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-赛博暴力破门方案潜入内核强行修正&quot;&gt;🔨 赛博暴力破门方案：潜入内核强行修正&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;既然外面的钥匙失效了，作为赛博堡垒的造物主，我们不再纠结于 Secret，直接利用 &lt;strong&gt;Socket 直连&lt;/strong&gt; 潜入数据库心脏，从内部强制重置密码。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-1直捣黄龙潜入主节点&quot;&gt;步骤 1：直捣黄龙，潜入主节点&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;利用 &lt;code dir=&quot;auto&quot;&gt;kubectl exec&lt;/code&gt; 绕过网络认证，以本地超级用户身份进入数据库 Pod：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 进入主节点终端并直连 psql&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;exec&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-it&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;database&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;homelab-db-cluster-1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;psql&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-2内核级重置密码&quot;&gt;步骤 2：内核级重置密码&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;进入 &lt;code dir=&quot;auto&quot;&gt;postgres=#&lt;/code&gt; 提示符后，执行 SQL 语句进行“物理修正”：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;-- 强行将 postgres 用户的锁芯更换为你预设的密码&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;ALTER&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;USER&lt;/span&gt;&lt;span&gt; postgres &lt;/span&gt;&lt;span&gt;WITH&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PASSWORD&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;你的新密码&apos;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;-- 退出内核&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;\q&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-总结首席承包商的终极底牌&quot;&gt;👑 总结：首席承包商的终极底牌&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;这次排障告诉我们一个真理：&lt;strong&gt;在云原生时代，GitOps 是流程，但 &lt;code dir=&quot;auto&quot;&gt;kubectl&lt;/code&gt; 是真理。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;不管外面的声明式配置如何演变，只要你能以系统造物主的身份进行“内核级干预”，你就永远拥有整座赛博堡垒的最终解释权。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;-避坑准则&quot;&gt;💡 避坑准则&lt;/h3&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;重建集群时&lt;/strong&gt;：若要彻底重置密码，必须连同 Longhorn 的 PVC 一起清理。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排障优先级&lt;/strong&gt;：当应用层认证失败时，优先检查物理存储是否包含陈旧状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-脑裂排障逻辑图-troubleshooting-flow&quot;&gt;🗺️ 脑裂排障逻辑图 (Troubleshooting Flow)&lt;/h2&gt;&lt;/div&gt;
&lt;div data-content=&quot;graph TD
  A[发现认证失败] --&gt; B{Secret 密码正确吗?}
  B -- 否 --&gt; C[修正 Secret]
  B -- 是 --&gt; D{是否保留了旧 PVC?}
  D -- 否 --&gt; E[检查网络或特殊字符]
  D -- 是 --&gt; F[判定为脑裂: 状态脱节]
  F --&gt; G[kubectl exec 进入容器]
  G --&gt; H[SQL 强制 ALTER USER]
  H --&gt; I[pgAdmin 重新连接成功]&quot; data-status=&quot;loading&quot;&gt;&lt;/div&gt;</content:encoded><category>troubleshooting</category><category>cnpg</category><category>postgresql</category><category>kubernetes</category><category>k3s</category></item><item><title>K8s 焦土政策：网关与证书系统的终极卸载指南</title><link>https://besthomelab.tech/en/blog/cert-manager-unistall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/cert-manager-unistall/</guid><pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;这是一份针对 Kubernetes 集群的**“彻彻底底、连根拔起”**清理方案。&lt;/p&gt;
&lt;p&gt;当你的网关和证书系统因为各种改动搅得一团糟，且面临诸如 ArgoCD 陷入死锁、命名空间卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 无法删除等极其顽固的底层状态错误时，**“焦土政策（物理核平）”**绝对是最有效、最干净的排障手段。&lt;/p&gt;
&lt;p&gt;请&lt;strong&gt;严格按照以下顺序&lt;/strong&gt;执行。这套连招能保证把系统里的残留基因拔得干干净净，绝不影响下一次重装。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-第一阶段斩断源头-切断-argocd-重建链&quot;&gt;☢️ 第一阶段：斩断源头 (切断 ArgoCD 重建链)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在使用 GitOps (如 ArgoCD) 时，决不能直接去删底层资源，否则 ArgoCD 会发现“建筑没了”，并立刻把它们重新拉起来。我们必须先切断图纸的下发。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-尝试常规删除应用&quot;&gt;1. 尝试常规删除应用&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;traefik&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-遭遇死锁强行剥夺-argocd-的遗愿清单&quot;&gt;2. 遭遇死锁？强行剥夺 ArgoCD 的遗愿清单&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果上面的命令卡住转圈（报错 &lt;code dir=&quot;auto&quot;&gt;metadata.finalizers: Forbidden&lt;/code&gt;），说明 ArgoCD 本身陷入了死结。立刻打开新终端，执行强制“拔管”：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;: {&quot;finalizers&quot;: null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;application&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;traefik&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;: {&quot;finalizers&quot;: null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;执行后，ArgoCD 面板上的应用会瞬间消失，系统不再自动重建。&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-第二阶段深度扫荡-清理-webhooks-与-全局-crds&quot;&gt;💣 第二阶段：深度扫荡 (清理 Webhooks 与 全局 CRDs)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;这是 99% 的人重装失败的根源！&lt;/strong&gt; 命名空间好删，但全局注册的蓝图规范（CRD）和拦截器（Webhook）如果不清空，下次安装必定会报出各种版本冲突。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-摧毁潜伏的-webhook&quot;&gt;1. 摧毁潜伏的 Webhook&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;Cert-manager 会向 K8s API Server 注入拦截器，必须优先干掉，否则它会拦截你接下来的所有安装请求：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;validatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager-webhook&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--ignore-not-found&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;mutatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager-webhook&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--ignore-not-found&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-屠宰所有相关-crd-蓝图基因&quot;&gt;2. 屠宰所有相关 CRD (蓝图基因)&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 删光 Traefik 和 Cert-manager 的残留基因&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-E&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;traefik|cert-manager&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-扫荡残留的全局权限-rbac&quot;&gt;3. 扫荡残留的“全局权限” (RBAC)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;这一步经常被忽视，导致重装时报 &lt;code dir=&quot;auto&quot;&gt;Ownership/Adoption&lt;/code&gt; 错误：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 清理集群级别的角色与绑定&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrole,clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-E&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;cert-manager|traefik&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 清理隐藏在 kube-system 核心区的领导者选举权限&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;role,rolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-第三阶段核平街区-强制清理-namespace-内部残留&quot;&gt;🧨 第三阶段：核平街区 (强制清理 Namespace 内部残留)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;如果你发现 Namespace 删不掉，或者里面总剩下一堆 &lt;code dir=&quot;auto&quot;&gt;Role&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;Service&lt;/code&gt;, &lt;code dir=&quot;auto&quot;&gt;ServiceAccount&lt;/code&gt;，那是它们身上带着 &lt;strong&gt;Finalizers（保护锁）&lt;/strong&gt;。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-强制碎锁局部资源&quot;&gt;1. 强制“碎锁”局部资源&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;在删除 Namespace 之前，先手动清除这些顽固住户的遗愿清单：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 定义目标命名空间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;TARGET_NS&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;cert-manager&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;traefik&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; ns &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;${&lt;/span&gt;&lt;span&gt;TARGET_NS&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;@&lt;/span&gt;&lt;span&gt;]}&quot;&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;do&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;正在强制碎锁 &lt;/span&gt;&lt;span&gt;$ns&lt;/span&gt;&lt;span&gt; 中的局部资源...&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# 批量清除 Role, RoleBinding, ServiceAccount, Service 的保护锁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rolebinding,role,serviceaccount,service&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; $ns &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; $ns &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;:{&quot;finalizers&quot;:null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-物理超度-namespace&quot;&gt;2. 物理超度 Namespace&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;现在执行删除指令，由于内部资源已碎锁，它们会随街区一并消失：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cert-manager&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;traefik&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--force&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--grace-period=0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-第四阶段物理超度-清理僵尸命名空间&quot;&gt;💀 第四阶段：物理超度 (清理僵尸命名空间)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;如果执行完第三步，使用 &lt;code dir=&quot;auto&quot;&gt;kubectl get ns&lt;/code&gt; 发现它们依然死死卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 状态，说明遭遇了**“僵尸命名空间”**。动用最后的 API 接口直连手段：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-开启通向集群心脏的后门&quot;&gt;1. 开启通向集群心脏的后门&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;proxy&lt;/span&gt;&lt;span&gt; &amp;#x26;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-发射核弹指令清空命名空间的-finalizers&quot;&gt;2. 发射核弹指令，清空命名空间的 Finalizers&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;直接调用 API 接口，强行抹除 Namespace 最后的执念：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 针对 cert-manager&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-H&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-X&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PUT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--data-binary&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;Namespace&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;v1&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;cert-manager&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;finalizers&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:[]}}&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http://localhost:8001/api/v1/namespaces/cert-manager/finalize&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 针对 traefik&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-H&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-X&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;PUT&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--data-binary&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;Namespace&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;v1&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;traefik&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;},&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:{&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;finalizers&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;:[]}}&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;http://localhost:8001/api/v1/namespaces/traefik/finalize&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-验尸与关门&quot;&gt;3. 验尸与关门&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 确认僵尸已经彻底消失&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ns&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 杀掉后台开启的 kubectl proxy&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kill&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;%1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 架构师总结&lt;/strong&gt;
走完这完整的四阶段，你的集群就真正回到了**“像素级纯净”**的状态。所有的 Role、ServiceAccount 和全局权限都已化为灰烬。现在，你可以放心地去推送你配置了 &lt;strong&gt;OpenDNS 5353 端口&lt;/strong&gt; 的新图纸，享受一次零报错的全新丝滑安装体验！&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><category>kubernetes</category><category>cert-manager</category><category>traefik</category><category>argocd</category></item><item><title>K8s 证书避坑指南：如何安全地测试并申请 Let&apos;s Encrypt 泛域名证书</title><link>https://besthomelab.tech/en/blog/encrypt-test/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/encrypt-test/</guid><pubDate>Mon, 27 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在 Kubernetes 集群中，使用 &lt;code dir=&quot;auto&quot;&gt;cert-manager&lt;/code&gt; 配合 Let’s Encrypt 自动签发免费的 HTTPS 泛域名证书，是目前的业界标配。&lt;/p&gt;
&lt;p&gt;但是，无数新手在第一次配置时都会踩进一个**“死亡陷阱”**：Let’s Encrypt 对正式接口有极其严格的速率限制。如果你因为 DNS 配置填错、Token 权限不对等原因导致申请失败超过 5 次，&lt;strong&gt;你的域名将被拉黑封锁 1 个小时；如果反复重试，甚至会被封锁 7 天！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;为了避免“坠机”，最标准、最专业的做法是：&lt;strong&gt;先用测试服 (Staging) 跑通流程，再切换到正式服 (Production)。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天这篇文章，就带你完整走一遍这个“演习到转正”的标准全流程。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-第一阶段使用-staging-测试服-进行实战演习&quot;&gt;🚦 第一阶段：使用 Staging (测试服) 进行实战演习&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Let’s Encrypt 提供了一个专门的 Staging 测试环境，它的请求限制极其宽松，你可以随便报错、随便重试，绝对不会封锁你的域名。&lt;/p&gt;
&lt;p&gt;我们的第一步，就是写一份指向测试服的图纸。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-编写-staging-配置文件&quot;&gt;1. 编写 Staging 配置文件&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;创建一个名为 &lt;code dir=&quot;auto&quot;&gt;cluster-issuer-and-cert.yaml&lt;/code&gt; 的文件。请注意看代码中的注释，&lt;strong&gt;有 3 个地方是测试服独有的&lt;/strong&gt;：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 1. 声明一个测试服的“发证机关” (ClusterIssuer)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cert-manager.io/v1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ClusterIssuer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-staging&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# 🧪 标志 1：命名为 staging&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;acme&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 🧪 标志 2：必须使用 Staging 的 API 地址！&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;https://acme-staging-v02.api.letsencrypt.org/directory&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;(https://acme-staging-v02.api.letsencrypt.org/directory)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;your-email@example.com&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;# ⚠️ 替换为你的真实邮箱，用于接收过期通知&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;privateKeySecretRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;# 🧪 标志 3：测试服专用的账号私钥名称，千万别和正式服重名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-staging-account-key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;solvers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;dns01&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;cloudflare&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;# 这里以 Cloudflare DNS 验证为例&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;apiTokenSecretRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cloudflare-api-token&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;api-token&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;---&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 2. 提交一份“证书申请单” (Certificate)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cert-manager.io/v1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Certificate&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# ⚠️ 替换为你网关 (如 Traefik/Nginx) 所在的命名空间&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;secretName&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# 最终生成的证书 Secret 名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;issuerRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# 🧪 标志 4：指定上面那个测试服发证机关来处理这张单子&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-staging&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ClusterIssuer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;commonName&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;*.example.com&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# ⚠️ 替换为你的域名&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;dnsNames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;&quot;example.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;&quot;*.example.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-部署并验证演习成果&quot;&gt;2. 部署并验证演习成果&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;将上面的配置应用到集群中：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apply&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cluster-issuer-and-cert.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;接下来，我们不需要去浏览器里看，直接在终端里盯着它的状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 监控证书状态 (将 default 换成你自己的 namespace)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;certificate&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-w&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;成功标志&lt;/strong&gt;：当你看到 &lt;code dir=&quot;auto&quot;&gt;READY&lt;/code&gt; 这一列从 &lt;code dir=&quot;auto&quot;&gt;False&lt;/code&gt; 变成了 &lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;True&lt;/code&gt;&lt;/strong&gt;，恭喜你，演习大获全胜！这证明你的 DNS Token 和底层网络链路已经 100% 跑通。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;终极查验 (彻底放心)&lt;/strong&gt;：如果你想彻底确认这张申请下来的证书到底是谁发的，建议使用以下&lt;strong&gt;兼容性最强&lt;/strong&gt;的“临时文件法”进行查验：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 1. 提取 Secret 中的证书内容，解码后存入临时文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;jsonpath=&apos;{.data.tls\.crt}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;base64&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/tmp/cert_verify.crt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 2. 调用 openssl 物理查验该文件并过滤颁发者&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;openssl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;x509&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-in&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/tmp/cert_verify.crt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-text&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-noout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;Issuer&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 3. 查完即焚，删除临时文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/tmp/cert_verify.crt&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;预计输出结果：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;演习环境 (Staging)&lt;/strong&gt;：输出包含 &lt;code dir=&quot;auto&quot;&gt;Issuer: ..., CN=(STAGING) Artificial Apricot R3&lt;/code&gt;。
&lt;blockquote&gt;
&lt;p&gt;这证明 Let’s Encrypt 已经认可了你的域名所有权，并把测试用的“假证书”发给你了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;正式环境 (Production)&lt;/strong&gt;：输出包含 &lt;code dir=&quot;auto&quot;&gt;Issuer: ..., CN=R3&lt;/code&gt; (没有 STAGING 字样)。
&lt;blockquote&gt;
&lt;p&gt;这说明你的正式绿锁已经下发。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;h2 id=&quot;-第二阶段销毁假证正式转正-production&quot;&gt;🚀 第二阶段：销毁假证，正式转正 (Production)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;既然流程已经跑通，我们就可以放心大胆地去正式服领真绿锁了。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-修改图纸切换为正式环境&quot;&gt;1. 修改图纸，切换为正式环境&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;回到你刚才的 &lt;code dir=&quot;auto&quot;&gt;cluster-issuer-and-cert.yaml&lt;/code&gt; 文件，把那 4 个测试服的标志全部改掉：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cert-manager.io/v1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ClusterIssuer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-prod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# ✅ 1. 改为 prod&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;acme&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;# ✅ 2. 换成 Let&apos;s Encrypt 的正式服 API&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;: [&lt;/span&gt;&lt;span&gt;https://acme-v02.api.letsencrypt.org/directory&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;(https://acme-v02.api.letsencrypt.org/directory)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;email&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;your-email@example.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;privateKeySecretRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;      &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-prod-account-key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# ✅ 3. 换个正式的工作证名称&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;solvers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;      &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;dns01&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;          &lt;/span&gt;&lt;span&gt;cloudflare&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;            &lt;/span&gt;&lt;span&gt;apiTokenSecretRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cloudflare-api-token&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;              &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;api-token&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;---&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;cert-manager.io/v1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;Certificate&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;secretName&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;issuerRef&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;letsencrypt-prod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;# ✅ 4. 向正式服机关提交申请&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;ClusterIssuer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;commonName&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;*.example.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;dnsNames&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;&quot;example.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;&quot;*.example.com&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;再次应用配置：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apply&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cluster-issuer-and-cert.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-核心必做物理销毁旧证书&quot;&gt;2. 【核心必做】物理销毁旧证书！&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;这是无数人翻车的一步！&lt;/strong&gt; 虽然你修改了申请单，但 Kubernetes 发现你的系统里已经存在一个叫 &lt;code dir=&quot;auto&quot;&gt;my-website-tls&lt;/code&gt; 的 Secret（刚才测试服发的那个），并且还没过期，它&lt;strong&gt;很可能不会去触发重新签发&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;你必须手动把那个假证书“撕毁”，倒逼 cert-manager 重新去正式服申请：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 删除测试服生成的假证书 Secret&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-见证真锁降临&quot;&gt;3. 见证真锁降临&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;删掉假证书后，cert-manager 会立刻反应过来：“哎呀，证书没了，而且现在的发证机关变成了 Prod，我得赶紧去申请一张新的！”&lt;/p&gt;
&lt;p&gt;再次查看状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;certificate&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-website-tls&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-w&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;由于之前的网络链路已经验证过完全没问题，这次的申请会极快通过。当状态再次变为 &lt;code dir=&quot;auto&quot;&gt;READY: True&lt;/code&gt; 时，刷新你的浏览器页面（建议使用无痕模式清除缓存）。&lt;/p&gt;
&lt;p&gt;那把坚不可摧、受全球所有设备信任的 &lt;strong&gt;HTTPS 绿色小锁&lt;/strong&gt;，就已经完美挂在你的域名上了！&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 总结：&lt;/strong&gt;
无论是个人折腾还是企业级部署，&lt;strong&gt;先用 Staging 测试，再切 Prod 签发，最后 delete secret 强制重签&lt;/strong&gt;，这套“三步走”战略能帮你避开 99% 的证书签发雷区。&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><category>kubernetes</category><category>cert-manager</category><category>letsencrypt</category></item><item><title>ArgoCD 密码重置：如何恢复遗忘的 admin 登录凭证</title><link>https://besthomelab.tech/en/blog/argocd-password-reset/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/argocd-password-reset/</guid><pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;故障背景&quot;&gt;故障背景&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在日常运维中，如果遗忘了 ArgoCD Web 面板中 &lt;code dir=&quot;auto&quot;&gt;admin&lt;/code&gt; 账户的自定义登录密码，将导致无法通过图形界面管理应用。&lt;/p&gt;
&lt;p&gt;ArgoCD 将 &lt;code dir=&quot;auto&quot;&gt;admin&lt;/code&gt; 账户的密码哈希值存储在名为 &lt;code dir=&quot;auto&quot;&gt;argocd-secret&lt;/code&gt; 的 Kubernetes Secret 资源中。当我们在 UI 界面修改密码时，系统实际上是在更新该 Secret 内部的 &lt;code dir=&quot;auto&quot;&gt;admin.password&lt;/code&gt; 字段。如果该字段被清空或移除，ArgoCD 将自动回退，允许使用系统在初始化时生成的默认密码进行登录。&lt;/p&gt;
&lt;p&gt;基于这一底层逻辑，我们可以通过命令行强制重置密码状态。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;密码恢复流程&quot;&gt;密码恢复流程&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;请确保你的终端已连接到目标 K3s 集群，且具备操作 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间的高级权限。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-1移除自定义密码字段&quot;&gt;步骤 1：移除自定义密码字段&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code dir=&quot;auto&quot;&gt;kubectl patch&lt;/code&gt; 命令，强行从存储配置的 Secret 中剔除自定义密码记录。这相当于清除了系统中后续添加的身份验证覆写规则。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd-secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type=json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p=&lt;/span&gt;&lt;span&gt;&apos;[{&quot;op&quot;: &quot;remove&quot;, &quot;path&quot;: &quot;/data/admin.password&quot;}]&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;执行成功后，终端应返回 &lt;code dir=&quot;auto&quot;&gt;secret/argocd-secret patched&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-2重启-api-server-服务&quot;&gt;步骤 2：重启 API Server 服务&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;密码字段移除后，需要重启 ArgoCD 的前端 Server 组件，使其强制重新读取底层的 Secret 状态。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd-server&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;等待几秒钟，确保新的 Pod 成功启动并接管流量。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-3提取系统初始密码&quot;&gt;步骤 3：提取系统初始密码&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;此时，ArgoCD 已经回退到出厂安全状态。我们需要从专门存储初始密码的 Secret (&lt;code dir=&quot;auto&quot;&gt;argocd-initial-admin-secret&lt;/code&gt;) 中提取密码的 Base64 原文并进行解码。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd-initial-admin-secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;jsonpath=&quot;{.data.password}&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;base64&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&lt;/span&gt;&lt;span&gt; &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;请复制终端输出的这串随机字符串，这是你目前的唯一登录凭证。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-4登录并设置新密码&quot;&gt;步骤 4：登录并设置新密码&lt;/h3&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;浏览器访问你的 ArgoCD 面板。&lt;/li&gt;
&lt;li&gt;账号输入 &lt;code dir=&quot;auto&quot;&gt;admin&lt;/code&gt;，密码粘贴刚刚提取的初始字符串。&lt;/li&gt;
&lt;li&gt;登录成功后，导航至页面左侧的 &lt;strong&gt;User Info&lt;/strong&gt; 选项卡。&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;Update Password&lt;/strong&gt;，输入当前密码（初始密码）并设定一个新的、已妥善记录的自定义密码。&lt;/li&gt;
&lt;/ol&gt;
&lt;aside aria-label=&quot;Caution&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Caution &lt;/p&gt; &lt;div&gt; &lt;p&gt;&lt;strong&gt;安全提示：&lt;/strong&gt;
&lt;code dir=&quot;auto&quot;&gt;argocd-initial-admin-secret&lt;/code&gt; 仅设计为首次安装时的临时凭证机制。一旦你成功恢复访问并设置了新的自定义密码，建议将此初始 Secret 删除，以符合最小权限安全原则。&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;</content:encoded><category>kubernetes</category><category>k3s</category><category>argocd</category><category>troubleshooting</category><category>security</category></item><item><title>完全卸载 ArgoCD：级联删除与集群环境重置</title><link>https://besthomelab.tech/en/blog/argocd-uninstll-all/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/argocd-uninstll-all/</guid><pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;核心概念级联删除-cascading-deletion&quot;&gt;核心概念：级联删除 (Cascading Deletion)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在 GitOps 架构中，如果需要彻底重置测试环境或完全弃用当前的部署方案，我们需要将 ArgoCD 及其部署的所有业务应用一并清理。&lt;/p&gt;
&lt;p&gt;ArgoCD 在创建 &lt;code dir=&quot;auto&quot;&gt;Application&lt;/code&gt; 资源时，默认会注入 &lt;code dir=&quot;auto&quot;&gt;resources-finalizer.argocd.argoproj.io&lt;/code&gt; 终结器 (Finalizer)。当执行删除操作时，ArgoCD 控制器会根据该终结器，主动向集群发送指令，依次删除该应用所关联的全部底层资源（如 Deployment、Service、ConfigMap 等）。这就是&lt;strong&gt;级联删除&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为了实现彻底卸载，我们必须保留这些终结器，并让 ArgoCD 控制器先完成全部业务资源的回收，然后再卸载 ArgoCD 自身组件。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;彻底卸载流程-teardown-steps&quot;&gt;彻底卸载流程 (Teardown Steps)&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-1触发业务资源的级联删除&quot;&gt;步骤 1：触发业务资源的级联删除&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;首先，直接删除 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间下的所有 &lt;code dir=&quot;auto&quot;&gt;Application&lt;/code&gt; 资源。
&lt;strong&gt;警告：此操作不可逆。执行后，由 ArgoCD 管理的所有实际业务（如 Portainer、数据库等集群应用）将立即开始停止并被销毁。&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applications&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-2监控资源回收进度&quot;&gt;步骤 2：监控资源回收进度&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;由于涉及大量底层资源的终止与销毁，该过程可能需要数分钟。通过以下命令实时监控 &lt;code dir=&quot;auto&quot;&gt;Application&lt;/code&gt; 的状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applications&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-w&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;当命令输出为空，或提示 &lt;code dir=&quot;auto&quot;&gt;No resources found in argocd namespace.&lt;/code&gt; 时，表明所有被托管的业务资源已彻底清理完毕。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-3卸载-argocd-核心组件&quot;&gt;步骤 3：卸载 ArgoCD 核心组件&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;业务资源清理完成后，使用当初部署时相同的官方清单反向卸载 ArgoCD 控制器及相关组件：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-4清理底层全局资源-crd-与命名空间&quot;&gt;步骤 4：清理底层全局资源 (CRD 与命名空间)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;最后，删除遗留的自定义资源定义 (CRD) 和专属命名空间。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 删除专属 CRD：&lt;/strong&gt;
&lt;em&gt;(注意：如果集群内还有其他命名空间在使用 ArgoCD，请勿执行此步骤)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applications.argoproj.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applicationsets.argoproj.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;appprojects.argoproj.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. 删除命名空间：&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;进阶排障-troubleshooting&quot;&gt;进阶排障 (Troubleshooting)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;如果在上述流程中遇到命令卡死或资源无法删除的情况，请参考以下处理方案：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-application-删除卡死&quot;&gt;1. Application 删除卡死&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果 &lt;code dir=&quot;auto&quot;&gt;kubectl delete applications&lt;/code&gt; 长时间无响应，通常是因为某些底层资源（如持久化存储卷）无法正常释放，导致 ArgoCD 控制器无法完成终结器逻辑。
可以通过强制移除 Finalizer 来跳过等待：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apps&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;: {&quot;finalizers&quot;: null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-namespace-状态卡在-terminating&quot;&gt;2. Namespace 状态卡在 Terminating&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果最后一步删除 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间时一直卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 状态，说明 Kubernetes API 垃圾回收遭遇死锁。可使用 API 强制注销指令直接清除（需确保已安装 &lt;code dir=&quot;auto&quot;&gt;jq&lt;/code&gt; 工具）：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;.spec.finalizers = []&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;replace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--raw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;/api/v1/namespaces/argocd/finalize&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;完成以上步骤后，执行 &lt;code dir=&quot;auto&quot;&gt;kubectl get all -A&lt;/code&gt;，确认集群内已无相关组件残留，集群状态重置完成。&lt;/p&gt;</content:encoded><category>kubernetes</category><category>k3s</category><category>argocd</category><category>ops</category></item><item><title>拆除赛博防盗门：如何安全卸载 Sealed Secrets</title><link>https://besthomelab.tech/en/blog/sealed-secrets-uninstall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/sealed-secrets-uninstall/</guid><pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;️-拆迁前的致命警告-the-ownerreference-trap&quot;&gt;🏗️ 拆迁前的致命警告 (The OwnerReference Trap)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在动用挖掘机之前，包工头必须先弄清楚 Kubernetes 底层极其冷酷的垃圾回收逻辑：&lt;strong&gt;属主引用 (OwnerReferences)&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;当我们使用 Sealed Secrets 时，Controller 会读取我们提交的乱码 (&lt;code dir=&quot;auto&quot;&gt;SealedSecret&lt;/code&gt; 资源)，并在同命名空间下生成一个真实的密码 (&lt;code dir=&quot;auto&quot;&gt;Secret&lt;/code&gt; 资源)。
在这个过程中，Controller 会给真实的 &lt;code dir=&quot;auto&quot;&gt;Secret&lt;/code&gt; 打上一个烙印：“你的主人是那个 &lt;code dir=&quot;auto&quot;&gt;SealedSecret&lt;/code&gt;”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;致命后果&lt;/strong&gt;：
如果你直接卸载 Sealed Secrets 并删除了它的 CRD（自定义资源定义），集群里所有的 &lt;code dir=&quot;auto&quot;&gt;SealedSecret&lt;/code&gt; 会瞬间消失。K8s 垃圾回收器一看“主人死了”，就会把底层真实的 &lt;code dir=&quot;auto&quot;&gt;Secret&lt;/code&gt; 全部一起拉去陪葬。
你的数据库、网盘、可视化面板会在下一次重启时，因为找不到密码而全部崩溃瘫痪！&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-第一阶段跑路前的保命操作-备份主密钥&quot;&gt;🔐 第一阶段：跑路前的保命操作 (备份主密钥)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;无论你是想重装集群，还是想迁移到其他加密方案（如 SOPS 或 External Secrets），&lt;strong&gt;备份主密钥&lt;/strong&gt;都是重中之重。丢失了这把私钥，你存在 GitHub 上的所有加密乱码将永远变成解不开的死数据。&lt;/p&gt;
&lt;p&gt;打开终端，从系统核心区 (&lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt;) 提取你的主密钥并保存到本地安全的地方：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 提取带有特定标签的主密钥 Secret，并导出为 YAML&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sealedsecrets.bitnami.com/sealed-secrets-key&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;yaml&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sealed-secrets-master-key-backup.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;aside aria-label=&quot;Danger&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; Danger &lt;/p&gt; &lt;div&gt; &lt;p&gt;&lt;strong&gt;极密警告：&lt;/strong&gt; 这个 &lt;code dir=&quot;auto&quot;&gt;sealed-secrets-master-key-backup.yaml&lt;/code&gt; 文件就是你整个赛博堡垒的“万能钥匙”。&lt;strong&gt;绝对、绝对、绝对不要&lt;/strong&gt;把它 &lt;code dir=&quot;auto&quot;&gt;git commit&lt;/code&gt; 推送到任何公开仓库中！请将它存放在你的离线 U 盘或 1Password 等加密金库里。&lt;/p&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-第二阶段无损剥离与拆除-safe-teardown&quot;&gt;✂️ 第二阶段：无损剥离与拆除 (Safe Teardown)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;如果你希望在卸载 Sealed Secrets 之后，集群里的应用依然能拿着现有的明文密码继续运行（无损拆除），你需要遵循以下步骤。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-1解除密码的主仆契约&quot;&gt;步骤 1：解除密码的“主仆契约”&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;我们需要切断真实 &lt;code dir=&quot;auto&quot;&gt;Secret&lt;/code&gt; 与 &lt;code dir=&quot;auto&quot;&gt;SealedSecret&lt;/code&gt; 之间的属主绑定。这可以通过批量 Patch 抹除 &lt;code dir=&quot;auto&quot;&gt;ownerReferences&lt;/code&gt; 来实现（需要宿主机安装 &lt;code dir=&quot;auto&quot;&gt;jq&lt;/code&gt; 工具）。&lt;/p&gt;
&lt;p&gt;执行以下硬核除名脚本（遍历所有命名空间）：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 找出所有由 SealedSecret 生成的真实 Secret，并切断它们的从属关系&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secrets&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all-namespaces&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;.items[] | select(.metadata.ownerReferences != null) | select(.metadata.ownerReferences[].kind == &quot;SealedSecret&quot;) | .metadata.namespace + &quot; &quot; + .metadata.name&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;tr&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-d&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;while&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-r&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ns&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;do&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;正在解放密码: &lt;/span&gt;&lt;span&gt;$ns&lt;/span&gt;&lt;span&gt; / &lt;/span&gt;&lt;span&gt;$name&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; $name &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; $ns &lt;/span&gt;&lt;span&gt;--type=json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p=&lt;/span&gt;&lt;span&gt;&apos;[{&quot;op&quot;: &quot;remove&quot;, &quot;path&quot;: &quot;/metadata/ownerReferences&quot;}]&apos;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;执行完毕后，所有的业务密码都变成了自由的 K8s 原生对象，不再受 Sealed Secrets 牵连。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-2纯手工物理强拆解密守卫&quot;&gt;步骤 2：纯手工物理强拆解密守卫&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;既然密码已经自由，且我们准备对集群进行彻底重置，我们就不再依赖任何自动化工具，直接使用 K8s 原生命令进行“物理强拆”。&lt;/p&gt;
&lt;p&gt;我们需要把部署在核心区 (&lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt;) 的 Controller、Service 以及配套的 RBAC 权限全部清理干净。为了精准打击且不误伤其他核心组件，我们利用标签 (Label) 进行批量扫荡：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 1. 拆除运行中的核心建筑（Pod、Service、Deployment 等）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/name=sealed-secrets&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 2. 清扫遗留的系统权限（Role、ClusterRole 等），不留任何幽灵后门&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrole,clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/name=sealed-secrets&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;role,rolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/name=sealed-secrets&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(💡 监理提示：如果你当初是直接使用原生的 &lt;code dir=&quot;auto&quot;&gt;helm install&lt;/code&gt; 命令安装的，这里也可以更优雅地使用 &lt;code dir=&quot;auto&quot;&gt;helm uninstall sealed-secrets -n kube-system&lt;/code&gt; 一键卸载。但使用上述的标签扫荡法作为兜底，是最为彻底的。)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-3深度清理地基与残骸&quot;&gt;步骤 3：深度清理地基与残骸&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;为了保证赛博堡垒的绝对干净，我们需要把底层的 CRD 协议和留存的主密钥彻底铲平。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 销毁加密协议图纸 (CRD)：&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 这会删除集群中所有的 SealedSecret 乱码对象，但因为我们在步骤 1 解除了绑定，真实 Secret 不会受影响&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sealedsecrets.bitnami.com&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. 销毁集群中的主密钥：&lt;/strong&gt;
虽然 Controller 死了，但主密钥可能还静静地躺在 &lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt; 里。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sealedsecrets.bitnami.com/sealed-secrets-key&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h2 id=&quot;-验收与后续规划&quot;&gt;🎉 验收与后续规划&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;巡查集群状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pods&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sealed&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;如果没有任何输出，恭喜你！这扇“赛博防盗门”已经被你完美拆除，而且大楼里的所有业务都在照常营业。&lt;/p&gt;</content:encoded><category>kubernetes</category><category>k3s</category><category>sealed-secrets</category><category>security</category><category>gitops</category></item><item><title>跑路但不拆楼：如何安全卸载 ArgoCD 且保留所有业务应用</title><link>https://besthomelab.tech/en/blog/argocd-uninstll/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/argocd-uninstll/</guid><pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;️-核心概念非级联删除-non-cascading-deletion&quot;&gt;🏗️ 核心概念：非级联删除 (Non-Cascading Deletion)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在赛博堡垒中，有时我们只想重装或卸载 ArgoCD 本身（比如迁移 GitOps 工具，或者清理测试环境），但&lt;strong&gt;绝不希望&lt;/strong&gt;它把正在运行的业务应用（比如我们的存储大坝、可视化面板）一起删掉。&lt;/p&gt;
&lt;p&gt;ArgoCD 在部署应用时，默认会给资源打上一个叫 &lt;code dir=&quot;auto&quot;&gt;resources-finalizer.argocd.argoproj.io&lt;/code&gt; 的终结器（相当于一根引爆线）。如果你直接执行 &lt;code dir=&quot;auto&quot;&gt;kubectl delete namespace argocd&lt;/code&gt;，它会顺着这根线把底层真实的 Pod 和 Service 全部“爆破”掉，甚至会导致整个命名空间卡死在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 状态。&lt;/p&gt;
&lt;p&gt;要做到**“监工跑路，大楼照常营业”**，我们必须在拆除指挥中心前，偷偷剪断所有的引爆线。&lt;/p&gt;
&lt;aside aria-label=&quot;⚠️ 高阶架构拆除警告：提防自愈反扑与违章建筑&quot;&gt; &lt;p aria-hidden=&quot;true&quot;&gt; ⚠️ 高阶架构拆除警告：提防自愈反扑与违章建筑 &lt;/p&gt; &lt;div&gt; &lt;ol&gt;
&lt;li&gt;&lt;strong&gt;提防自愈反扑 (Self-Heal Trap)&lt;/strong&gt;：如果你的集群使用了 &lt;strong&gt;App of Apps (套娃架构)&lt;/strong&gt; 并且开启了自动修复 (&lt;code dir=&quot;auto&quot;&gt;selfHeal: true&lt;/code&gt;)。当你试图剪断子应用的引爆线时，总控制台会瞬间察觉并强行将其接回！这会导致后续删除时发生意外的连带破坏（例如 Pod 还在，但 Service 丢了）。因此，&lt;strong&gt;必须先瘫痪控制器，再执行清理&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;提防违章建筑 (Namespace Nuke)&lt;/strong&gt;：卸载的最后一步会彻底夷平 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间。如果你之前图省事，把其他业务的 Service 或 Ingress 放在了 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间下，它们将遭受无差别的核打击。请确保 &lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间内只有纯粹的 GitOps 基础设施！&lt;/li&gt;
&lt;/ol&gt; &lt;/div&gt; &lt;/aside&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-无损拆除流程-safe-teardown-steps&quot;&gt;✂️ 无损拆除流程 (Safe Teardown Steps)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;为了绝对的安全，我们将采用**“暗杀级”**施工法：先切断监工的大脑，再从容拆除。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-1瘫痪指挥中心大脑-停止控制器&quot;&gt;步骤 1：瘫痪指挥中心大脑 (停止控制器)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;这是应对复杂 GitOps 架构最关键的一步。我们必须先把 ArgoCD 的应用控制器副本数缩容为 0，让其失去对集群状态的监听和自愈能力。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;scale&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;statefulset&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd-application-controller&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--replicas=0&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(💡 监理提示：执行后，ArgoCD 变成了“瞎子和聋子”，绝对不会再产生任何反扑动作。)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-2从容剪断所有应用的引爆线&quot;&gt;步骤 2：从容剪断所有应用的“引爆线”&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;大脑死机后，我们就可以毫无顾忌地强制抹除所有 Application 对象的 Finalizer。&lt;/p&gt;
&lt;p&gt;打开终端，执行这行“批量剪线”脚本：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apps&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;: {&quot;finalizers&quot;: null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(💡 监理提示：执行完后，这些应用就已经彻底脱离 ArgoCD 的“同归于尽”机制了。)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-3销毁-gitops-档案-删除-application-对象&quot;&gt;步骤 3：销毁 GitOps 档案 (删除 Application 对象)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;既然引爆线已经没了，且没有控制器来阻挠，我们现在就可以安全地删掉 ArgoCD 里的那些“项目档案”了。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apps&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;这条命令会瞬间执行完毕，而&lt;strong&gt;你集群里的真实业务应用完全不会受到任何影响&lt;/strong&gt;，它们已经变成了 K8s 的原生脱管应用。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-4拆除主体建筑-反向执行安装脚本&quot;&gt;步骤 4：拆除主体建筑 (反向执行安装脚本)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;清空了档案后，我们就可以按图索骥，用当初浇筑时的官方图纸进行反向拆除，把 ArgoCD 的 Redis 缓存、API 服务等组件清理掉：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;步骤-5深度清理残骸-删除-crd-与命名空间&quot;&gt;步骤 5：深度清理残骸 (删除 CRD 与命名空间)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;最后一步，把划拨给 ArgoCD 的专属园区，以及它留在 K8s 底层的那些自定义资源定义（CRD）连根拔起。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 彻底粉碎专属 CRD：&lt;/strong&gt;
&lt;em&gt;(⚠️ 警告：这会删除全集群所有命名空间下的 ArgoCD 相关资源，确保你没有其他的 ArgoCD 实例在使用它们！)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applications.argoproj.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;appprojects.argoproj.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;applicationsets.argoproj.io&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;2. 抹平命名空间：&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-进阶排障应对强拆中的钉子户-troubleshooting&quot;&gt;🧰 进阶排障：应对“强拆”中的钉子户 (Troubleshooting)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在实际的集群拆迁中，K8s 的垃圾回收机制偶尔会发生死锁。如果你在执行上述步骤时卡住了，请使用以下“重火力”工程手段。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-漏网之鱼appproject-的终结器卡死&quot;&gt;1. 漏网之鱼：AppProject 的终结器卡死&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;除了 Application，ArgoCD 的“项目对象” (AppProject) 也带有防删机制。如果你发现删除一直卡住，请再补上这一刀：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 剪断所有项目的引爆线&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;appprojects&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p=&lt;/span&gt;&lt;span&gt;&apos;[{&quot;op&quot;: &quot;remove&quot;, &quot;path&quot;: &quot;/metadata/finalizers&quot;}]&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-清扫游荡的幽灵全局权限残留&quot;&gt;2. 清扫游荡的幽灵：全局权限残留&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;ArgoCD 拥有控制整个集群的极高权限，这意味着它创建的某些 &lt;code dir=&quot;auto&quot;&gt;ClusterRole&lt;/code&gt; 是不受命名空间限制的。拆除后，我们可以用标签（Label）进行一次全局扫荡：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrole&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/part-of=argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/part-of=argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-终极黑魔法强杀卡死的-namespace&quot;&gt;3. 终极黑魔法：强杀卡死的 Namespace&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果所有的图纸都已经清理完毕，但最后执行 &lt;code dir=&quot;auto&quot;&gt;kubectl delete namespace argocd&lt;/code&gt; 时依然无限卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt; 状态。这意味着 K8s 底层的 API Server 陷入了死循环，通常是因为残留的无法解析的资源阻塞了垃圾回收。&lt;/p&gt;
&lt;p&gt;请掏出这段&lt;strong&gt;极其危险但也极其有效&lt;/strong&gt;的 API 强制注销指令（需要宿主机已安装 &lt;code dir=&quot;auto&quot;&gt;jq&lt;/code&gt; 工具）：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;argocd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;json&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;jq&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;.spec.finalizers = []&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;replace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--raw&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&quot;/api/v1/namespaces/argocd/finalize&quot;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;这条指令会直接绕过正常的垃圾回收流程，粗暴地把该园区的终结器全部清空，Namespace 瞬间就会灰飞烟灭！&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-验收自由的业务大楼&quot;&gt;🎉 验收：自由的业务大楼&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;至此，ArgoCD 已经被你彻底从集群中抹除，你可以使用 &lt;code dir=&quot;auto&quot;&gt;kubectl get pods -A&lt;/code&gt; 巡查一圈。&lt;/p&gt;
&lt;p&gt;你会发现，&lt;code dir=&quot;auto&quot;&gt;argocd&lt;/code&gt; 命名空间已经彻底消失，且没有任何幽灵权限残留。但你之前通过它部署的真实业务，依然在各自的命名空间里稳健运行。现在，你可以随时重新安装一个崭新的 ArgoCD，再把它们重新“收编”回流水线中！&lt;/p&gt;</content:encoded><category>kubernetes</category><category>k3s</category><category>argocd</category><category>ops</category><category>troubleshooting</category></item><item><title>赛博拆迁办：Headlamp 与网络组件的无痕卸载</title><link>https://besthomelab.tech/en/blog/headlamp-unistall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/headlamp-unistall/</guid><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在赛博工地里，会建高楼只是基本功，懂得如何&lt;strong&gt;干净利落地拆除&lt;/strong&gt;才是老手的自我修养。Kubernetes 集群就像有洁癖的强迫症患者，如果留下一堆不再使用的孤儿资源（Orphaned Resources），不仅占用节点性能，还可能引发潜在的安全和网络冲突。&lt;/p&gt;
&lt;p&gt;今天，“赛博拆迁办”正式进场。我们将按照“逆向工程”的逻辑，把上一篇部署的 Headlamp 仪表盘、权限通行证以及“四大天王” Service 全部连根拔起，做到真正的&lt;strong&gt;拔线走人、片甲不留&lt;/strong&gt;。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;-拆除准备确认拆迁目标&quot;&gt;🧹 拆除准备：确认拆迁目标&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;拆除之前，一定要确认我们即将操作的命名空间（Namespace）和资源名称，避免误伤友军。我们将要清理的内容包含：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Helm 部署的 &lt;code dir=&quot;auto&quot;&gt;my-headlamp&lt;/code&gt; 实例。&lt;/li&gt;
&lt;li&gt;手搓的管理员权限（ServiceAccount、Secret、ClusterRoleBinding）。&lt;/li&gt;
&lt;li&gt;网络压测时留下的四大 Service。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-核心拆除作业&quot;&gt;🚜 核心拆除作业&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;我们将利用之前保留的“施工图纸（YAML文件）”来进行反向拆除。这也是 GitOps 理念的一大优势：&lt;strong&gt;图纸即状态&lt;/strong&gt;。当你想要销毁什么，只需将 &lt;code dir=&quot;auto&quot;&gt;apply&lt;/code&gt; 换成 &lt;code dir=&quot;auto&quot;&gt;delete&lt;/code&gt;。&lt;/p&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;卸载核心建筑：移除 Headlamp 应用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;既然当初是用对讲机（Helm）呼叫的空投，现在也用它来撤场。执行以下命令，Helm 会自动分析并清理属于 &lt;code dir=&quot;auto&quot;&gt;my-headlamp&lt;/code&gt; 的所有关联资源（如 Deployment、内置 Service 等）。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uninstall&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;my-headlamp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;预期输出：&lt;code dir=&quot;auto&quot;&gt;release &quot;my-headlamp&quot; uninstalled&lt;/code&gt;。此时监控室的主体结构已坍塌。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;拔除网络管线：销毁“四大天王” Service&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LoadBalancer 还在占用发牌员的内网 IP，NodePort 还在宿主机上开着洞。果断切断它们，归还给 Cilium：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;all-services.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(如果你之前没保存文件，也可以像拆除权限那样，直接指定名字进行强制拆除：)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 备用方案（无图纸强制拆除）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;svc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-nodeport&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-loadbalancer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;fake-headlamp-ext&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;预期输出会显示这几个 Service 被 deleted。Cilium 会瞬间感知并回收底层的 L2 ARP 广播和跨节点端口映射。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;吊销上帝通行证：清理 RBAC 与 Secret&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;虽然应用不在了，但我们手搓的集群最高权限账号还留在 &lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt; 里。这在安全规范中是绝对的“高危隐患”。直接拿原图纸反向操作：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-admin.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(如果你之前没保存文件，也可以用命令行逐个击破：)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 备用方案（无图纸强制拆除）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-admin&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;serviceaccount&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-admin&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;secret&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp-admin-token&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清理仓库图纸源 (可选)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你是个极致的强迫症，希望本地电脑也不留痕迹，可以把 Headlamp 的 Helm 仓库源从本地一并删掉：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-拆除验收清点现场&quot;&gt;🔍 拆除验收：清点现场&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;老规矩，拆完必须验收。执行以下命令，看看现场有没有留下垃圾：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 检查 Pod 是否已销毁&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pods&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 检查网络 Service 是否已清理&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;svc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 检查越权角色绑定是否已吊销&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;如果上面三条命令敲下去，&lt;strong&gt;什么也没有输出&lt;/strong&gt;，恭喜你，这片赛博空地已经彻底清理干净，网络拓扑也恢复到了最纯粹的状态。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;包工头语录&lt;/strong&gt;：能够随时随地一键搭建，也能胸有成竹一键销毁，才是掌控 Kubernetes 的终极自由！准备好这片干净的土地，我们要准备迎接下一个重磅工程了。&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><category>kubernetes</category><category>helm</category><category>uninstall</category><category>headlamp</category></item><item><title>赛博拆迁办：安全切断外接大水管 (卸载 NFS 动态供应器)</title><link>https://besthomelab.tech/en/blog/nfs-unistall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/nfs-unistall/</guid><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在赛博工地，拆迁工作也分危险等级。如果说卸载 Longhorn 相当于“定向爆破承重墙”，那么卸载 NFS 动态供应器仅仅相当于**“辞退了一个水管工”**。&lt;/p&gt;
&lt;p&gt;因为 NFS 的实际数据都安全地躺在你远端的 TrueNAS 或群晖里，K3s 集群内运行的仅仅是一个负责“自动建文件夹和接管子”的调度程序（Provisioner）。所以，它的卸载过程非常轻松且无痛。&lt;/p&gt;
&lt;p&gt;尽管如此，为了保证集群状态的绝对干净，包工头还是建议你按照标准协议进行拆除。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;️-拆除前置清退依赖水管的租客&quot;&gt;⚠️ 拆除前置：清退依赖水管的租客&lt;/h2&gt;&lt;/div&gt;
&lt;span&gt;安全规范&lt;/span&gt;
&lt;p&gt;在辞退水管工之前，最好先确认集群里是否还有应用正在使用 &lt;code dir=&quot;auto&quot;&gt;nfs-client&lt;/code&gt; 这个存储类（StorageClass）。&lt;/p&gt;
&lt;p&gt;如果还有应用在用，当你卸载了供应器后，这些应用原本挂载的旧硬盘虽然还能读写，但未来如果它们意外重启或者你需要扩容，由于失去了“水管工”的调度，它们可能会陷入异常状态。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;检查指令：&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 查看是否还有绑定到 nfs-client 的 PVC（存储声明）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pvc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-A&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nfs-client&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(如果输出为空，说明水管已经全部闲置，可以放心开拆。如果还有业务在使用，请先决定是保留业务，还是将其连同 PVC 一并删除。)&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-核心拆除作业&quot;&gt;🚜 核心拆除作业&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;呼叫 Helm 拆迁队 (Uninstall Provisioner)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因为我们是使用 Helm 规范化部署的，直接用一条命令就可以把水管工（Pod）、它的权限（RBAC）以及图纸代号（StorageClass）全部带走：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uninstall&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nfs-provisioner&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;预期输出：&lt;code dir=&quot;auto&quot;&gt;release &quot;nfs-provisioner&quot; uninstalled&lt;/code&gt;。此时，K8s 已经失去了自动在 NAS 上划分目录的能力。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;打扫物理 NAS 的残余数据 (Manual Cleanup)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;还记得我们在上一篇配置 &lt;code dir=&quot;auto&quot;&gt;values.yaml&lt;/code&gt; 时，特意加了一个防爆机制 &lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;archiveOnDelete: true&lt;/code&gt;&lt;/strong&gt; 吗？&lt;/p&gt;
&lt;p&gt;正是因为这个机制，即使你之前在 K8s 里删除了测试用的 PVC，水管工也不会真的去删你 NAS 里的数据，而是会将那个文件夹重命名，加上 &lt;code dir=&quot;auto&quot;&gt;archived-&lt;/code&gt; 前缀。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;现在，水管工已经被我们辞退了，这部分“赛博垃圾”就需要你手动去清理了：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录你物理 NAS 的后台（TrueNAS / 群晖）。&lt;/li&gt;
&lt;li&gt;打开文件管理器，进入你分配给 K8s 的那个共享根目录（例如 &lt;code dir=&quot;auto&quot;&gt;/mnt/pool/k8s_nfs&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;你会看到一些名字带有 &lt;code dir=&quot;auto&quot;&gt;archived-&lt;/code&gt; 开头的文件夹。如果你确认这些数据都已经没用了，直接在 NAS 后台&lt;strong&gt;右键 -&gt; 删除&lt;/strong&gt;即可，彻底释放物理空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清理本地 Helm 仓库 (可选)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你有极度的强迫症，不想在本地电脑上留下任何痕迹，可以顺手把官方的图纸源也删掉：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;repo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;remove&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nfs-subdir-external-provisioner&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-拆除验收&quot;&gt;🔍 拆除验收&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;最后，敲下这行命令，看看 K8s 的“存储物资局”里还有没有这张图纸：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;storageclass&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;如果输出的列表中已经找不到 &lt;code dir=&quot;auto&quot;&gt;nfs-client&lt;/code&gt;，且终端里没有任何关于 &lt;code dir=&quot;auto&quot;&gt;nfs-provisioner&lt;/code&gt; 的报错，那么恭喜你，这根外接大水管已经被安全、干净地彻底切断！&lt;/p&gt;</content:encoded><category>kubernetes</category><category>helm</category><category>uninstall</category><category>nfs</category><category>storage</category></item><item><title>赛博拆迁办：安全定向爆破 Longhorn 分布式存储大坝</title><link>https://besthomelab.tech/en/blog/longhorn-unistall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/longhorn-unistall/</guid><pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在 Kubernetes 的世界里，无状态应用（如之前部署的 Headlamp）卸载起来就像拔掉 U 盘一样简单。但是，&lt;strong&gt;存储组件是集群的“承重墙”&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;Longhorn 作为底层存储大坝，掌管着所有容器的命脉数据。为了防止新手误操作导致“删库跑路”的悲剧，Longhorn 官方在底层上了一道极其死板的“物理锁”。如果你直接暴力执行卸载，整个 &lt;code dir=&quot;auto&quot;&gt;longhorn-system&lt;/code&gt; 命名空间会永远卡在 &lt;code dir=&quot;auto&quot;&gt;Terminating&lt;/code&gt;（挂起）状态，你的 K8s 集群将陷入无尽的死锁僵局。&lt;/p&gt;
&lt;p&gt;今天，包工头就结合官方的卸载与排错指南，带你按照正规的“定向爆破协议”，一步步安全、干净地拆除这座大坝，并解决拆除过程中可能遇到的所有疑难杂症。&lt;/p&gt;
&lt;div&gt;&lt;h2 id=&quot;️-拆除前置警告清退所有租客&quot;&gt;⚠️ 拆除前置警告：清退所有租客！&lt;/h2&gt;&lt;/div&gt;
&lt;span&gt;极度危险&lt;/span&gt;
&lt;p&gt;&lt;strong&gt;在执行任何卸载命令前，为了防止损坏集群，官方强烈建议：&lt;/strong&gt;
你必须手动删除所有正在使用 Longhorn 卷的 Kubernetes 工作负载（包括 PersistentVolume, PersistentVolumeClaim, StorageClass, Deployment, StatefulSet 等）。
&lt;strong&gt;一旦拆除开始，所有基于 Longhorn 创建的虚拟硬盘数据将瞬间灰飞烟灭！请务必提前做好数据备份。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-核心爆破流程-helm-方式&quot;&gt;🚜 核心爆破流程 (Helm 方式)&lt;/h2&gt;&lt;/div&gt;
&lt;ol role=&quot;list&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;解除数据自毁保护锁 (The Safety Catch)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是卸载 Longhorn &lt;strong&gt;最核心、最不可省略&lt;/strong&gt;的一步。默认情况下 &lt;code dir=&quot;auto&quot;&gt;deleting-confirmation-flag&lt;/code&gt; 是关闭的，卸载任务会直接报错拦截。我们需要强制告诉 Longhorn 控制器：“我确定要销毁一切”。&lt;/p&gt;
&lt;p&gt;在终端敲入这行指令，修改核心配置，允许删除操作：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;value&quot;: &quot;true&quot;}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type=merge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;lhs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deleting-confirmation-flag&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;预期输出：&lt;code dir=&quot;auto&quot;&gt;setting.longhorn.io/deleting-confirmation-flag patched&lt;/code&gt;。保护锁现已解除。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;呼叫 Helm 拆迁队 (Uninstall Release)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;保护锁解除后，我们就可以正常呼叫 Helm 执行反向拆除了。它会自动释放 Cilium 分配的 LoadBalancer IP，并遣散所有节点的存储引擎容器。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uninstall&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;稍等片刻，直到终端提示 &lt;code dir=&quot;auto&quot;&gt;release &quot;longhorn&quot; uninstalled&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;清理大坝废墟 (Delete Namespace)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;确认 Helm 卸载完毕后，我们将整个存储专区物理抹除：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;打扫物理宿主机的残渣 (Node Data Cleanup)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：这一步需要到你所有的 3 台 Ubuntu 物理机/虚拟机上分别执行！&lt;/strong&gt;
虽然 K8s 里的组件删除了，但 Longhorn 之前在你的宿主机磁盘上生成的物理数据块依然保留着。为了彻底归还磁盘空间，直接使用 &lt;code dir=&quot;auto&quot;&gt;rm&lt;/code&gt; 大法：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-rf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/lib/longhorn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;恢复 Linux 内核秩序 (可选)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你确定这几台机器以后&lt;strong&gt;再也不碰&lt;/strong&gt;基于 iSCSI 的存储，可以把之前我们立下的“开机规矩”撤销掉。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/modules-load.d/longhorn.conf&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;disable&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--now&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;iscsid&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-疑难杂症与抢修指南-troubleshooting&quot;&gt;🛠️ 疑难杂症与抢修指南 (Troubleshooting)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在赛博工地，意外总是难免的。如果你在卸载过程中遇到了卡死、报错，或者突然“手滑”后悔了，请参考以下官方急救方案：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;-症状-1手滑卸载了但我不想删取消卸载&quot;&gt;💊 症状 1：手滑卸载了，但我不想删！（取消卸载）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你不小心执行了 &lt;code dir=&quot;auto&quot;&gt;helm uninstall&lt;/code&gt;（且当时没开保护锁导致它卡在 uninstalling 状态），你可以利用 Helm 的时光机功能紧急回档。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;抢修指令：&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 1. 查找 Longhorn 卸载前的最后一个正常版本号 (REVISION)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;list&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-a&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 2. 假设查到上一个正常版本是 1，执行强制回滚：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollback&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;提示 &lt;code dir=&quot;auto&quot;&gt;Rollback was a success!&lt;/code&gt; 代表大坝抢修成功，数据保住了！&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;-症状-2namespace-一直卡在-terminatingcrd-删不掉&quot;&gt;💊 症状 2：Namespace 一直卡在 Terminating，CRD 删不掉&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;这是 Kubernetes 卸载存储组件最常见的恶疾：&lt;strong&gt;Finalizer 幽灵锁&lt;/strong&gt;。因为底层引擎已经被你删了，K8s 还在傻傻等待底层引擎来确认删除这些 CRD（自定义资源），从而形成死锁。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;抢修指令（暴力清除所有 Longhorn 状态）：&lt;/strong&gt;
执行以下脚本，它会遍历所有 Longhorn 的 CRD，强行抹除它们的 Finalizer，然后连根拔起。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 批量强拆：剥夺所有 Longhorn 资源的终结器&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; crd &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; $(&lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn.io&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;awk&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{print $1}&apos;&lt;/span&gt;&lt;span&gt;); &lt;/span&gt;&lt;span&gt;do&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;    &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; $crd &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;xargs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-I&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;patch&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;{}&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&apos;{&quot;metadata&quot;:{&quot;finalizers&quot;:null}}&apos;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--type&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;merge&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;done&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;-症状-3执行清理脚本时报错-webhook-找不到&quot;&gt;💊 症状 3：执行清理脚本时报错 Webhook 找不到&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你在执行上面那个清理脚本时，K8s 抛出了类似这样的错误：
&lt;code dir=&quot;auto&quot;&gt;Internal error occurred: failed calling webhook &quot;validator.longhorn.io&quot;... service &quot;longhorn-admission-webhook&quot; not found&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这是因为残缺的卸载过程把 Webhook 服务删了，但注册表里还留着它的名字，导致 K8s 每次修改资源都想去请求一个不存在的验证服务。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;抢修指令：&lt;/strong&gt;
删除这些拦截请求的幽灵配置，为清理脚本放行：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ValidatingWebhookConfiguration&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-webhook-validator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;MutatingWebhookConfiguration&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn-webhook-mutator&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;删除这两个配置后，重新执行&lt;strong&gt;症状 2&lt;/strong&gt;中的 CRD 清理脚本，即可丝滑通关。&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-终极验收&quot;&gt;🔍 终极验收&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;历经波折后，执行最后的扫尾质检：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;crd&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ns&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;longhorn&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;如果上述命令&lt;strong&gt;没有任何输出&lt;/strong&gt;，恭喜你，这座赛博存储大坝已经被完美定向爆破，所有的顽疾和锁链都已被彻底斩断！&lt;/p&gt;</content:encoded><category>kubernetes</category><category>k3s</category><category>longhorn</category><category>uninstall</category><category>storage</category><category>troubleshooting</category></item><item><title>K3s + Cilium 踩坑实录：Longhorn 插件无限重启？揪出 eBPF 路由脑裂的幕后黑手</title><link>https://besthomelab.tech/en/blog/cilium-coredns/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/cilium-coredns/</guid><pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大家好，我是赛博包工头。欢迎来到赛博工地。&lt;/p&gt;
&lt;p&gt;在咱们上一期对 K3s 故障节点进行了“核弹级强拆”并重新加入集群后，本以为可以顺利盖起 Longhorn 存储大坝了。结果，Longhorn 的核心存储特派员 &lt;code dir=&quot;auto&quot;&gt;longhorn-csi-plugin&lt;/code&gt; 却一直在无限崩溃重启（CrashLoopBackOff）。&lt;/p&gt;
&lt;p&gt;表面上看是存储插件坏了，但经过一顿抽丝剥茧，最后发现：&lt;strong&gt;这根本不是存储的锅，而是一起典型的网络大动脉断裂案！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天这篇排错实录，我们就来复盘一下如何解决这种“查号台还活着，但去查号台的路被炸断了”的底层网络脑裂问题。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-案发现场伪装成存储故障的网络崩塌&quot;&gt;💥 案发现场：伪装成存储故障的网络崩塌&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;当时查看 &lt;code dir=&quot;auto&quot;&gt;longhorn-csi-plugin&lt;/code&gt; 的崩溃遗言（Logs），发现了极其关键的一行报错：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;E0419 00:36:26.346354       1 main.go:167] &quot;Error connecting to CSI driver&quot; err=&quot;context deadline exceeded&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;time=&quot;2026-04-19T00:36:30.790662906Z&quot; level=warning msg=&quot;Failed to initialize Longhorn API client Get \&quot;http://longhorn-backend:9500/v1\&quot;: dial tcp: lookup longhorn-backend on 10.61.0.10:53: read udp 10.60.2.244:53943-&gt;10.61.0.10:53: i/o timeout. Retrying&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;日志翻译：&lt;/strong&gt; Longhorn 插件启动时，需要找集群内部的“114查号台”（CoreDNS，IP 为 &lt;code dir=&quot;auto&quot;&gt;10.61.0.10:53&lt;/code&gt;）去查询总控中心的地址。结果请求发出去后，如同石沉大海，直接报了 &lt;code dir=&quot;auto&quot;&gt;i/o timeout&lt;/code&gt;（连接超时）。因为拿不到总控地址，插件干脆拒绝启动，最后被 Kubelet 当做死进程给毙了。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️️-抽丝剥茧派出侦察兵探路&quot;&gt;🕵️‍♂️ 抽丝剥茧：派出侦察兵探路&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;为了验证是不是真的连不上 DNS，我跑到后台看了一眼 CoreDNS 的状态，发现它分明是 &lt;code dir=&quot;auto&quot;&gt;1/1 Running&lt;/code&gt;，活得好好的，安安稳稳地跑在 &lt;code dir=&quot;auto&quot;&gt;k3s-master-02&lt;/code&gt; 节点上。&lt;/p&gt;
&lt;p&gt;接着，我拉起了一个带 &lt;code dir=&quot;auto&quot;&gt;nslookup&lt;/code&gt; 工具的 &lt;code dir=&quot;auto&quot;&gt;busybox&lt;/code&gt; 侦察兵进行极限测试：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--tty&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;debug-net&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--image=busybox&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--restart=Never&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nslookup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubernetes.default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;返回的结果非常绝望：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;;; connection timed out; no servers could be reached&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;结论：查号台活得好好的，但去找查号台的路，全断了。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-底层逻辑大动脉为什么会断&quot;&gt;🧠 底层逻辑：大动脉为什么会断？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;这要归咎于咱们这套集群的高级架构。&lt;/p&gt;
&lt;p&gt;在安装 K3s 时，我们加上了 &lt;code dir=&quot;auto&quot;&gt;--disable-kube-proxy&lt;/code&gt; 参数。这意味着 Kubernetes 传统的基于 iptables 的内部流量转发机制被废弃了。&lt;strong&gt;全集群的 Service IP（包括内部 DNS 地址 10.61.0.10），全靠 Cilium 的 eBPF 机制在 Linux 内核底层进行拦截和高效转发。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但是！咱们刚才对 &lt;code dir=&quot;auto&quot;&gt;k3s-master-03&lt;/code&gt; 执行了“核弹级强拆”，导致整个集群的 Cilium 路由映射表（BPF Maps）出现了严重的数据断层和脑裂。&lt;/p&gt;
&lt;p&gt;Cilium 彻底迷失了方向，不知道该怎么把 UDP 53 端口的请求跨节点发给 &lt;code dir=&quot;auto&quot;&gt;k3s-master-02&lt;/code&gt; 上的 CoreDNS，于是网络包在内核层直接被无情丢弃。底层网络一断，上层依赖内部域名的 Longhorn 存储插件自然跟着全军覆没。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-抢修方案网络管线大换血&quot;&gt;🛠️ 抢修方案：网络管线“大换血”&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;既然病根在底层的路由表缓存，咱们&lt;strong&gt;不需要重装&lt;/strong&gt;，只需要强制集群对网络管线进行一次&lt;strong&gt;滚动重启（Rollout Restart）&lt;/strong&gt;，让 eBPF 重新绘制整张全网路由表即可。&lt;/p&gt;
&lt;p&gt;请依次执行这&lt;strong&gt;排雷三把斧&lt;/strong&gt;：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第一斧强制重建-cilium-网络映射表&quot;&gt;第一斧：强制重建 Cilium 网络映射表&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;让所有节点的 Cilium 特派员重新扫描集群，重写内核里的路由规则：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ds&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cilium&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(敲完后喝口水等个半分钟，让 3 个节点的 Cilium Pod 挨个重启完成)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第二斧顺手重启查号台-coredns&quot;&gt;第二斧：顺手重启查号台 (CoreDNS)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;为了防止 CoreDNS 本身残留什么僵尸缓存，给它也来一记还我漂漂拳：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rollout&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;restart&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;deploy&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;coredns&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;第三斧再次派出侦察兵验证验收&quot;&gt;第三斧：再次派出侦察兵验证验收&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;等上面的网络和 DNS Pod 都处于 Running 状态后，重新敲一遍之前的测试命令：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;run&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-i&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--tty&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;debug-net&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--image=busybox&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--restart=Never&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nslookup&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kubernetes.default&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;💡 预期结果：&lt;/strong&gt;
只要这次没有报 &lt;code dir=&quot;auto&quot;&gt;timed out&lt;/code&gt;，而是瞬间返回了类似 &lt;code dir=&quot;auto&quot;&gt;Server: 10.61.0.10&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;Address: 10.61.0.10:53&lt;/code&gt; 的解析结果（即便带了 NXDOMAIN 的小 Bug 也不影响），就说明全集群的大动脉彻底打通了！&lt;/p&gt;
&lt;p&gt;大动脉一通，之前卡在 &lt;code dir=&quot;auto&quot;&gt;CrashLoopBackOff&lt;/code&gt; 的 &lt;code dir=&quot;auto&quot;&gt;longhorn-csi-plugin&lt;/code&gt; 就会瞬间找回组织，自动停止报错并挂载成功。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;包工头施工笔记：&lt;/strong&gt;
排查 K8s 故障时，如果上层应用报“连接超时”，不要急着重装应用。拔出网络排错“侦察兵”测一下底层连通性，往往能事半功倍。&lt;strong&gt;“遇到 eBPF 脑裂，一键 Rollout 重启网络插件”&lt;/strong&gt;，这是赛博工地里必须掌握的保命神技！&lt;/p&gt;</content:encoded><category>k3s</category><category>cilium</category><category>longhorn</category><category>kubernetes</category><category>troubleshooting</category></item><item><title>K3s 高可用集群踩坑实录：节点加入失败死锁？四步“核弹级强拆”彻底清理脏数据</title><link>https://besthomelab.tech/en/blog/k3s-reinstall-node/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/k3s-reinstall-node/</guid><pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;大家好，我是赛博包工头。欢迎回到赛博工地。&lt;/p&gt;
&lt;p&gt;最近在给 HomeLab 打 K3s 高可用（HA）集群地基的时候，遇到了一个非常搞心态的坑：&lt;strong&gt;新加入的控制节点（比如 Master 03）死活连不上主集群，一直处于 &lt;code dir=&quot;auto&quot;&gt;NotReady&lt;/code&gt; 或者疯狂重启的状态。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你去查日志（&lt;code dir=&quot;auto&quot;&gt;journalctl -u k3s&lt;/code&gt;），会发现满屏都在刷类似这样的报错：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;rpc error: code = Unavailable desc = connection error: desc = &quot;transport: authentication handshake failed: context deadline exceeded&quot;&lt;/code&gt;
&lt;code dir=&quot;auto&quot;&gt;failed to get etcd status&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多兄弟遇到这种情况，第一反应是：“卸载重装！”
结果跑完官方的卸载脚本，再重新安装，&lt;strong&gt;发现问题依旧，还是同样的报错！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;今天，我们就来扒一扒这个坑的底层原因，并给出一套“挫骨扬灰”级别的强拆重装方案。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-案情分析为什么卸载重装没用&quot;&gt;🔍 案情分析：为什么卸载重装没用？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;罪魁祸首在于：K3s 官方提供的卸载脚本 &lt;code dir=&quot;auto&quot;&gt;/usr/local/bin/k3s-uninstall.sh&lt;/code&gt; &lt;strong&gt;“太温柔了”&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;为了防止用户手残误删掉宝贵的生产数据，这个官方脚本在卸载程序时，&lt;strong&gt;故意保留了 &lt;code dir=&quot;auto&quot;&gt;/var/lib/rancher/k3s&lt;/code&gt; 这个核心数据目录&lt;/strong&gt;（里面存着本地的 ETCD 数据库文件）。&lt;/p&gt;
&lt;p&gt;这就导致了一个致命的逻辑死锁：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;你的节点之前因为某种原因加入集群失败，本地生成了一份残缺或错误的 ETCD 数据。&lt;/li&gt;
&lt;li&gt;你执行了官方卸载脚本，卸载了 K3s 程序。&lt;/li&gt;
&lt;li&gt;你重新执行加入命令。&lt;/li&gt;
&lt;li&gt;新安装的 K3s 程序一启动，&lt;strong&gt;直接读取到了上一波残留的“脏数据”&lt;/strong&gt;。它拿着这套旧的、错误的身份凭证去向主集群报到，立刻又被主集群的安保机制拒之门外，当场死锁崩溃。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以，想要真正重装，我们必须把这台机器上的残骸&lt;strong&gt;彻底炸平&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-终极核弹强拆与重装指南&quot;&gt;🧨 终极核弹强拆与重装指南&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;请严格按照以下 4 步流程操作，&lt;strong&gt;少一步都不行&lt;/strong&gt;。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第一步执行官方卸载停机熄火&quot;&gt;第一步：执行官方卸载（停机熄火）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;首先，在出故障的节点（例如 &lt;code dir=&quot;auto&quot;&gt;Master 03&lt;/code&gt;）上，把 K3s 进程停掉并执行常规卸载：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;/usr/local/bin/k3s-uninstall.sh&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;(如果是 Agent 节点，执行 &lt;code dir=&quot;auto&quot;&gt;/usr/local/bin/k3s-agent-uninstall.sh&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第二步手动清理物理残骸-最关键的一步&quot;&gt;第二步：手动清理物理残骸（🔥 最关键的一步）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;这是官方脚本漏掉的，也是破除死锁的核心。我们必须把它的老巢彻底炸平。
依然在 &lt;strong&gt;故障节点（Master 03）&lt;/strong&gt; 上执行：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-rf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/lib/rancher/k3s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-rf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/rancher/k3s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-rf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/var/lib/kubelet&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;⚠️ 警告：执行完这一步，该节点上的所有 K3s 本地数据将彻底灰飞烟灭，不可恢复。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第三步去主节点注销僵尸户口&quot;&gt;第三步：去主节点注销“僵尸户口”&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;因为 Master 03 之前卡死过，主集群可能还保留着它的“僵尸档案”。为了防止主集群出于安全防范拒绝它重新加入，我们需要去主节点把它踢掉。&lt;/p&gt;
&lt;p&gt;登录到健康的 &lt;strong&gt;主节点（例如 Master 01，10.0.10.10）&lt;/strong&gt;，执行：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-03&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;第四步重新注入灵魂满血复活&quot;&gt;第四步：重新注入灵魂（满血复活）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;现在，Master 03 已经是一张纯洁的白纸，主集群里也没有了它的黑历史。
回到 &lt;strong&gt;故障节点（Master 03）&lt;/strong&gt;，重新粘贴你规划好的&lt;a href=&quot;https://besthomelab.tech/cluster/ha-setup/#-%E6%A0%B8%E5%BF%83%E6%96%BD%E5%B7%A5%E6%B5%81%E7%A8%8B-installation-steps&quot;&gt;加入命令&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-验收施工成果&quot;&gt;🏁 验收施工成果&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;执行完第四步后，在终端里等个大概 30 秒。然后切回你的本地电脑或主节点，敲一下查岗命令：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nodes&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;</content:encoded><category>k3s</category><category>kubernetes</category><category>homelab</category><category>etcd</category><category>troubleshooting</category></item><item><title>PVE 宿主机实战：4T USB 硬盘挂载与 NFS 权限配置指南</title><link>https://besthomelab.tech/en/blog/pve-nfs/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/pve-nfs/</guid><pubDate>Fri, 17 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在 PVE 环境中，将大容量 USB 硬盘挂载至宿主机并开启 NFS 共享，是实现跨虚拟机数据共享的高效方案。但在实际操作中，磁盘识别错误会导致数据丢失，网段配置不当会导致访问受阻。本文记录了从底层格式化到权限调优的标准流程。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;一-物理硬盘初始化&quot;&gt;一、 物理硬盘初始化&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;1-确认硬盘标识极重要&quot;&gt;1. 确认硬盘标识（极重要）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;在执行任何格式化操作前，必须核对物理磁盘。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;lsblk&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 观察磁盘容量（如 3.7T）和类型。通常系统盘为 &lt;code dir=&quot;auto&quot;&gt;sda&lt;/code&gt;，外挂盘可能为 &lt;code dir=&quot;auto&quot;&gt;sdb&lt;/code&gt; 或 &lt;code dir=&quot;auto&quot;&gt;sdc&lt;/code&gt;。请在后续步骤中将 &lt;code dir=&quot;auto&quot;&gt;/dev/sdb&lt;/code&gt; 替换为你实际识别到的磁盘代号。&lt;strong&gt;一旦选错，数据将不可恢复。&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2-创建分区与格式化&quot;&gt;2. 创建分区与格式化&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;对于超过 2T 的硬盘，必须使用 GPT 分区表：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 使用 fdisk 工具（以 /dev/sdb 为例，请按实际修改）&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;fdisk&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/dev/sdb&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 交互指令：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 输入 g (创建 GPT 分区表)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 输入 n (创建新分区，起始和结束扇区均按回车保持默认)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 输入 w (写入并退出)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 格式化分区为 ext4&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mkfs.ext4&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/dev/sdb1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-实现持久化挂载&quot;&gt;3. 实现持久化挂载&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;使用 UUID 挂载可以防止 USB 插拔后驱动器路径改变。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 获取 UUID&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;blkid&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/dev/sdb1&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 记录 UUID=&quot;xxxxxxxx-xxxx-...&quot; 部分&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 创建挂载点&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-p&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/mnt/nfs&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 修改系统挂载表&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;nano&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/etc/fstab&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 在末尾添加（替换为你实际的 UUID）：&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;UUID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;你的UUID&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;/mnt/nfs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;ext4&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;defaults&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 生效挂载&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;mount&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-a&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;二-nfs-服务安装与核心权限配置&quot;&gt;二、 NFS 服务安装与核心权限配置&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;1-安装服务&quot;&gt;1. 安装服务&lt;/h3&gt;&lt;/div&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;update&lt;/span&gt;&lt;span&gt; &amp;#x26;&amp;#x26; &lt;/span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-y&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nfs-kernel-server&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-配置共享权限etcexports&quot;&gt;2. 配置共享权限（/etc/exports）&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;编辑配置文件：&lt;code dir=&quot;auto&quot;&gt;nano /etc/exports&lt;/code&gt;，添加如下配置：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;/mnt/nfs 10.0.0.0/16(rw,sync,no_subtree_check,no_root_squash,insecure)&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h4 id=&quot;-参数详解与调整说明&quot;&gt;💡 参数详解与调整说明：&lt;/h4&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;网段地址 (10.0.0.0/16)&lt;/strong&gt;：
&lt;strong&gt;必须按实际修改&lt;/strong&gt;。这里的地址定义了谁能访问此共享。
&lt;ul&gt;
&lt;li&gt;如果你的 IP 是 &lt;code dir=&quot;auto&quot;&gt;192.168.1.x&lt;/code&gt;，请填入 &lt;code dir=&quot;auto&quot;&gt;192.168.1.0/24&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;使用 &lt;code dir=&quot;auto&quot;&gt;/16&lt;/code&gt; 掩码（如 &lt;code dir=&quot;auto&quot;&gt;10.0.0.0/16&lt;/code&gt;）可以覆盖 &lt;code dir=&quot;auto&quot;&gt;10.0.x.x&lt;/code&gt; 范围内的所有 IP，适合多子网环境。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;insecure&lt;/code&gt; (关键)&lt;/strong&gt;：
默认 NFS 要求客户端使用 1024 以下端口，而 Kubernetes/K3s 等容器化平台挂载时常使用高位随机端口。&lt;strong&gt;不加此参数会导致 &lt;code dir=&quot;auto&quot;&gt;Access Denied&lt;/code&gt;。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code dir=&quot;auto&quot;&gt;no_root_squash&lt;/code&gt;&lt;/strong&gt;：
允许客户端以 root 权限写入，这对于需要持久化存储的应用（如数据库、媒体库）至关重要。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;三-服务生效与状态验收&quot;&gt;三、 服务生效与状态验收&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;修改配置后必须手动刷新导出表：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 强制重新导出所有路径&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;exportfs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-ra&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 查看当前生效的完整配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;exportfs&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-v&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;验收标准：&lt;/strong&gt;
在 &lt;code dir=&quot;auto&quot;&gt;exportfs -v&lt;/code&gt; 的输出中，确认包含了你设置的路径和网段，并且权限列表中出现了 &lt;code dir=&quot;auto&quot;&gt;insecure&lt;/code&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;运维建议&quot;&gt;运维建议&lt;/h2&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;磁盘休眠&lt;/strong&gt;：部分 USB 硬盘盒会自动进入休眠，可能导致 Pod 首次挂载超时。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络防火墙&lt;/strong&gt;：若挂载失败，请检查 PVE 节点是否开启了数据中心防火墙，确保 &lt;strong&gt;2049&lt;/strong&gt; 端口已对目标网段放行。&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>pve</category><category>nfs</category><category>storage</category><category>linux</category><category>homelab</category></item><item><title>彻底清理并重新部署 Portainer：解决存储与权限冲突</title><link>https://besthomelab.tech/en/blog/portainer-reinstall/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/portainer-reinstall/</guid><pubDate>Fri, 17 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在通过 Helm 将 Portainer 的底层存储从 &lt;code dir=&quot;auto&quot;&gt;local-path&lt;/code&gt; 更改为 &lt;code dir=&quot;auto&quot;&gt;longhorn&lt;/code&gt; 时，直接执行 &lt;code dir=&quot;auto&quot;&gt;helm upgrade&lt;/code&gt; 通常会导致升级失败。这主要由以下三个原因造成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;PVC Immutable 报错&lt;/strong&gt;：Kubernetes 规范限制了已绑定 PVC 的 &lt;code dir=&quot;auto&quot;&gt;storageClassName&lt;/code&gt; 是不可变的，不能直接修改覆盖。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全局权限冲突&lt;/strong&gt;：Helm 尝试创建全局的 &lt;code dir=&quot;auto&quot;&gt;ClusterRoleBinding&lt;/code&gt; 时，会因为系统中存在历史安装遗留的同名资源而报错。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手动资源残留&lt;/strong&gt;：通过 &lt;code dir=&quot;auto&quot;&gt;kubectl apply&lt;/code&gt; 手动创建的 Service（例如手动配置的 LoadBalancer）不在 Helm 的管理范围内，&lt;code dir=&quot;auto&quot;&gt;helm uninstall&lt;/code&gt; 不会自动将其回收。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;为了保证新配置能够顺利应用，必须先彻底清理命名空间下的所有关联资源，然后执行干净的重装。以下是完整的操作步骤。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;第一阶段彻底清理残留资源&quot;&gt;第一阶段：彻底清理残留资源&lt;/h2&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意：&lt;/strong&gt; 执行以下清理命令将删除该节点上 Portainer 的所有历史数据。请在操作前确认数据已备份或不再需要。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;h3 id=&quot;1-卸载-helm-发布版本&quot;&gt;1. 卸载 Helm 发布版本&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;首先，通过 Helm 卸载现有的 Portainer 实例：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uninstall&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-删除命名空间下的所有资源及-pvc&quot;&gt;2. 删除命名空间下的所有资源及 PVC&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;由于 Helm 卸载操作会保留 PVC 以及未被其管理的手动资源，需要使用以下命令强制清空 &lt;code dir=&quot;auto&quot;&gt;portainer&lt;/code&gt; 命名空间：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pvc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;--all&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;3-清理全局权限绑定&quot;&gt;3. 清理全局权限绑定&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;&lt;code dir=&quot;auto&quot;&gt;ClusterRole&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;ClusterRoleBinding&lt;/code&gt; 是集群级别的资源，不包含在特定命名空间内。需要手动删除它们以解决后续的权限冲突报错：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrolebinding&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;clusterrole&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;4-验证清理结果&quot;&gt;4. 验证清理结果&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;执行以下命令检查命名空间，确认环境已完全清空：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;all,pvc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;正常情况下，终端应返回：&lt;code dir=&quot;auto&quot;&gt;No resources found in portainer namespace.&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;第二阶段执行全新安装&quot;&gt;第二阶段：执行全新安装&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;环境清理完毕后，使用配置好 Longhorn 存储的 &lt;code dir=&quot;auto&quot;&gt;portainer-values.yaml&lt;/code&gt; 文件重新执行 Helm 安装命令：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;install&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer/portainer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;--create-namespace&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;--set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;persistence.storageClass=longhorn&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;--set&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;nodeSelector=null&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;\&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer-values.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;第三阶段验证部署与恢复服务&quot;&gt;第三阶段：验证部署与恢复服务&lt;/h2&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;1-检查集群资源状态&quot;&gt;1. 检查集群资源状态&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;安装完成后，检查 Pod 和 PVC 的状态。确认 PVC 已经绑定到 &lt;code dir=&quot;auto&quot;&gt;longhorn&lt;/code&gt;，并且 Pod 处于 &lt;code dir=&quot;auto&quot;&gt;Running&lt;/code&gt; 状态：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pods,pvc,svc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;wide&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;2-恢复手动创建的-service-视情况执行&quot;&gt;2. 恢复手动创建的 Service (视情况执行)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;如果你之前的外网访问依赖于手动创建的 Service（例如名为 &lt;code dir=&quot;auto&quot;&gt;portainer-lb-manual&lt;/code&gt; 的资源），并且该配置没有整合进 Helm 的 &lt;code dir=&quot;auto&quot;&gt;values.yaml&lt;/code&gt; 中，你需要重新应用该配置文件来恢复服务的对外暴露：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 请将文件名替换为你实际使用的 yaml 文件&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;apply&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-f&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;portainer-lb-manual.yaml&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;执行完毕后，即可通过分配的 IP 地址访问 Portainer 并完成初始管理员密码的设置。&lt;/p&gt;</content:encoded><category>k3s</category><category>kubernetes</category><category>helm</category><category>portainer</category><category>longhorn</category></item><item><title>架构师的外科手术：破解 kube-vip 启动死循环</title><link>https://besthomelab.tech/en/blog/kube-vip-startup-deadlock/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/kube-vip-startup-deadlock/</guid><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;前置联动说明&lt;/strong&gt;
本文是对 &lt;a href=&quot;https://besthomelab.tech/cluster/ha-setup/&quot;&gt;K3s 高可用集群浇筑 (HA Setup)&lt;/a&gt; 章节中“补丁 2”配置的深度原理解析。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;🕵️ 发现异常&lt;/strong&gt;：如果不加该补丁，仅照抄基础部署清单，&lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 容器会无限 CrashLoopBackOff，日志疯狂报错 &lt;code dir=&quot;auto&quot;&gt;Timeout&lt;/code&gt;（连接 API Server 超时）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🧠 根本原因&lt;/strong&gt;：底层网络插件（Cilium）未完全就绪，或者 Kube-proxy 被卸载时，组件向集群内部虚拟 IP（10.61.0.1）寻址产生的“先有鸡还是先有蛋”的死循环。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;🛠️ 解决方案&lt;/strong&gt;：通过注入宿主机物理回环地址 (&lt;code dir=&quot;auto&quot;&gt;127.0.0.1&lt;/code&gt;) 强行搭桥，实现控制面与虚拟网络的彻底解耦。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;在打造这套赛博堡垒的高可用地基时，如果直接照搬基础的部署清单，我们大概率会在 &lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 的启动阶段摔得头破血流。今天，包工头就带你从底层扒开这个“补丁”的硬核逻辑，复盘我们是如何斩断这个死循环的。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-灾难复盘为什么会疯狂-timeout&quot;&gt;💣 灾难复盘：为什么会疯狂 Timeout？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在默认情况下，Kubernetes 集群里的任何 Pod（包括 &lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt;）想要呼叫“总部”（API Server），都会去请求一个内部的虚拟 IP（比如我们配置的 &lt;code dir=&quot;auto&quot;&gt;10.61.0.1&lt;/code&gt; 这个 ClusterIP）。&lt;/p&gt;
&lt;p&gt;但这就产生了一个致命的&lt;strong&gt;死循环&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 启动了，它需要和另外两台机器商量谁当“带头大哥”（Leader Election），这必须读写 API Server 的数据。&lt;/li&gt;
&lt;li&gt;于是 &lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 向上级汇报，把请求发给了虚拟网关 &lt;code dir=&quot;auto&quot;&gt;10.61.0.1&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;但是！&lt;/strong&gt; 此时底层的 Cilium 网络插件可能正在重启，或者还没完全就绪；又或者我们在浇筑阶段强行卸载了 &lt;code dir=&quot;auto&quot;&gt;kube-proxy&lt;/code&gt;，导致这个虚拟 IP &lt;code dir=&quot;auto&quot;&gt;10.61.0.1&lt;/code&gt; 根本没人给它做底层转发。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;结果&lt;/strong&gt;：&lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 找不到总部，一直苦苦等待响应，最后只能抛出绝望的 &lt;strong&gt;Timeout&lt;/strong&gt; 并崩溃重启。大门失守，高可用形同虚设。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-破局之法精准搭桥-外科手术&quot;&gt;🗝️ 破局之法：精准搭桥 (外科手术)&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;为了打破这个死循环，我们在 &lt;code dir=&quot;auto&quot;&gt;kube-vip.yaml&lt;/code&gt; 中通过 &lt;code dir=&quot;auto&quot;&gt;sed&lt;/code&gt; 命令强行注入了这两行环境变量：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;KUBERNETES_SERVICE_HOST&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;127.0.0.1&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;- &lt;/span&gt;&lt;span&gt;name&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;KUBERNETES_SERVICE_PORT&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;&quot;6443&quot;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;这两行代码到底干了啥&quot;&gt;这两行代码到底干了啥？&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;它的作用，就是&lt;strong&gt;给 &lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 塞了一张“本地特权 VIP 通行证”！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由于我们在部署时声明了 &lt;code dir=&quot;auto&quot;&gt;--inCluster&lt;/code&gt; 并开启了 &lt;code dir=&quot;auto&quot;&gt;hostNetwork: true&lt;/code&gt;（共享宿主机网络），当我们强制注入 &lt;code dir=&quot;auto&quot;&gt;127.0.0.1&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;6443&lt;/code&gt; 后，&lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 就不再去那个虚无缥缈的 &lt;code dir=&quot;auto&quot;&gt;10.61.0.1&lt;/code&gt; 绕弯子了。&lt;/p&gt;
&lt;p&gt;它会直接“敲隔壁的门”——&lt;strong&gt;通过主机的本地回环网卡（Localhost），呼叫本台物理机上正在运行的 K3s API Server！&lt;/strong&gt; 管你底层的 Cilium 瘫没瘫痪，管你 K8s 的虚拟网络通没通，我们走的是物理机的地下通道，绝对畅通无阻！这相当于给我们的赛博堡垒建立了一条&lt;strong&gt;最高安全级别的消防通道&lt;/strong&gt;。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;总结&quot;&gt;总结&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;我们的 &lt;code dir=&quot;auto&quot;&gt;KUBERNETES_SERVICE_HOST&lt;/code&gt; 注入是在做&lt;strong&gt;精密的外科手术&lt;/strong&gt;。通过注入本地回环地址，实现控制面组件与虚拟网络的硬解耦，彻底斩断网络启动期的死循环锁。&lt;/p&gt;</content:encoded><category>k3s</category><category>kubernetes</category><category>architecture</category><category>troubleshooting</category><category>guide</category></item><item><title>赛博工地的“五分钟定律”：揭秘节点宕机后的 Pod 驱逐真相</title><link>https://besthomelab.tech/en/blog/k3s-pod-eviction-timeout/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/k3s-pod-eviction-timeout/</guid><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;&lt;h2 id=&quot;-案发现场消失的-headlamp&quot;&gt;🚨 案发现场：消失的 Headlamp&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;在我们的 K3s 高可用堡垒中，我进行了一次“暴力断电”演习：直接关掉了 &lt;code dir=&quot;auto&quot;&gt;k3s-master-03&lt;/code&gt; 节点。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;当时的情况如下：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;业务中断&lt;/strong&gt;：原本运行在 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt; 节点上的 &lt;code dir=&quot;auto&quot;&gt;Headlamp&lt;/code&gt;（单副本）瞬间无法访问。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;状态迷惑&lt;/strong&gt;：控制台输入 &lt;code dir=&quot;auto&quot;&gt;kubectl get pods -o wide&lt;/code&gt;，发现该 Pod 居然还显示为 &lt;code dir=&quot;auto&quot;&gt;Running&lt;/code&gt;，且依然赖在已经失联的 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt; 节点上。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;没有漂移&lt;/strong&gt;：想象中的“毫秒级瞬移到其他节点”并没有发生。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种“僵尸 Pod”现象并非 Bug，而是触发了 Kubernetes 调度架构中极其核心的机制：&lt;strong&gt;基于污点的驱逐（Taint-based Eviction）与五分钟定律&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;📖 &lt;strong&gt;官方原典参考&lt;/strong&gt;：本文底层逻辑均来源于 &lt;a href=&quot;https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/taint-and-toleration/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Kubernetes 官方文档：污点和容忍度&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-核心概念与实盘求证&quot;&gt;🛡️ 核心概念与实盘求证&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;要理解这五分钟，必须先看懂 K8s 官方定义的一对博弈属性，我们直接用命令在案发现场求证：&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;1-污点-taint--节点的逐客令&quot;&gt;1. 污点 (Taint) —— 节点的“逐客令”&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;当 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt; 节点断电失联时，K8s 控制面会迅速给该节点打上严厉的污点。
&lt;strong&gt;🕵️ 求证指令：我们怎么确定节点真的被打上污点了？&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 查看 03 节点的污点状态&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;describe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;node&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-03&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Taints&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;输出结果&lt;/strong&gt;：你会看到 &lt;code dir=&quot;auto&quot;&gt;Taints: node.kubernetes.io/not-ready:NoExecute, node.kubernetes.io/unreachable:NoExecute&lt;/code&gt;。
这就是节点的逐客令。&lt;code dir=&quot;auto&quot;&gt;NoExecute&lt;/code&gt; 效果意味着：不仅新 Pod 不能来，已经在上面的 Pod 必须立刻被驱逐！&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;2-容忍度-toleration--pod-的特权通行证&quot;&gt;2. 容忍度 (Toleration) —— Pod 的“特权通行证”&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;面对驱逐令，Pod 能否抗旨？这就看它自身有没有配置对应的容忍度。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-破案这-300-秒是从哪来的&quot;&gt;🕵️ 破案：这 300 秒是从哪来的？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;既然污点是 &lt;code dir=&quot;auto&quot;&gt;NoExecute&lt;/code&gt; (立刻驱逐)，为什么 Headlamp 还能在上面赖 5 分钟？这是因为 API Server 在创建普通 Pod 时，&lt;strong&gt;默认、悄悄地给它们注入了限时的容忍度。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;🕵️ 求证指令：抓出 Pod 身上被暗中注入的“宽限期”&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 查看 Headlamp 这个 Pod 的详细配置&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;describe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;&amp;#x3C;你的-headlamp-pod-名字&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-A&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Tolerations&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;输出结果&lt;/strong&gt;：你会赫然发现这样两行配置：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;node.kubernetes.io/not-ready:NoExecute op=Exists for 300s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;node.kubernetes.io/unreachable:NoExecute op=Exists for 300s&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;官方文档解读&lt;/strong&gt;：“这些自动添加的容忍度意味着 Pod 可以在检测到对应的问题之一时，在 5 分钟内保持绑定在该节点上。”
即：长官让我滚，但我有 300 秒的宽限期。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-架构思考daemonset-为什么永远不漂移&quot;&gt;🏗️ 架构思考：DaemonSet 为什么永远不漂移？&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;像 &lt;code dir=&quot;auto&quot;&gt;Cilium&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;kube-vip&lt;/code&gt; 这类组件，即便过了 5 分钟也不会去别的节点重新拉起。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;🕵️ 求证指令：看看 DaemonSet 的容忍度有何不同？&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;# 使用 -A 10 确保能把 DaemonSet 身上长长的一串特权全打印出来&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;describe&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/name=kube-vip-ds&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-A&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;Tolerations&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;输出结果&lt;/strong&gt;：你会发现它们也有 &lt;code dir=&quot;auto&quot;&gt;not-ready&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;unreachable&lt;/code&gt; 的容忍度，&lt;strong&gt;但是没有 &lt;code dir=&quot;auto&quot;&gt;for 300s&lt;/code&gt; 这个时间限制！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;官方文档明确指出：“DaemonSet 中的 Pod 被创建时，针对不可达污点添加的 &lt;code dir=&quot;auto&quot;&gt;NoExecute&lt;/code&gt; 容忍度，&lt;strong&gt;将不会指定 tolerationSeconds&lt;/strong&gt;。这保证了出现上述问题时 DaemonSet 永远不会被驱逐。”&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-极客进阶掌控驱逐倒计时的快与慢&quot;&gt;⚡ 极客进阶：掌控驱逐倒计时的“快与慢”&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;作为集群的架构师，你可以通过在 YAML 的 &lt;code dir=&quot;auto&quot;&gt;spec.tolerations&lt;/code&gt; 中显式声明，来&lt;strong&gt;覆盖&lt;/strong&gt;这默认的 300 秒：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;场景 A（无状态前端）&lt;/strong&gt;：想让面板瞬间漂移？配置 &lt;code dir=&quot;auto&quot;&gt;tolerationSeconds: 30&lt;/code&gt;。&lt;em&gt;(警告：容易引发网络抖动时的重建风暴)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;场景 B（有状态存储）&lt;/strong&gt;：数据库绑了本地硬盘？必须延长保命！配置 &lt;code dir=&quot;auto&quot;&gt;tolerationSeconds: 6000&lt;/code&gt; 死等网络恢复。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-总结与施工建议&quot;&gt;🛠️ 总结与施工建议&lt;/h2&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;架构侧&lt;/strong&gt;：核心业务增加副本数（Replicas &gt;= 2）配合反亲和性，是应对这 5 分钟断档期的最优雅解法。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应急侧&lt;/strong&gt;：演练时不想等待？直接执行强制抹除：&lt;code dir=&quot;auto&quot;&gt;kubectl delete pod &amp;#x3C;POD_NAME&gt; -n &amp;#x3C;NAMESPACE&gt; --force --grace-period=0&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;排查侧&lt;/strong&gt;：想要系统性掌握这套机制的排查手法？👉 &lt;strong&gt;&lt;a href=&quot;https://besthomelab.tech/cluster/ops/k3s-taints-tolerations-ops&quot;&gt;点击查看《赛博工地巡检手册：污点与容忍度排查指令集》&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded><category>k3s</category><category>kubernetes</category><category>scheduling</category><category>high-availability</category><category>troubleshooting</category></item><item><title>赛博赶羊战术：不改 YAML 强制定向调度 Pod</title><link>https://besthomelab.tech/en/blog/06-k3s-cordon-trick/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/06-k3s-cordon-trick/</guid><pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;在赛博堡垒的日常巡检中，我们偶尔会萌生一些“非分之想”：&lt;strong&gt;我想把正在运行的 Headlamp 面板，强行从 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 节点挪到 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt; 节点上去。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;按照正规军的做法，我们应该去修改 Deployment 的 YAML 文件，加上 &lt;code dir=&quot;auto&quot;&gt;nodeSelector&lt;/code&gt; 或节点亲和性。但如果这仅仅是一次临时测试，为了这么点小事去改核心图纸，未免太兴师动众。如果给 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;02&lt;/code&gt; 节点打 &lt;code dir=&quot;auto&quot;&gt;NoSchedule&lt;/code&gt; 污点，又会像“核弹打蚊子”一样误伤集群里的其他无辜业务。&lt;/p&gt;
&lt;p&gt;今天，包工头教你一招极客圈里经典的“障眼法”——&lt;strong&gt;利用节点封锁 (Cordon) 机制的“赛博赶羊战术”&lt;/strong&gt;。&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;-战术核心关上多余的门只留一条路&quot;&gt;🐑 战术核心：关上多余的门，只留一条路&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;Kubernetes 提供了一个专门用于节点临时维护的命令：&lt;code dir=&quot;auto&quot;&gt;kubectl cordon&lt;/code&gt;（封锁）。
当节点被 Cordon 后，它会被打上 &lt;code dir=&quot;auto&quot;&gt;SchedulingDisabled&lt;/code&gt; 的标记。这就像给节点挂上了“暂停营业”的牌子：已经在里面吃饭的顾客（运行中的 Pod）不受影响，但绝对不接待新客（新创建的 Pod 无法调度进来）。&lt;/p&gt;
&lt;p&gt;我们的战术逻辑极其简单：&lt;strong&gt;把不想去的节点全封锁，然后把 Pod 杀掉让它重生。K8s 大脑环顾四周发现只有一台节点“开着门”，就只能乖乖把 Pod 丢进去。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-实机演练四步微操指南&quot;&gt;🛠️ 实机演练：四步微操指南&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;假设我们要把 &lt;code dir=&quot;auto&quot;&gt;kube-system&lt;/code&gt; 命名空间下的 &lt;code dir=&quot;auto&quot;&gt;Headlamp&lt;/code&gt; 强行赶到 &lt;code dir=&quot;auto&quot;&gt;k3s-master-03&lt;/code&gt; 节点。&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第一步封锁非目标节点-关门&quot;&gt;第一步：封锁非目标节点 (关门)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;我们要逼迫目标去 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt;，所以先把 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;02&lt;/code&gt; 的大门焊死：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;cordon&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-01&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-02&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;验证：此时敲击 &lt;code dir=&quot;auto&quot;&gt;kubectl get nodes&lt;/code&gt;，你会看到 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;02&lt;/code&gt; 的 STATUS 变成了 &lt;code dir=&quot;auto&quot;&gt;Ready,SchedulingDisabled&lt;/code&gt;。&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第二步击杀当前-pod-放狗咬羊&quot;&gt;第二步：击杀当前 Pod (放狗咬羊)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;直接删掉当前正在运行的 Headlamp Pod。由于它是由 Deployment 管理的，K8s 会瞬间拉起一个新的替代品。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;delete&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-l&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;app.kubernetes.io/name=headlamp&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;div&gt;&lt;h3 id=&quot;第三步查收战果&quot;&gt;第三步：查收战果&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;去看看新重生的 Headlamp 落在哪了：&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;get&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;pods&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-n&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;kube-system&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;wide&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;grep&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;headlamp&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;因为大脑别无选择，你会发现新的 Pod 已经精准无误地降落在了 &lt;code dir=&quot;auto&quot;&gt;k3s-master-03&lt;/code&gt; 上！微操成功！&lt;/em&gt;&lt;/p&gt;
&lt;div&gt;&lt;h3 id=&quot;第四步光速解除封锁-极其重要&quot;&gt;第四步：光速解除封锁 (极其重要！)&lt;/h3&gt;&lt;/div&gt;
&lt;p&gt;羊已经进圈了，赶紧把 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 和 &lt;code dir=&quot;auto&quot;&gt;02&lt;/code&gt; 的大门重新打开，否则你后续部署的任何新业务都会因为找不到节点而卡在 &lt;code dir=&quot;auto&quot;&gt;Pending&lt;/code&gt; 状态。&lt;/p&gt;
&lt;div&gt;&lt;figure&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;uncordon&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-01&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;k3s-master-02&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;&lt;/div&gt;
&lt;p&gt;&lt;em&gt;验证：再次 &lt;code dir=&quot;auto&quot;&gt;kubectl get nodes&lt;/code&gt;，&lt;code dir=&quot;auto&quot;&gt;SchedulingDisabled&lt;/code&gt; 标记消失，集群恢复常态。&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;div&gt;&lt;h2 id=&quot;️-架构师的灵魂拷问&quot;&gt;⚠️ 架构师的灵魂拷问&lt;/h2&gt;&lt;/div&gt;
&lt;p&gt;虽然这套连招玩起来行云流水，极其酷炫，但我必须提醒你：&lt;strong&gt;它终究是一张“体验卡”。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Kubernetes 的核心信仰是&lt;strong&gt;声明式架构(Declarative)&lt;/strong&gt;。Cordon 大法只是一次性欺骗了调度器。如果明天 &lt;code dir=&quot;auto&quot;&gt;03&lt;/code&gt; 节点重启了，或者 Headlamp 意外崩溃了，K8s 大脑在重新调度时，面对三扇全开的大门，依然会随机把 Headlamp 扔回 &lt;code dir=&quot;auto&quot;&gt;01&lt;/code&gt; 或 &lt;code dir=&quot;auto&quot;&gt;02&lt;/code&gt;。系统并没有记住你的真实意图。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;总结：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;临时测试、排查干扰&lt;/strong&gt;：用 Cordon 大法，干净利落。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;永久固化、生产要求&lt;/strong&gt;：请务必遵守纪律，老老实实去写 &lt;code dir=&quot;auto&quot;&gt;nodeSelector&lt;/code&gt; 或 &lt;code dir=&quot;auto&quot;&gt;nodeAffinity&lt;/code&gt;。这才是让 Tech Fortress 坚不可摧的终极规范。&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>k3s</category><category>kubernetes</category><category>scheduling</category><category>tips</category><category>ops</category></item><item><title>blog1</title><link>https://besthomelab.tech/en/blog/blog-test/</link><guid isPermaLink="true">https://besthomelab.tech/en/blog/blog-test/</guid><pubDate>Sat, 21 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“所谓的高可用，就是当你拔掉电源的时候，它确实不可用了。”&lt;/strong&gt; &gt; 欢迎来到赛博工地的最底层。这里没有优雅的代码，只有嗡嗡作响的散热风扇、错综复杂的网线，以及用金钱堆砌起来的虚假安全感。&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded><category>pve</category></item></channel></rss>