<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>证书轮换 on Zero Day Notes</title>
        <link>https://blog.5772447.xyz/tags/%E8%AF%81%E4%B9%A6%E8%BD%AE%E6%8D%A2/</link>
        <description>Recent content in 证书轮换 on Zero Day Notes</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh</language>
        <lastBuildDate>Fri, 11 Sep 2026 07:00:00 +0800</lastBuildDate><atom:link href="https://blog.5772447.xyz/tags/%E8%AF%81%E4%B9%A6%E8%BD%AE%E6%8D%A2/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>记一次 K8s 节点 kubelet 证书轮换失败导致节点 NotReady 风暴的排查</title>
            <link>https://blog.5772447.xyz/posts/e01939e6/</link>
            <pubDate>Fri, 11 Sep 2026 07:00:00 +0800</pubDate>
            <guid>https://blog.5772447.xyz/posts/e01939e6/</guid>
            <description>&lt;h1 id=&#34;问题背景&#34;&gt;&lt;a href=&#34;#%e9%97%ae%e9%a2%98%e8%83%8c%e6%99%af&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;问题背景&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;生产 K8s 集群（v1.28）运行约 18 个月，节点总数 42 台。近期因安全合规要求，计划将 kubelet 客户端证书有效期从默认 1 年缩短至 90 天，并开启 &lt;code&gt;rotateCertificates: true&lt;/code&gt; 自动轮换。变更后第 3 天凌晨，监控突然告警：&lt;strong&gt;12 台节点同时进入 NotReady 状态&lt;/strong&gt;，持续约 47 分钟后才陆续恢复。业务 Pod 因节点 NotReady 被驱逐，部分有状态服务短暂中断。&lt;/p&gt;&#xA;&lt;h1 id=&#34;故障现象&#34;&gt;&lt;a href=&#34;#%e6%95%85%e9%9a%9c%e7%8e%b0%e8%b1%a1&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;故障现象&#xD;&#xA;&lt;/h1&gt;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;kubectl get nodes&lt;/code&gt; 显示 12 台节点 Condition &lt;code&gt;Ready&lt;/code&gt; 为 &lt;code&gt;False&lt;/code&gt;，Reason &lt;code&gt;KubeletNotReady&lt;/code&gt;，Message 包含 &lt;code&gt;x509: certificate has expired or is not yet valid&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;受影响节点全部为「老节点」（kubelet 启动时间 &amp;gt; 400 天），新节点（近 3 个月上线的）全部正常。&lt;/li&gt;&#xA;&lt;li&gt;apiserver 日志出现大量 &lt;code&gt;authentication.go: Failed to verify client certificate&lt;/code&gt; 错误，对应节点 kubelet 连接被拒绝。&lt;/li&gt;&#xA;&lt;li&gt;节点上 &lt;code&gt;journalctl -u kubelet&lt;/code&gt; 可见：&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;certificate rotation failed: x509: certificate signed by unknown authority&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;server returned error: x509: certificate has expired or is not yet valid&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;集群层面 &lt;code&gt;kubelet_server_expiration_renew_errors&lt;/code&gt; 指标在故障窗口内突增。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h1 id=&#34;排查过程&#34;&gt;&lt;a href=&#34;#%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;排查过程&#xD;&#xA;&lt;/h1&gt;&lt;h2 id=&#34;1-确认证书状态&#34;&gt;&lt;a href=&#34;#1-%e7%a1%ae%e8%ae%a4%e8%af%81%e4%b9%a6%e7%8a%b6%e6%80%81&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;1. 确认证书状态&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;在故障节点执行：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubelet --version&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ls -l /var/lib/kubelet/pki/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates -issuer&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;发现：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;kubelet-client-current.pem&lt;/code&gt; 指向的实际文件 &lt;code&gt;kubelet-client-2025-06-12-10.pem&lt;/code&gt; 过期时间为 &lt;strong&gt;2026-06-12&lt;/strong&gt;（已过期 91 天）。&lt;/li&gt;&#xA;&lt;li&gt;Issuer 为集群自签 CA &lt;code&gt;kubelet-bootstrap-ca@162xxxx&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;目录下还存在 3 个历史证书文件，最新一个也是 2025-06-12 生成。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;2-检查-kubelet-配置&#34;&gt;&lt;a href=&#34;#2-%e6%a3%80%e6%9f%a5-kubelet-%e9%85%8d%e7%bd%ae&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;2. 检查 kubelet 配置&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;关键配置 &lt;code&gt;/var/lib/kubelet/config.yaml&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;rotateCertificates&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;serverTLSBootstrap&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;code&gt;rotateCertificates: true&lt;/code&gt; 已开启，但 &lt;code&gt;serverTLSBootstrap&lt;/code&gt; 为 false（默认）。&lt;/p&gt;&#xA;&lt;p&gt;进一步检查 kubelet 启动参数：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ps aux | grep kubelet | grep -E &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;bootstrap-kubeconfig|kubeconfig&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;发现节点使用的是&lt;strong&gt;静态 kubeconfig&lt;/strong&gt;（&lt;code&gt;/etc/kubernetes/kubelet.conf&lt;/code&gt;），而非 TLS Bootstrapping 流程生成的 &lt;code&gt;bootstrap-kubeconfig&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;3-对比正常节点与故障节点&#34;&gt;&lt;a href=&#34;#3-%e5%af%b9%e6%af%94%e6%ad%a3%e5%b8%b8%e8%8a%82%e7%82%b9%e4%b8%8e%e6%95%85%e9%9a%9c%e8%8a%82%e7%82%b9&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;3. 对比正常节点与故障节点&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;正常节点（近 3 个月上线）：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;使用 &lt;code&gt;kubeadm init&lt;/code&gt; 时自动生成的 bootstrap token + &lt;code&gt;bootstrap-kubeconfig&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;kubelet 启动参数包含 &lt;code&gt;--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubeconfig&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;证书轮换成功，当前证书有效期至 2026-12-01。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;故障节点（老节点）：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;早期使用 &lt;code&gt;kubeadm join --token xxx&lt;/code&gt; 一次性加入，kubeconfig 写死在 &lt;code&gt;/etc/kubernetes/kubelet.conf&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;没有 &lt;code&gt;bootstrap-kubeconfig&lt;/code&gt;，&lt;code&gt;kubelet.conf&lt;/code&gt; 中的 client-certificate 直接指向过期文件。&lt;/li&gt;&#xA;&lt;li&gt;即使 &lt;code&gt;rotateCertificates: true&lt;/code&gt;，kubelet 也无法触发「续期请求」，因为它不知道去哪里申请新证书。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;4-根因定位&#34;&gt;&lt;a href=&#34;#4-%e6%a0%b9%e5%9b%a0%e5%ae%9a%e4%bd%8d&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;4. 根因定位&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;核心矛盾&lt;/strong&gt;：&lt;code&gt;rotateCertificates&lt;/code&gt; 依赖 TLS Bootstrapping 流程，而老节点从未配置过 bootstrap token + &lt;code&gt;bootstrap-kubeconfig&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;当原 client 证书过期后：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;kubelet 尝试用过期证书连接 apiserver → 认证失败。&lt;/li&gt;&#xA;&lt;li&gt;即使配置了 &lt;code&gt;rotateCertificates: true&lt;/code&gt;，kubelet 也无法构造合法的 CSR 请求（因为连 apiserver 都连不上）。&lt;/li&gt;&#xA;&lt;li&gt;节点进入 NotReady → 触发 Pod 驱逐 → 雪崩。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h1 id=&#34;解决方案&#34;&gt;&lt;a href=&#34;#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;解决方案&#xD;&#xA;&lt;/h1&gt;&lt;h2 id=&#34;紧急恢复已执行&#34;&gt;&lt;a href=&#34;#%e7%b4%a7%e6%80%a5%e6%81%a2%e5%a4%8d%e5%b7%b2%e6%89%a7%e8%a1%8c&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;紧急恢复（已执行）&#xD;&#xA;&lt;/h2&gt;&lt;p&gt;对 12 台故障节点逐一执行「手动续期 + 重启」：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 6&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 7&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 8&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt; 9&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;10&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;11&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 1. 备份旧证书&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;mv /var/lib/kubelet/pki/kubelet-client-current.pem /var/lib/kubelet/pki/backup/&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 2. 用管理员 kubeconfig 手动生成新证书（通过 kubectl certificate approve 模拟）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl create csr node-manual-renewal-&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;hostname&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --from-file&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;/var/lib/kubelet/pki/kubelet-client.key &lt;span style=&#34;color:#ae81ff&#34;&gt;\&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  --signer-name&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;kubernetes.io/kubelet-serving&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 3. 实际操作中直接用 kubeadm 重新 join（最稳妥）&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubeadm token create --print-join-command&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubeadm join ... --ignore-preflight-errors&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;DirAvailable--var-lib-etcd&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：生产环境严禁直接删除 &lt;code&gt;/var/lib/kubelet/pki&lt;/code&gt;，必须先备份。&lt;/p&gt;&#xA;&lt;h2 id=&#34;根治方案计划本周上线&#34;&gt;&lt;a href=&#34;#%e6%a0%b9%e6%b2%bb%e6%96%b9%e6%a1%88%e8%ae%a1%e5%88%92%e6%9c%ac%e5%91%a8%e4%b8%8a%e7%ba%bf&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;根治方案（计划本周上线）&#xD;&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;全量切换到 TLS Bootstrapping&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;为所有节点创建长期有效的 bootstrap token（或使用 &lt;code&gt;kubeadm token create --ttl=0&lt;/code&gt;）。&lt;/li&gt;&#xA;&lt;li&gt;在所有节点部署 &lt;code&gt;/etc/kubernetes/bootstrap-kubeconfig&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;修改 kubelet 启动参数，移除静态 &lt;code&gt;--kubeconfig&lt;/code&gt;，改用 &lt;code&gt;--bootstrap-kubeconfig&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;配置证书轮换参数&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# /var/lib/kubelet/config.yaml&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;rotateCertificates&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;serverTLSBootstrap&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;   &lt;span style=&#34;color:#75715e&#34;&gt;# 同时开启 server 证书轮换&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;监控与告警&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;新增 Prometheus 规则：&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- &lt;span style=&#34;color:#f92672&#34;&gt;alert&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;KubeletClientCertExpiringSoon&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;expr&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;kubelet_certificate_manager_client_expiration_seconds &amp;lt; 86400 * 14&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;设置 14 天提前告警，避免再次出现批量过期。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;变更验收 Checklist&lt;/strong&gt;（已写入运维手册）：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;证书有效期检查脚本每日巡检。&lt;/li&gt;&#xA;&lt;li&gt;节点 NotReady 数量 &amp;gt; 3 触发 PagerDuty 立即响应。&lt;/li&gt;&#xA;&lt;li&gt;证书轮换操作必须在「维护窗口 + 灰度 10% 节点」后全量。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h1 id=&#34;根因分析&#34;&gt;&lt;a href=&#34;#%e6%a0%b9%e5%9b%a0%e5%88%86%e6%9e%90&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;根因分析&#xD;&#xA;&lt;/h1&gt;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;层面&lt;/th&gt;&#xA;          &lt;th&gt;具体原因&lt;/th&gt;&#xA;          &lt;th&gt;为什么没被发现&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;架构&lt;/td&gt;&#xA;          &lt;td&gt;老节点使用静态 kubeconfig，缺少 bootstrap 流程&lt;/td&gt;&#xA;          &lt;td&gt;早期集群规模小，证书 1 年有效期，运维人员认为「够用」&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;配置&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;rotateCertificates: true&lt;/code&gt; 但缺少配套 bootstrap 配置&lt;/td&gt;&#xA;          &lt;td&gt;文档中只写了「开启即可」，未强调「老节点需先迁移」&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;监控&lt;/td&gt;&#xA;          &lt;td&gt;仅监控证书剩余天数，未区分「是否可自动续期」&lt;/td&gt;&#xA;          &lt;td&gt;指标 &lt;code&gt;kubelet_certificate_manager_client_expiration_seconds&lt;/code&gt; 在过期后才报警&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;变更管理&lt;/td&gt;&#xA;          &lt;td&gt;安全合规要求「缩短有效期」时，未做节点分层评估&lt;/td&gt;&#xA;          &lt;td&gt;变更 checklist 缺少「证书轮换依赖项检查」&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h1 id=&#34;预防措施&#34;&gt;&lt;a href=&#34;#%e9%a2%84%e9%98%b2%e6%8e%aa%e6%96%bd&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;预防措施&#xD;&#xA;&lt;/h1&gt;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;节点生命周期管理&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;新节点必须通过「标准化镜像 + cloud-init + kubeadm join」流程上线，禁止手动 &lt;code&gt;kubeadm join&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;老节点每年至少做一次「证书与 bootstrap 流程一致性检查」。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;证书治理平台&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;引入 &lt;code&gt;cert-manager&lt;/code&gt; 或自研「K8s 证书中心」，统一管理 client/server 证书生命周期。&lt;/li&gt;&#xA;&lt;li&gt;提供「一键续期」与「过期前 30 天自动续期」能力。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;变更前置检查脚本&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;div style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&#xA;&lt;table style=&#34;border-spacing:0;padding:0;margin:0;border:0;&#34;&gt;&lt;tr&gt;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;1&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;2&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;3&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;4&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;5&#xA;&lt;/span&gt;&lt;span style=&#34;white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#7f7f7f&#34;&gt;6&#xA;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&#xA;&lt;td style=&#34;vertical-align:top;padding:0;margin:0;border:0;;width:100%&#34;&gt;&#xA;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#!/bin/bash&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# check_kubelet_bootstrap.sh&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt; ! -f /etc/kubernetes/bootstrap-kubeconfig &lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  echo &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;WARNING: node &lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;$(&lt;/span&gt;hostname&lt;span style=&#34;color:#66d9ef&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt; is using static kubeconfig, certificate rotation may fail&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  exit &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;/div&gt;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;定期演练&lt;/strong&gt;：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;每季度执行一次「模拟证书过期」演练，验证自动轮换与应急流程。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h1 id=&#34;总结&#34;&gt;&lt;a href=&#34;#%e6%80%bb%e7%bb%93&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;总结&#xD;&#xA;&lt;/h1&gt;&lt;p&gt;本次故障的本质是**「配置项与节点历史状态不匹配」**。&lt;code&gt;rotateCertificates: true&lt;/code&gt; 看似简单，实则依赖完整的 TLS Bootstrapping 链路。老节点因历史遗留问题，在证书过期后无法自愈，导致批量 NotReady 风暴。&lt;/p&gt;&#xA;&lt;p&gt;教训：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;任何「看似自动」的功能，都必须在全量节点上验证依赖条件。&lt;/li&gt;&#xA;&lt;li&gt;安全合规变更必须结合「节点分层」与「历史技术债」评估。&lt;/li&gt;&#xA;&lt;li&gt;监控不仅要看「结果」（证书是否过期），更要看「过程」（是否具备自愈能力）。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;后续将把「kubelet 证书轮换一致性检查」纳入每月运维 Checklist，并计划在 Q4 引入 cert-manager 做全生命周期治理。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
