Kubernetes traefik tls证书到期替换:用TaoToken统一Key管理secret更新与滚动验证
1. Kubernetes traefik tls证书到期替换为什么删除重建是下策每年证书到期那几天运维群里总有人问同一个问题Kubernetes 里 traefik 的 tls 证书怎么换才不中断。我见过最常见的做法就是kubectl delete secret再kubectl create secret简单粗暴但这里有个真实的空窗期风险——secret 被删掉到新 secret 创建完成之间traefik 如果正好要处理新的 TLS 握手就会拿到一个不存在的证书引用轻则握手失败重则 Ingress 报 502。对于电商、API 网关这类流量不间断的业务哪怕几百毫秒的证书缺失都可能被监控抓到。这篇要解决的就是这个场景Kubernetes 集群里 traefik Ingress 的 tls 证书到期如何用 secret 替换流程做到滚动生效、零中断并且用 TaoToken 统一 Key 通道来管理证书更新后的服务连通性验证。核心检索词就是 Kubernetes traefik tls证书到期替换适合正在维护 traefik 入口、手上有 DV 或 OV 证书、又不想停机的人。先说清楚 traefik 的证书加载机制。traefik 作为 Ingress Controller 时它监听 Kubernetes 的 Secret 资源当带有tls.crt和tls.key的 secret 发生变化traefik 的 provider 会收到 watch 事件然后热加载新的证书到内存不需要重启 Pod。这意味着只要 secret 的更新是原子性的证书切换就可以做到无感。问题就出在「删除再创建」这个动作上delete 和 create 是两个独立事件中间必然有一个 secret 不存在的窗口traefik 在这个窗口里拿不到证书。所以正确的思路是不要 delete而是用kubectl apply或kubectl patch去更新已有 secret 的 data 字段。这样 Kubernetes 对 secret 的更新是单次 API 调用traefik 收到的是一个 update 事件而不是 deleteadd证书引用始终存在只是内容被替换。下面我会把几种替换方式都列出来重点讲可复制、可回滚、可验证的那一种。另外要提醒一点证书文件本身来自哪里不影响 K8s 侧的操作。不管你是从云厂商控制台下载的 zip还是用 certbot 生成的 pem最终都要转成tls.crt和tls.key两个字段。云厂商给的 Nginx 目录里通常是xxx_bundle.crt和xxx.keybundle 里已经包含了中间证书链直接作为tls.crt用即可。如果你的证书链是分开的需要把服务器证书和中间证书按顺序拼接成一个 crt 文件否则部分客户端会报证书链不完整。我试过在流量高峰期做替换只要走 apply 路径traefik 的 access log 里不会出现 TLS handshake error。下面从 TaoToken 的前置准备开始把整条链路串起来。2. TaoToken 统一 Key 管理证书更新后的连通性验证通道证书替换本身是 K8s 侧的操作但替换完你怎么确认服务真的通了尤其是 traefik 后面挂了一堆微服务证书换了之后如果某个后端因为 SNI 或证书链问题握手失败光看 traefik 的日志不一定能立刻发现。这时候需要一个稳定的、可编程的验证通道去主动请求你的域名检查 TLS 握手和 HTTP 响应。TaoToken 在这里的角色是统一 Key 管理通道。它提供一个兼容 OpenAI 风格的 API 入口你可以用同一个 Key 去调用不同的模型能力用来做证书更新后的连通性探测、响应内容校验甚至让模型帮你解析 traefik 的报错日志。官网地址是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 注意 API 地址不带 UTM 参数直接拼/v1/chat/completions这类路径即可。为什么证书替换场景要扯到 TaoToken因为很多团队的验证脚本是写死的 curl只能判断 HTTP 200判断不了证书链是否完整、SNI 是否匹配、后端返回的内容是否符合预期。用 TaoToken 的模型对话能力你可以把 curl 拿到的响应头、证书信息、甚至 traefik 的 error log 丢给模型让它判断「这次替换是否真的成功」。这不是必须的但在多域名、多命名空间的复杂环境里能省掉大量人工核对。具体操作上你需要先在 TaoToken 控制台创建一个 API Key。进入 console 页面 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 在 API Keys 管理里生成一个 Key复制保存。这个 Key 就是后面验证脚本里要用的凭证。如果你只是做证书验证用模型对话的额度就够了不需要开 Coding Plan但如果你打算把验证脚本做成长期跑的 Agent可以考虑 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它有更稳定的长任务配额。拿到 Key 之后验证脚本的骨架是这样先用 curl 或 openssl 去请求你的域名拿到 TLS 握手结果和 HTTP 状态码然后把结果整理成一段文本通过 TaoToken 的 API 发给模型让模型输出「证书是否有效、链是否完整、是否需要人工介入」。这样你就有了一条独立于 K8s 集群的验证通道即使集群内的监控挂了你也能从外部确认服务状态。需要强调的是TaoToken 在这里是辅助验证和日志分析不是替代 traefik 或 K8s 的证书管理。证书的存储、加载、热更新仍然由 Kubernetes 和 traefik 负责。TaoToken 的 Key 管理只是让你在验证环节有一个统一的入口不用为每个验证脚本单独维护一套凭证。如果你还没有 Key现在可以去 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 创建一个。创建时注意选择对应的权限范围证书验证只需要模型调用权限即可。Key 生成后只显示一次记得存到你的密码管理器或 K8s Secret 里不要硬编码在脚本中。3. 可复制配置kubectl patch 与 apply 更新 traefik tls secret这一节是全文的核心操作部分。假设你的 traefik Ingress 使用的 tls secret 名字是all-example-com命名空间是master新证书文件是1_example.com_bundle.crt和2_example.com.key。下面给出三种可复制的方式按推荐程度排序。第一种用kubectl create secret tls配合--dry-runclient生成 YAML再 apply。这是最稳妥的方式因为它会完整替换 secret 的 data 字段且只产生一次 update 事件kubectl create secret tls all-example-com \ --key2_example.com.key \ --cert1_example.com_bundle.crt \ -n master \ --dry-runclient -o yaml | kubectl apply -f -执行后会输出secret/all-example-com configured说明是更新而不是新建。注意--dry-runclient在较新版本 kubectl 里也可以写成--dry-runclient老版本用--dry-run即可。这个命令的好处是幂等重复执行不会报错适合放进 CI 流水线。第二种用kubectl patch直接更新 data 字段。这种方式需要你先把证书内容 base64 编码然后构造 patch JSON。适合在脚本里做精细控制CRT_B64$(base64 -w 0 1_example.com_bundle.crt) KEY_B64$(base64 -w 0 2_example.com.key) kubectl patch secret all-example-com -n master --typemerge -p { \data\: { \tls.crt\: \${CRT_B64}\, \tls.key\: \${KEY_B64}\ } }注意base64 -w 0在 macOS 上可能不支持-w参数macOS 用base64 -i file或者openssl base64 -A。patch 的--typemerge表示合并更新只改 data 里的两个 key不动其他字段。执行成功会返回secret/all-example-com patched。第三种如果你习惯用 YAML 文件管理可以写一个secret.yaml把 base64 后的内容填进去然后 applyapiVersion: v1 kind: Secret metadata: name: all-example-com namespace: master type: kubernetes.io/tls data: tls.crt: LS0tLS1CRUdJTi...你的 base64 证书链 tls.key: LS0tLS1CRUdJTi...你的 base64 私钥然后执行kubectl apply -f secret.yaml -n master这种方式适合 GitOps 流程secret 文件可以放在加密的仓库里配合 sealed-secrets 或 SOPS 使用。但要注意YAML 里的 base64 必须是一行不能有换行否则 K8s 解析会报错。三种方式对比一下方式是否原子更新是否幂等适合场景create --dry-run apply是是CI/CD、脚本kubectl patch是是精细控制、部分更新YAML apply是是GitOps、版本管理不管用哪种核心原则是不要 delete。delete 之后再 createtraefik 会先收到 delete 事件把证书从内存里移除然后才收到 add 事件重新加载。这个窗口期就是中断风险的来源。更新完成后检查 secret 是否真的变了kubectl get secret all-example-com -n master -o jsonpath{.data.tls\.crt} | base64 -d | openssl x509 -noout -dates这会输出证书的notBefore和notAfter确认新证书的有效期已经生效。如果输出的还是旧日期说明 apply 没成功检查一下文件路径和命名空间。另外如果你的 traefik 配置里用了tls.secretName引用这个 secret不需要改 Ingress 或 IngressRoutetraefik 会自动感知 secret 变化。但如果你用的是tls.certResolver自动签发那替换逻辑不一样这里不展开。4. 验证请求与成功结果traefik 热加载检查与连通性测试secret 更新完下一步是确认 traefik 真的加载了新证书并且服务连通性正常。这一步不能只看kubectl get secret因为 secret 更新成功不代表 traefik 已经热加载。先看 traefik 的 Pod 日志。找到 traefik 的 Podkubectl get pods -n kube-system | grep traefik然后跟踪日志kubectl logs -f traefik-pod-name -n kube-system在另一个终端里触发一次 secret 更新或者等几秒你应该能在日志里看到类似这样的行leveldebug msgConfiguration received from provider kubernetes providerNamekubernetes leveldebug msgSkipping TLS certificate for secret master/all-example-com ...不同 traefik 版本的日志措辞不一样但关键是有 provider 收到配置更新的事件。如果日志里完全没有反应可能是 traefik 的 RBAC 没有 watch secret 的权限检查 ClusterRole 里有没有secrets的get/list/watch。接下来做外部连通性验证。用 openssl 检查证书链openssl s_client -connect example.com:443 -servername example.com -showcerts /dev/null 2/dev/null | openssl x509 -noout -dates -subject输出里notAfter应该是新证书的到期时间。如果还是旧时间说明 traefik 没加载新证书或者你请求的域名没走这个 secret。再用 curl 检查 HTTP 响应curl -sv https://example.com/healthz -o /dev/null 21 | grep -E SSL certificate|HTTP/正常输出里应该有SSL certificate verify ok和HTTP/2 200。如果出现SSL certificate problem说明证书链有问题检查 bundle 文件是否包含了中间证书。现在把 TaoToken 的验证通道接进来。写一个简单的脚本把 curl 和 openssl 的输出整理后发给模型#!/bin/bash DOMAINexample.com CERT_INFO$(openssl s_client -connect ${DOMAIN}:443 -servername ${DOMAIN} /dev/null 2/dev/null | openssl x509 -noout -dates -subject -issuer) HTTP_CODE$(curl -s -o /dev/null -w %{http_code} https://${DOMAIN}/healthz) PROMPT这是证书替换后的验证结果请判断是否成功\n证书信息${CERT_INFO}\nHTTP状态码${HTTP_CODE}\n如果证书未过期且HTTP为200回复SUCCESS否则回复FAIL并说明原因。 curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer ${TAOTOKEN_API_KEY} \ -H Content-Type: application/json \ -d { \model\: \gpt-4o-mini\, \messages\: [{\role\: \user\, \content\: \${PROMPT}\}] } | jq -r .choices[0].message.content把TAOTOKEN_API_KEY换成你在 API Keys 页面创建的 Key。模型返回SUCCESS就说明验证通过。这个脚本可以放进 CI每次证书替换后自动跑一遍。成功的结果应该是traefik 日志显示 provider 更新openssl 显示新到期时间curl 返回 200TaoToken 模型返回 SUCCESS。四个条件都满足才算一次零中断替换完成。如果你在验证时发现 traefik 日志里出现no certificate found或TLS handshake error先别慌检查是不是 secret 名字和 Ingress 里引用的不一致。traefik 对 secret 的命名空间敏感Ingress 在哪个 namespacesecret 就要在哪个 namespace跨 namespace 引用需要额外配置。5. 本篇常见错排查401、local proxy failed、reading choices 与 OAuth证书替换过程中报错往往不在 K8s 侧而在验证脚本和 API 调用侧。这一节把几个高频报错列出来对照排查。第一个401 Unauthorized。如果你在调用 TaoToken API 时看到这个说明 Key 不对或没带上。检查Authorization: Bearer后面的 Key 是否完整有没有多余空格。Key 是在 API Keys 页面生成的如果忘了可以重新生成一个。注意不要把 Key 提交到 Git 仓库用环境变量或 K8s Secret 注入。第二个local proxy failed或connection refused。这通常出现在你本地跑验证脚本但网络环境无法直连 API 入口时。检查你的https_proxy环境变量是否指向了一个不可用的地址。如果你在公司内网确认防火墙是否放行了taotoken.net的 443 端口。这个报错和证书替换本身无关是网络链路问题。第三个reading choices相关报错比如cannot read property choices of undefined。这说明 API 返回的 JSON 结构和你预期的不一样通常是请求体格式错了。检查model字段是否拼写正确messages是否是数组Content-Type是否是application/json。如果返回的是错误信息而不是正常响应先打印完整响应体再解析。第四个OAuth相关报错。如果你用的是 Claude Code 或某些需要 OAuth 的客户端可能会遇到 token 过期。这时候需要重新走一遍授权流程。如果你是通过 TaoToken 的 ClaudeCodeAnthropic 入口接入参考文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里的配置说明确认 Base URL、Key、Model ID 三件套都填对了。关于三件套如果你用 Cline 或 CC Switch 这类工具配置里必须同时写全Base URLhttps://taotoken.net/apiAPI Key你在 console 生成的 KeyModel ID比如gpt-4o-mini或claude-3-5-sonnet按你实际调用的模型填少任何一个都会报错。特别是 Model ID有些客户端默认填了一个不存在的模型名导致model not found。还有一个容易忽略的点证书替换后如果你用kubectl edit secret手动改 base64很容易改错。因为 base64 编码后的内容很长手动替换时可能漏掉一个字符导致私钥和证书不匹配。traefik 加载时会报tls: private key does not match public key。遇到这个报错重新用kubectl create secret tls --dry-run生成一遍不要手动 edit。最后如果你在 traefik 日志里看到Unable to obtain ACME certificate说明你用的是 ACME 自动签发而不是手动 secret。这种情况下替换逻辑不同需要检查 certResolver 配置和 ACME 账户状态不在本篇讨论范围内。排障时建议按这个顺序先确认 secret 更新成功kubectl get secret再确认 traefik 加载成功看日志再确认外部握手成功openssl最后确认 API 验证通道正常TaoToken 返回。一层一层往下查不要跳步。6. 语义一致 CTA把证书替换和 Key 管理串成一条流水线证书替换不是一次性任务每年都要做而且随着域名增多手动操作越来越容易出错。把上面的步骤串成一条流水线才是长期省心的做法。我的建议是把kubectl create secret tls --dry-run | kubectl apply -f -写进 CI 脚本证书文件从密钥管理服务拉取替换后自动触发验证脚本。验证脚本里用 TaoToken 的 API 做一次模型判断确认证书链和 HTTP 状态都正常。这样每次证书到期你只需要更新证书文件剩下的交给流水线。如果你还没有 TaoToken 的 Key去 API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 创建一个然后参考接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 把验证脚本跑通。文档里有不同语言的调用示例照着改就行。对于需要长期跑验证 Agent 的团队Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 提供更稳定的配额适合把证书验证做成定时任务。如果只是偶尔验证用模型对话的按量额度就够了入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。最后提醒一句证书替换的核心是「不 delete只 update」traefik 的热加载能力足够支撑零中断。验证环节用外部通道确认不要只信集群内的监控。把这两点做到每年证书到期就不用再熬夜了。

相关新闻

Flutter零报错安装:环境隔离+版本锚定+架构校验三步法

Flutter零报错安装:环境隔离+版本锚定+架构校验三步法

1. 为什么“零报错”安装Flutter不是玄学,而是可复现的工程习惯 “Flutter之安装(零报错)”——这个标题乍看像一句口号,甚至带点营销味。但在我带过十几期跨平台开发实训、帮上百位新手从零搭建环境的实操经验里,“零…

2026/10/17 16:46:48 阅读更多 →
RAG检索优化:基于LangChain4j的重排序Rerank精排实战

RAG检索优化:基于LangChain4j的重排序Rerank精排实战

做 RAG 的朋友应该都有过这种体验:向量检索跑得好好的,相关度得分看起来也不错,可最后大模型回答出来的内容就是“差点意思”。真正的关键段落明明在库里,却被一堆弱相关的碎片挤到了后面,LLM 看到的是被噪声淹没的上下…

2026/10/17 16:45:47 阅读更多 →
Ubuntu Crontab定时任务原理与实战避坑指南

Ubuntu Crontab定时任务原理与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 16:45:47 阅读更多 →

最新新闻

Multi-Agent创业策略:避开通用平台,在垂直场景打造差异化护城河

Multi-Agent创业策略:避开通用平台,在垂直场景打造差异化护城河

一个残酷但真实的现象:近半年我接触了不少想靠Multi-Agent创业的团队,大多数人一开口就是“我们要做一个通用的Agent平台”。每次听到这句话,我内心都会咯噔一下。通用平台这件事,听起来性感和宏大,但在巨头生态已经成…

2026/10/17 17:52:35 阅读更多 →
VSCode 配置 MSVC 与 EasyX:C++ 图形编程环境搭建指南

VSCode 配置 MSVC 与 EasyX:C++ 图形编程环境搭建指南

1. 为什么要在 VSCode 里折腾 MSVC 加 EasyX 这套组合先把场景说清楚:你手里有一台 Windows 机器,想用 C 写点带图形界面的小玩意儿——画个圆、贴张图、做个贪吃蛇或者扫雷,但又不想背 Visual Studio 那套庞大的 IDE 包袱,只想在…

2026/10/17 17:52:35 阅读更多 →
大模型Agent面试必备:考点地图、高频问题与备战攻略

大模型Agent面试必备:考点地图、高频问题与备战攻略

大模型 Agent 方向的面试,这两年热度一直没降。我既作为候选人面过不少团队,也坐在面试官的位置上筛过简历、出过题、追问过候选人。一个很直观的感受是:这个方向看起来很“热”,但很多人的准备方式还停留在“背八股”阶段——模型…

2026/10/17 17:52:35 阅读更多 →
LangChain提示词管理实战:用YAML配置模板告别硬编码

LangChain提示词管理实战:用YAML配置模板告别硬编码

最早我管理提示词是硬编码派的。所有模板直接写在业务代码里,用的时候拼字符串,改完靠发版上生产。直到有一回,一个助手类产品在线上稳定跑了两个月,业务突然说要调整开场白语气。我心想不就改一句话吗,结果走了一遍完…

2026/10/17 17:52:34 阅读更多 →
模式识别算法MATLAB实现:从特征提取到分类器与聚类实战

模式识别算法MATLAB实现:从特征提取到分类器与聚类实战

简介:《模式识别与智能计算——MATLAB技术实现》(第3版)是一本面向模式识别与智能计算学习者的系统教程,适合计算机、信息工程、智能机器人等专业的学生及科研工程人员阅读。全书以统计学、神经网络、机器学习、群智能计算等交叉学…

2026/10/17 17:52:34 阅读更多 →
数据指标多重应用:从口径定义到业务决策的实战指南

数据指标多重应用:从口径定义到业务决策的实战指南

看一眼标题,很多人第一反应是“哪个指标?”,然后就没有然后了。做数据和运营这些年,最明显的一个感受是:大家天天在看日活、看留存、看转化率,但这些“熟悉得不能再熟悉”的指标,绝大多数时候只…

2026/10/17 17:51:34 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →