Files
Deploy-Laboratory/docs/03-02-k3s-traefik-acme.md
2026-03-21 04:36:06 +08:00

385 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 03-02-k3s Traefik ACME
> **状态:✅ 验证已完成**2026-03K3s 4 节点 ylc61ylc64Cloudflare DNS-01、Lets Encrypt 证书、TLS 矩阵 `test01test04.jackadam.top`HTTPS 与 HTTP-only 各 16 目标均 200Ansible `nginx-matrix-tls-deploy.yml` 已实机跑通。)
> 为 Traefik 配置 ACME 自动证书Let's Encrypt + Cloudflare DNS 验证),并部署 **TLS 矩阵**。
>
> **为 02-05 的升级版**02-05 为 HTTP-only节点 IP、无域名本页在其基础上增加 ACME 证书、域名、根路径 `/`,用于有域名时的学习或生产。
---
## 前置条件
- Traefik 已可用(见 `01-02-k3s-工作节点.md`
- 域名托管在 Cloudflare
- 已获取 Cloudflare API Token最小权限
- **调度与标签要求同 02-05 矩阵**M1M4 仍是控制/工作 × Ingress/IngressRoute 四类M1 需控制节点带 `node-role.kubernetes.io/control-plane` 标签且 Deployment 含 toleration否则 M1 Pod 会 Pending。若未打标排障思路与 `02-05-nginx-验证矩阵-一键部署.md` 中 M1 Pending 相同;**本页访问域名为 HTTPS/HTTP 根路径,不是 `/demo-mx`**。
---
## 部署说明Pod、部署方式、配置与存储
- **Pod / 部署**ACME 配置通过 `HelmChartConfig` 注入到 **同一个 Traefik Deployment**。**副本数为 chart 默认值 1**(即 `deployment.replicas` 未在 values 里写时默认为 1所以只有 1 个 Traefik Pod与 03-01 的 Traefik 是同一套 Deployment只是 values 里多了 ACME 参数与 env。
- **配置存在哪里**`HelmChartConfig` 存在 **etcd**控制节点K3s 的 chart 控制器据此更新 Traefik 的部署参数Traefik 进程从 **Kubernetes API** 读取 Ingress/IngressRoute无需多 Pod 间同步。
- **ACME 存储(证书与账户)**`acme.storage` 指向容器内 **`/data/acme.json`**。未配 hostPath 时K3s 默认会为 Traefik 挂载卷到 `/data`(如 emptyDir 或默认持久卷),**仅当前这一个 Traefik Pod 可写**Pod 重建后若卷不持久则需重新申请证书。若在 values 里配置了 **hostPath**(见本页可选配置),则 `/data` 对应宿主机目录证书写在物理机路径便于备份与复用Traefik 仍为 1 个 Pod不存在多副本间同步 acme.json 的问题。
- **第一次部署随机节点、重启后怎么办**Traefik 未指定 nodeSelector 时,首次会**随机调度**到某一节点。若使用了 **hostPath**,证书只存在于该节点的磁盘上;**Pod 被调度到其他节点**(重启、驱逐、缩容再扩容)时,新节点上的同名 hostPath 是另一块盘,**证书不会跟着走**,可能需重新申请。若希望重启或节点故障后仍保留证书,可:**① 把 Traefik 固定到某一节点**(在 HelmChartConfig 的 `deployment` 下配 `nodeSelector`,例如 `nodeSelector: { kubernetes.io/hostname: ylc61 }(节点名使用短主机名 ylc61ylc64便于配合 Cloudflare CDN`),使 hostPath 始终落在同一台机;**② 或不用 hostPath**,依赖 K3s 默认持久卷(若为 local-path则卷仍绑定某节点Pod 重建到同节点可复用);**③ 或改用 NFS 等共享存储**挂到 `/data`,多节点可读同一证书(需自行在 values 里配 PVC/volume
---
## 创建 Secret
```bash
# 首次创建(不存在时)
kubectl -n kube-system create secret generic cloudflare-api-token \
--from-literal=api-token='<YOUR_CLOUDFLARE_API_TOKEN>'
# 若需更新 Token可先删除再重建不会影响已签发的证书只影响后续申请/续期)
kubectl -n kube-system delete secret cloudflare-api-token --ignore-not-found=true
kubectl -n kube-system create secret generic cloudflare-api-token \
--from-literal=api-token='<YOUR_NEW_CLOUDFLARE_API_TOKEN>'
```
---
## Token 与 Secret 验证(建议强制做)
> 目的:确认 Cloudflare API Token 对 `jackadam.top`(你的 zone是可用且“可查 zone / 可编辑 DNS”的避免 ACME 只报失败但根因不明。
### 1本机验证 Token 是否能查到 zone
在任意联网环境的终端运行Token 不要手工写死到文档里,下面用占位符):
```bash
TOKEN='<YOUR_CLOUDFLARE_API_TOKEN>'
curl -sS -X GET "https://api.cloudflare.com/client/v4/zones?name=jackadam.top" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" | jq '.success,.errors'
```
期望输出:
- `.success``true`
- `.errors` 为空数组 `[]`
如果 `.success=false`,通常会看到类似 `9109: Invalid access token``403`,这意味着 Token 依然不满足 Cloudflare API 的权限要求。
> 如果你的机器没有 `jq`,可以先把 `| jq '.success,.errors'` 去掉看原始 JSON。
### 2集群内验证 Secret 是否写入了该 Token
用“哈希对比”的方式校验(只输出哈希,不会直接泄露 Token 原文):
```bash
# 本机 Token 的 sha256
TOKEN='<YOUR_CLOUDFLARE_API_TOKEN>'
printf "%s" "$TOKEN" | sha256sum
# 集群 Secret 解码后的 sha256仅输出哈希
kubectl -n kube-system get secret cloudflare-api-token \
-o jsonpath='{.data.api-token}' | base64 -d | sha256sum
```
若两行 `sha256sum` 结果一致,说明集群里的 Secret 已经写入为你当前测试的 Token。
---
## 配置 HelmChartConfig
> **重要**:同一 chart 只能有一份 `HelmChartConfig`(如 `name: traefik`)。若已按 03-01 部署了 Dashboard再单独 apply 本文件的配置会**覆盖**掉 03-01Dashboard 会失效。此时应二选一:**要么**使用 `03-03-k3s-traefik-dashboard-acme.md` 中的合并 YAMLDashboard + ACME 一份搞定),**要么**把本页的 ACME 配置合并进已有 03-01 的 `traefik-dashboard.yaml`,只保留一个 manifest 文件。
>
> **文件选择**K3s 自带的 `traefik.yaml` 会被 K3s 覆盖,**不要修改**。所有自定义配置ACME、nodeSelector、hostPath 以及其他扩展配置)都应写在 **`traefik-acme.yaml`** 这一份 HelmChartConfig 里,与默认 chart 合并生效。
1. 在控制节点创建 `traefik-acme.yaml`,推荐放入 K3s manifests 目录(路径同 03-01。**完整配置见 `ansible/files/traefik-acme/traefik-acme.yaml`**(与 Ansible 共用),复制后替换 `<YOUR_REAL_EMAIL>` 等占位符即可。
> 将 `<YOUR_REAL_EMAIL>` 改为你的邮箱。`/data/acme.json` 为容器内路径;`caserver` 为测试服务器staging正式上线前删除该行即切回生产 CA。Traefik 在容器内监听 8000/8443由 Service 和 svclb 映射到节点 80/443。
>
> **Ping / PROXY protocol**`--ping.entryPoint=websecure` 使 `GET /ping` 在 443 端口HTTPS返回 200适合生产仅暴露 TLS、HAProxy 对 443 做健康探测(`option httpchk GET /ping` + `http-check send meth GET uri /ping ssl`。Traefik 的 ping 一次只能指定一个 entrypoint若 HAProxy 用 HTTP 探测 80 端口(内网/测试),可改为 `--ping.entryPoint=web`。`trustedIPs` 需包含 HAProxy 所在 IP若 HAProxy 在前置路由器(如 192.168.2.1),需在 HAProxy 后端加 `send-proxy-v2`,否则 Traefik 无法解析 PROXY 头。
>
> **容器外(节点 80/443在哪里设置** 由 K3s 自带的 Traefik chart 的 Service 定义chart 里默认已配好 80→8000、443→8443一般无需改。若要改对外端口例如节点用 8080 代替 80可在 `valuesContent` 里增加 `ports` 覆盖,例如:`ports.web.expose.exposedPort: 8080`、`ports.websecure.expose.exposedPort: 8443`(与 `ports.web.port` / `ports.websecure.port` 区分:前者是节点/svc 暴露端口,后者是容器内端口)。
>
> **节点在 80/443 上的对外暴露在哪里设置?** 由 K3s 自带的 Traefik chart 的 Service 定义chart 里默认已配好 80→8000、443→8443一般无需改若要改对外端口请参考上文关于 `ports` 的说明。
2. 应用配置并等待 Traefik 重载(按实际路径选择其一复制执行):
```bash
# 默认路径
kubectl apply -f /var/lib/rancher/k3s/server/manifests/traefik-acme.yaml
kubectl -n kube-system rollout status deploy/traefik
kubectl -n kube-system logs deploy/traefik --tail=100 | grep -i acme || true
```
```bash
# 自定义 data-dir如 /storage
kubectl apply -f /storage/server/manifests/traefik-acme.yaml
kubectl -n kube-system rollout status deploy/traefik
kubectl -n kube-system logs deploy/traefik --tail=100 | grep -i acme || true
```
3. (可选)检查容器内 `acme.json` 是否生成:
```bash
kubectl -n kube-system exec -it deploy/traefik -- sh -c 'ls -l /data/acme.json || true'
```
> **关于持久化与备份GitLab 等重状态服务)**:请统一使用持久化存储方案(例如 Longhorn并制定备份策略。见 `03-07-k3s-longhorn-持久化存储.md`。
---
## 验证与使用顺序概览
> 1按上节完成 **ACME 配置**Secret + `traefik-acme.yaml`)。
> 2apply **本页下方的完整矩阵 YAML**M1M4TLS 仅 `websecure` + 同域名 **HTTP-only** 仅 `web` 供内网/测试,与 02-05 的 `/demo-mx` 清单不同Traefik 会自动发现并签发证书。
> 矩阵的域名为 `test01.jackadam.top``test04.jackadam.top`M1M4 各一M2/M4 的 hostname 按实际修改。
> **可选**:也可使用 Ansible 一键部署见下方「Ansible 一键部署TLS 矩阵)」。
---
## 常见问题ACME 报 DNS 解析错误的处理
> 现象Traefik 日志中反复出现
>
> - `lookup acme-staging-v02.api.letsencrypt.org on 10.43.0.10:53: server misbehaving`
> - 或 CoreDNS 日志中出现 `dial udp [240e:...]:53: connect: network is unreachable`
>
> 原因:宿主机启用了 IPv6 DNS但 k3s 默认 flannel 网络只提供 IPv4 Pod 网络CoreDNS 在 Pod 内访问 IPv6 上游 DNS 失败,导致 ACME 无法解析 Lets Encrypt 域名。
**简单可靠的修法(保持集群 IPv4-only仅修上游 DNS**
1. 编辑 CoreDNS 的 ConfigMap将上游 DNS 改为明确的 IPv4 地址:
```bash
kubectl -n kube-system edit configmap coredns
```
将 Corefile 中的
```txt
forward . /etc/resolv.conf
```
改为类似(按实际环境选择可用的 IPv4 DNS
```txt
forward . 114.114.114.114 8.8.8.8
```
2. 重启 CoreDNS
```bash
kubectl -n kube-system rollout restart deploy/coredns
kubectl -n kube-system rollout status deploy/coredns
```
3. 在 Traefik Pod 内验证解析是否恢复正常:
```bash
POD=$(kubectl -n kube-system get pod -l app.kubernetes.io/name=traefik -o jsonpath='{.items[0].metadata.name}')
kubectl -n kube-system exec -it "$POD" -- nslookup acme-staging-v02.api.letsencrypt.org || \
kubectl -n kube-system exec -it "$POD" -- nslookup acme-v02.api.letsigncrypt.org
```
解析成功后,重新访问 `https://test01.jackadam.top``https://test04.jackadam.top`Traefik 会重新尝试通过 ACME 申请证书,`openssl s_client` 输出中的 `issuer` 将不再是 `TRAEFIK DEFAULT CERT`
> 若需要在 k3s 上完整打通 IPv6 / dual-stack包括 Pod 级 IPv6 出网),通常需要使用支持 IPv6 的 CNI如 Calico、Cilium并重新设计网络建议参考单独的 Calico/Cilium 双栈实验文档。
## TLS 矩阵清单02-05 升级版)
> **唯一真源**[`ansible/files/nginx-matrix-tls/`](../../ansible/files/nginx-matrix-tls/)`01-control-ingress.yaml``04-worker-ingressroute.yaml`),与 [`ansible/playbooks/nginx-matrix-tls-deploy.yml`](../../ansible/playbooks/nginx-matrix-tls-deploy.yml) 共用;**本文不再内联整份 YAML**。
**相对 02-05 的差异摘要**:基于域名根路径 `/`TLS 仅绑 `websecure`;含 HTTP-only`web`)路由;与 02-05 的 `/demo-mx` 为两套资源M2/M4 节点名与域名请在清单内编辑。
**清单目录中每文件**已同时包含 TLS 与 HTTP-only每个 Mx 块内先为 TLS 路由(仅 `websecure`),紧跟同域名的 HTTP-only 路由(仅 `web`,内网/测试用)。**HTTP 也 200**`http://test01test04.jackadam.top` 直接返回 200不跳转 HTTPS、不 404由上述 4 个 HTTP-only 资源实现M1/M3 为 Ingress`traefik.ingress.kubernetes.io/router.entrypoints: web`,无 `spec.tls`、无 certresolverM2/M4 为 IngressRoute`entryPoints: [web]`,无 `tls` 段),与 TLS 路由共用同一批 Deployment/Service。**生产仅暴露 TLS 时**可删除这些 HTTP-only 资源。
---
部署有两种方式,任选其一即可。
**方式一:使用仓库 YAML 目录(推荐与文档一致)**
1. 在仓库中编辑 [`ansible/files/nginx-matrix-tls/`](../../ansible/files/nginx-matrix-tls/) 内各文件M2/M4 节点名、域名等)。
2. 按 k3s 存储方案可将整个目录复制到控制节点 manifests或直接在仓库根执行 `kubectl apply -f ansible/files/nginx-matrix-tls/ -R`(与 `01-01-k3s-控制节点含traefik.md` 存储路径说明一致)。
3. 清理示例(路径与 apply 时一致):
```bash
kubectl delete -f ansible/files/nginx-matrix-tls/ -R --ignore-not-found=true
```
或沿用下文按资源名删除。
或按资源名删除(与路径无关):
```bash
kubectl delete deployment,svc -n default nginx-m1 nginx-m2 nginx-m3 nginx-m4 --ignore-not-found=true
kubectl delete ingress -n default nginx-m1 nginx-m3 nginx-m1-http nginx-m3-http --ignore-not-found=true
kubectl delete ingressroute -n default nginx-m2 nginx-m4 nginx-m2-http nginx-m4-http --ignore-not-found=true
kubectl delete configmap -n default nginx-m1-html nginx-m2-html nginx-m3-html nginx-m4-html --ignore-not-found=true
```
**方式二:使用仓库内 manifests + Ansible playbook**
- 直接使用仓库中已合并好的 4 个文件(每个 Mx 含 TLS + HTTP-only在**仓库根目录**执行:
```bash
kubectl apply -f ansible/files/nginx-matrix-tls/ -R
```
需保证当前环境已设置 KUBECONFIG 或 `kubectl` 已指向目标集群(例如在控制节点上或已配置远程 kubeconfig
- 一键部署/清理推荐用 Playbook会先删 02-05 残留、再 apply、并做就绪与 curl 验证):
- 在 `ansible/` 目录下:`ansible-playbook -i inventory.ini playbooks/nginx-matrix-tls-deploy.yml`
- 在仓库根目录:`ansible-playbook -i ansible/inventory.ini ansible/playbooks/nginx-matrix-tls-deploy.yml`
- 清理:同上命令后加 `-e mode=cleanup`。
验证 HTTP 与 HTTPS 是否正常(将 `192.168.2.61 … 192.168.2.64` 按实际入口节点 IP 修改):
```bash
# HTTP 验证4 节点 × 4 域名,应均为 200
for ip in 192.168.2.61 192.168.2.62 192.168.2.63 192.168.2.64; do
echo "=== 节点 $ip 上的 4 个域名 (HTTP) ==="
for id in 1 2 3 4; do
curl -sI "http://test0$id.jackadam.top/" --resolve "test0$id.jackadam.top:80:$ip" -o /dev/null -w "test0$id:%{http_code}\n" || echo "test0$id:fail"
done
echo ""
done
# HTTPS 验证4 节点 × 4 域名,应均为 200证书为 Let's Encrypt
for ip in 192.168.2.61 192.168.2.62 192.168.2.63 192.168.2.64; do
echo "=== 节点 $ip 上的 4 个域名 (HTTPS) ==="
for id in 1 2 3 4; do
curl -skI "https://test0$id.jackadam.top/" --resolve "test0$id.jackadam.top:443:$ip" -o /dev/null -w "test0$id:%{http_code}\n" || echo "test0$id:fail"
done
echo ""
done
```
---
若 ACME 与 Cloudflare 配置正确Traefik 日志中可见证书申请成功;四个路径均返回 200页面分别显示 **M1**、**M2**、**M3**、**M4**,便于区分是哪个后端。
**若 curl 报 “SSL certificate problem: self-signed certificate”**:说明 Traefik 未拿到 Let's Encrypt 证书,在用默认自签证书。按下面逐项排查:
1. **确认已部署 TLS 矩阵**Ingress 需带 `spec.tls`、`host`、注解 `certresolver=cloudflare`
```bash
kubectl get ingress -n default nginx-m1 -o yaml | grep -A5 "tls:\|host:\|certresolver"
```
若无 `tls` / `host` / `certresolver`,说明当前是 02-05 的非 TLS Ingress需执行 `kubectl apply -f ansible/files/nginx-matrix-tls/ -R`(或跑 Ansible playbook `nginx-matrix-tls-deploy.yml`)。
2. **看 Traefik 是否尝试/成功申请证书**
```bash
kubectl -n kube-system logs deploy/traefik --tail=500 | grep -iE "acme|Let's Encrypt|certificate|error"
```
若有 `obtained certificate` 则已签发;若有 `acme: error` 或 `failed to get certificate`记下错误信息常见DNS 挑战超时、Cloudflare API Token 权限不足、域名未在 Cloudflare 托管)。
3. **确认 Cloudflare**test01test04.jackadam.top 的 zone 在 CloudflareSecret `cloudflare-api-token` 存在且 API Token 有 “Zone:DNS:Edit”若用 staging CA 测试,通过后再删 `caserver` 行切回生产。
4. **本地验证时加 `-k`** 可忽略证书校验只看 HTTP 是否 200`curl -sk -o /dev/null -w "%{http_code}" https://test01.jackadam.top/ --resolve test01.jackadam.top:443:192.168.2.61`。证书正常前可用 `-k` 做功能验证。
5. **日志出现 “Router uses a nonexistent certificate resolver certificateResolver=cloudflare”**:表示当前 Traefik **未加载 ACME 配置**,没有名为 `cloudflare` 的证书解析器,因此会用自签证书。需确认本页「配置 HelmChartConfig」中的 `traefik-acme.yaml` 已放到 K3s manifests 目录并已 apply且 Traefik 已用新配置重载:
```bash
kubectl get helmchartconfig -n kube-system traefik -o yaml
# 若存在且 valuesContent 中含 certificatesresolvers.cloudflare则重启 Traefik 使配置生效
kubectl -n kube-system rollout restart deploy/traefik
kubectl -n kube-system logs deploy/traefik --tail=50 | grep -i cloudflare
```
若 HelmChartConfig 不存在或没有 cloudflare 段,请按本页「创建 Secret」与「配置 HelmChartConfig」重新创建并 apply。
6. **日志出现 “service not found” / “kubernetes service not found: default/nginx-m2” / “middleware … does not exist”**:说明 Ingress/IngressRoute 已存在,但对应的 **Service 或 Middleware 缺失**(例如只 apply 了部分 TLS 矩阵,或先删后 apply 时 Traefik 在中间时刻读到不完整状态)。需**完整** apply TLS 矩阵,保证 M1M4 的 Deployment、Service、Middleware、Ingress/IngressRoute 一起就绪:
```bash
kubectl apply -f ansible/files/nginx-matrix-tls/ -R
kubectl get svc,middleware -n default | grep -E "nginx-m|stripprefix"
```
确认 nginx-m1m4 的 Service 与 stripprefix-m1m4 的 Middleware 均存在后Traefik 会重新同步路由;证书仍需按上一步确保 ACME 配置生效。
7. **日志出现 “Unable to obtain ACME certificate” 且错误含 “lookup … server misbehaving” 或 “cannot get ACME client get directory”**:说明 **集群内 DNSCoreDNS无法解析 Let's Encrypt 的域名**(如 acme-staging-v02.api.letsencrypt.orgTraefik Pod 连不上 ACME 服务器。排查步骤:
- 在**节点上**测解析(用节点自身 DNS`nslookup acme-staging-v02.api.letsencrypt.org` 或 `getent hosts acme-staging-v02.api.letsencrypt.org`。若节点也解析不了,需检查节点出口 DNS 与网络(如 /etc/resolv.conf、防火墙、是否可访问公网
- 在**集群内**测解析:`kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup acme-staging-v02.api.letsencrypt.org`。若失败,多为 CoreDNS 的上游 DNS 不可达或不允许外网查询;可临时将 CoreDNS 的 forward 改为 8.8.8.8 / 1.1.1.1 等可访问外网的 DNS 后重试。
- 若为内网环境且节点无法直接访问外网,需通过 HTTP 代理或允许集群访问外网 DNS/443 后再申请证书。
8. **排查时开启 Traefik DEBUG 日志**:默认 INFO 下 ACME 只打少量摘要。若要看到 DNS 挑战、TXT 查询、传播等待等更细的日志,可在 `traefik-acme.yaml` 的 `additionalArguments` 最前面增加一行 `- "--log.level=DEBUG"`,然后 apply 并重启 Traefik
```bash
# 在 valuesContent 的 additionalArguments 下第一项插入(若尚未存在)
sed -i '/additionalArguments:/a\ - "--log.level=DEBUG"' /storage/server/manifests/traefik-acme.yaml
# 若已有 additionalArguments 但无 log.level可手动在 YAML 里加一行:- "--log.level=DEBUG"
kubectl -n kube-system apply -f /storage/server/manifests/traefik-acme.yaml
kubectl -n kube-system rollout restart deploy/traefik
```
复现问题后查看详细输出ACME、DNS、TXT、propagation 等):
```bash
kubectl -n kube-system logs deploy/traefik --since=15m --all-containers | grep -iE "acme|dnschallenge|TXT|propagation|challenge|authorization|certificate"
```
排查结束后可将 `--log.level=DEBUG` 删掉或改为 `INFO`,避免生产日志过多。
---
## Ansible 一键部署TLS 矩阵)
可使用 Ansible 自动部署 / 清理 TLS 矩阵test01test04.jackadam.top并做 HTTPS 验证:
- **Playbook**`ansible/playbooks/nginx-matrix-tls-deploy.yml`
- **Manifests**`ansible/files/nginx-matrix-tls/`M1M4 带 TLS域名为 test01test04.jackadam.top按实际修改 M2/M4 节点名 ylc61/ylc64
- **前置**:已按本页完成 ACME 配置,且 test01test04.jackadam.top 已解析到入口 IP
```bash
# 一键部署 TLS 矩阵
cd ansible
ansible-playbook -i inventory.ini playbooks/nginx-matrix-tls-deploy.yml -e mode=deploy
# 一键删除 TLS 矩阵
cd ansible
ansible-playbook -i inventory.ini playbooks/nginx-matrix-tls-deploy.yml -e mode=cleanup
```
Playbook 在 `mode=deploy` 时会:拷贝 TLS manifests 到控制节点 → **若存在不含 TLS 的 nginx 矩阵02-05先按资源名删除**deployments、svc、ingress、ingressroute、configmaps 共 M1M4→ `kubectl apply` TLS 矩阵 → 等待 Pod 就绪 → 对**所有 k3s_nodes 节点**做 HTTPS 验证4 节点 × 4 域名 = 16 个目标,与 02-05 HTTP 矩阵一致,所有节点均为入口点)。`mode=cleanup` 时则按资源名删除 TLS 矩阵相关 Deployment/Service/Ingress/IngressRoute/ConfigMap并清理 `/tmp/nginx-matrix-tls` 目录,恢复到未部署 TLS 矩阵前的状态。
---
## 删除部署与文件
因同一 chart 只能有一份 HelmChartConfig后续改做 03-01Dashboard或 03-03Dashboard+ACME 合并)时,建议先删除本部署并删掉 manifest 文件。
1. **删除集群内 HelmChartConfig**Traefik 会按 chart 默认重载ACME 配置失效):
```bash
# 默认路径
kubectl delete -f /var/lib/rancher/k3s/server/manifests/traefik-acme.yaml
kubectl -n kube-system rollout status deploy/traefik
```
```bash
# 自定义 data-dir如 /storage
kubectl delete -f /storage/server/manifests/traefik-acme.yaml
kubectl -n kube-system rollout status deploy/traefik
```
2. **删除宿主机上的 manifest 文件**(否则 K3s 重启会再次加载):
```bash
# 默认路径
sudo rm -f /var/lib/rancher/k3s/server/manifests/traefik-acme.yaml
```
```bash
# 自定义 data-dir如 /storage
sudo rm -f /storage/server/manifests/traefik-acme.yaml
```
3. **可选**nginx 矩阵的删除见 `02-05-nginx-验证矩阵-一键部署.md` 删除小节。Cloudflare API Token 的 Secret`cloudflare-api-token`)若不再使用可删:`kubectl -n kube-system delete secret cloudflare-api-token`。
---
## 注意事项
- 证书一直不签发:优先检查 DNS 解析与 Cloudflare Token 权限
- 首次签发慢:可等待 1-5 分钟再看日志
- 仍返回 502优先回到后端链路排查不是 ACME 本身问题
---
## 相关文档
- `02-05-nginx-验证矩阵-一键部署.md`(独立 HTTP 矩阵 `/demo-mx`,与本文 TLS 矩阵**非同一套**;调度/标签排障可参考)
- `01-02-k3s-工作节点.md`
- `03-04-k3s-cloudflare-tunnel-配置接入.md`
- `06-01-k3s-networkpolicy-故障排查.md`
## 下一步
- 返回 00-00-构建总览.md按导航继续。