Teable 内网离线部署:k3s + Helm 全流程(附排查表) Teable 内网离线部署k3s Helm 全流程一句话一台干净的 x86_64 机器用 k3s 起单节点集群离线导入 16 个镜像装 ingress-nginx 接管 80/443再用 Helm 把 Teable 部署到 opensandbox-system。全程不联网。0. 版本先确认别用别的版本组件版本说明k3sv1.28.x材料里的k3s/k3s自带k3s --version确认containerd随 k3s不要用系统的 Docker 导入ingress-nginx chart4.11.x对应 controller v1.15.1Teable chart见 tgz 内 Chart.yamlteable-deployment-k8s.tgz验证日期2026-10镜像 tag 固定到日期超半年请重测为什么放最前面离线部署最难复现的就是版本漂移。k3s 差一个小版本CNI 行为就可能不一样。1. 名词名词一句话解释k3s精简版 Kubernetes。可以理解成这台机器上的程序统一管理台containerdk3s 内部真正负责运行镜像的组件Pod最小工作单元一个 Pod 里通常跑一个程序Deployment保证指定数量的 Pod 一直在跑Service给一组 Pod 一个固定访问地址Ingress域名/路径 → Service 的转发规则ingress-nginx执行 Ingress 规则的前台监听 80/443命名空间给程序分组本方案用opensandbox-systemSecret放证书、密码等敏感内容PVC给 Pod 的硬盘数据放这里Helmk8s 的安装包管理器chartHelm 安装包一堆模板镜像程序打包好的毛坯房DNAT内核层端口转发。k3s 用它在 80/443 上接客自签证书自己签发的证书浏览器会警告点继续即可2. 准备2.1 检查机器uname -m nproc free -h df -h / ip -o -4 addr show scope global【你应该看到】x86_64 CPU 数 ≥ 4 内存 total ≥ 7.0Gi 根分区可用 ≥ 50G 一个全局 IPv4 地址把它抄下来【如果不对】配置不够请换机器架构不是x86_64则本材料不适用。2.2 确认基础命令for t in bash curl tar gzip openssl python3 ip ss iptables; do printf %-10s $t command -v $t || echo MISSING done【判据】每一项都有路径没有MISSING。2.3 检查材料八个核心部件k3s/k3s k3s 主程序 k3s/install.sh 安装脚本 k3s/k3s-airgap-images-amd64.tar k3s 自带组件镜像 helm/helm Helm 二进制 ingress-nginx-images.tar 入口控制器镜像 teable-k8s-images.tar Teable 及依赖镜像 teable-deployment-k8s.tgz Teable 的 Helm chart values.yaml 你的定制配置cd ~/offline/k8s-offline for f in k3s/k3s k3s/install.sh k3s/k3s-airgap-images-amd64.tar \ helm/helm teable-k8s-images.tar ingress-nginx-images.tar \ teable-deployment-k8s.tgz values.yaml; do if [ -s $f ]; then printf OK %-35s %s\n $f $(du -h $f | cut -f1) else printf MISS %s\n $f fi done【判据】全部OK。确认业务镜像条目数tar -xOf teable-k8s-images.tar manifest.json \ | python3 -c import json,sys; print(业务镜像条目:, len(json.load(sys.stdin)))【你应该看到】业务镜像条目: 14展开 chartHelm 读不了压缩包必须先解压cd $HOME/offline ls -d teable-deployment 2/dev/null || tar xzf $HOME/offline/k8s-offline/teable-deployment-k8s.tgz ls -d $HOME/offline/teable-deployment/helm/teable-infra【判据】最后一行能打印出目录。这里最容易出错解压后的teable-deployment在~/offline/下不在k8s-offline/下。后面CHART_DIR必须跟着这个路径不能写错。ingress-nginx 的 chart 也要展开ls $HOME/offline/k8s-offline/ingress-nginx/Chart.yaml 2/dev/null \ || tar xzf $HOME/offline/k8s-offline/ingress-nginx-chart.tgz -C $HOME/offline/k8s-offline ls $HOME/offline/k8s-offline/ingress-nginx/Chart.yaml【如果这一步失败】说明材料里缺ingress-nginx-chart.tgz。ingress-nginx-images.tar只有镜像没有 chart——两个是两回事。2.4 变量块每新开终端都要执行先把LAN_IP改成你的内网 IP再整段复制export BASE_DOMAINteable.lan export LAN_IP192.168.72.128 export RELEASEteable export NSopensandbox-system export OFFLINE$HOME/offline/k8s-offline export CHART_DIR$HOME/offline/teable-deployment/helm/teable-infra export VALUES$HOME/offline/k8s-offline/values.yaml export KUBECONFIG/etc/rancher/k3s/k3s.yaml变量作用能不能改BASE_DOMAIN四个域名的根可以但要同步改values.yaml并重建证书LAN_IP入口 IP也是浏览器访问的 IP必须改成你的RELEASEHelm release 名一般不改NS主命名空间一般不改OFFLINE材料目录路径不同时改CHART_DIRTeable chart 目录路径不同时改VALUES单机离线配置一般不改KUBECONFIGk3s 的集群凭证不要改【判据】echo $BASE_DOMAIN / $LAN_IP / $NS / $RELEASE ls -d $CHART_DIR $VALUES【你应该看到】teable.lan / 192.168.72.128 / opensandbox-system / teable /home/你的用户名/offline/teable-deployment/helm/teable-infra /home/你的用户名/offline/k8s-offline/values.yaml2.5 断网建议sudo ip route del default curl -I --max-time 5 https://ghcr.io 21 | head -3【你应该看到】Could not resolve host/Network is unreachable之类的失败。【注意】如果你的浏览器要访问内网 IP不要停网卡只删默认路由即可。3. 建集群3.0 先清旧的command -v k3s echo 发现旧 k3s先卸载 || echo k3s 未安装如果有输出sudo /usr/local/bin/k3s-uninstall.sh sudo /usr/local/bin/k3s-killall.sh 2/dev/null || true command -v k3s || echo k3s 已卸【判据】80/443 必须干净ss -ltn | grep -E :80\b|:443\b || echo 无监听 sudo iptables -t nat -S | grep DNAT | grep -E dport (80|443) || echo 无 DNAT为什么必须清旧数据目录里的 traefik 清单会残留新集群起来后 80/443 会被它抢先接管ingress-nginx 就起不来。3.1 放入 airgap 镜像【做什么】把 k3s 自带组件的镜像放到约定目录。【为什么】k3s 首次启动会扫描这个目录自动导入离线环境没法联网拉。sudo mkdir -p /var/lib/rancher/k3s/agent/images/ sudo cp $OFFLINE/k3s/k3s-airgap-images-amd64.tar \ /var/lib/rancher/k3s/agent/images/ ls -lh /var/lib/rancher/k3s/agent/images/【你应该看到】总计 520M -rw-r--r-- 1 root root 520M ... k3s-airgap-images-amd64.tar【如果不对】检查$OFFLINE是否已设置、源文件是否存在。3.2 安装 k3s【做什么】装成系统服务禁用 traefik开放 kubeconfig 读权限。sudo cp $OFFLINE/k3s/k3s /usr/local/bin/k3s sudo chmod x /usr/local/bin/k3s sudo cp $OFFLINE/k3s/install.sh /tmp/install.sh sudo chmod x /tmp/install.sh sudo INSTALL_K3S_SKIP_DOWNLOADtrue \ INSTALL_K3S_EXEC--disable traefik --write-kubeconfig-mode 644 \ /tmp/install.sh【你应该看到】关键行[INFO] Skipping k3s download and verify ... [INFO] systemd: Starting k3s不应该出现Downloading/Failed to download。【如果不对】见第 8 章排查表 E1。3.3 验证集群systemctl is-active k3s kubectl get nodes -o wide kubectl get pods -A kubectl get storageclass kubectl -n kube-system get deploy traefik 21 || true【你应该看到】active 节点 Ready kube-system 里 coredns / local-path-provisioner / metrics-server 均 Running local-path (default) traefik 显示 NotFound解读active → k3s 服务在跑 节点 Ready → 集群可以接受调度 三个组件 Running → airgap 的 520M 镜像生效了 local-path → 有默认 StorageClassPVC 才能绑定 traefik NotFound → 已禁用80/443 留给 ingress-nginx如果kube-system里有Pending说明 airgap 镜像没生效回去看 3.1 的目录。3.4 检查 80/443 是否真的空闲【为什么】k8s / Docker / 旧 traefik 会通过 iptables DNAT 占端口ss看不到。ss -ltnp 2/dev/null | grep -E :80\b|:443\b || echo 80/443 无用户态监听 curl -s --max-time 3 http://127.0.0.1/ | head -c 100 || echo 连接失败正常 sudo iptables -t nat -S | grep DNAT | grep -E dport (80|443) \ || echo 无宿主机 80/443 DNAT【你应该看到】80/443 无用户态监听 连接失败正常 无宿主机 80/443 DNAT4. 装前置4.1 导入镜像到 containerd【做什么】把 14 个业务镜像 2 个 ingress 镜像导进 k3s 自己的 containerd。【为什么】k3s 和 Docker 的镜像存储是两套docker images有不代表 k3s 能用。cd $OFFLINE sudo k3s ctr images import teable-k8s-images.tar sudo k3s ctr images import ingress-nginx-images.tar【耗时】1–5 分钟会看到一行行unpacking ...done。【判据】sudo k3s ctr images ls | grep -E teable|opensandbox|postgres|redis|minio \ | awk {print $1} | sort【你应该看到】14 个例如docker.io/library/postgres:15.4 docker.io/library/redis:7.2.4 ghcr.io/teableio/minio-mc:RELEASE.2025-04-16T18-13-26Z ghcr.io/teableio/minio:RELEASE.2025-04-22T22-12-26Z ghcr.io/teableio/opensandbox-controller:v0.2.0 ghcr.io/teableio/opensandbox-egress:v1.0.12 ghcr.io/teableio/opensandbox-execd:v1.0.19-fix3 ghcr.io/teableio/opensandbox-image-committer:v0.1.0 ghcr.io/teableio/opensandbox-ingress:v1.0.7 ghcr.io/teableio/opensandbox-server:v0.2.0-fix11 ghcr.io/teableio/teable-app-runtime:20260919T055651Z ghcr.io/teableio/teable-infra-service:20261014T082748Z ghcr.io/teableio/teable:release.2026-10-14T12-10-48Z.3400 ghcr.io/teableio/teable-sandbox-agent:release.2026-10-14T12-10-48Z.3400计数模式要包含 minio/postgres/redissudo k3s ctr images ls | grep -cE teable|opensandbox|minio|postgres|redis【期望】≥ 14ingress 镜像sudo k3s ctr images ls | grep ingress-nginx【你应该看到】2 条controller:v1.15.1、kube-webhook-certgen:v1.6.9。留一份清单备用sudo k3s ctr images ls -q /tmp/images-in-containerd.txt4.2 建命名空间命名空间相当于给 Teable 的所有零件划了一层楼。kubectl create namespace $NS kubectl get ns $NS【你应该看到】namespace/opensandbox-system created NAME STATUS AGE opensandbox-system Active 0s4.3 生成自签证书【做什么】造一个本地 CA 4 张服务器证书。【为什么】本方案不用 cert-managerTLS 证书必须自己提供。cd $OFFLINE mkdir -p certs cd certs openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ -subj /CNteable-lan-ca/OTeable -out ca.crt mkcert() { local cn$1 san$2 printf subjectAltName%s\n $san /tmp/san.ext openssl req -new -newkey rsa:2048 -nodes -keyout $cn.key \ -subj /CN$cn/OTeable -out $cn.csr 2/dev/null openssl x509 -req -in $cn.csr -CA ca.crt -CAkey ca.key -CAcreateserial \ -days 3650 -sha256 -extfile /tmp/san.ext -out $cn.crt 2/dev/null echo ✓ $cn (SAN: $san) } mkcert $BASE_DOMAIN DNS:$BASE_DOMAIN mkcert infra.$BASE_DOMAIN DNS:infra.$BASE_DOMAIN mkcert app-wildcard DNS:*.app.$BASE_DOMAIN mkcert sandbox-$BASE_DOMAIN DNS:*.sandbox.$BASE_DOMAIN【你应该看到】✓ teable.lan (SAN: DNS:teable.lan) ✓ infra.teable.lan (SAN: DNS:infra.teable.lan) ✓ app-wildcard (SAN: DNS:*.app.teable.lan) ✓ sandbox-teable.lan (SAN: DNS:*.sandbox.teable.lan)【⚠️假 ✓ 警告】上面把 openssl 的报错重定向到了/dev/null目录不可写时它照样打印 ✓。所以一定要跑下面的 verifyls *.crt【你应该看到】5 个ca.crt 4 张。openssl x509 -in app-wildcard.crt -noout -text | grep -A1 Subject Alternative Name openssl x509 -in sandbox-$BASE_DOMAIN.crt -noout -text | grep -A1 Subject Alternative Name openssl verify -CAfile ca.crt $BASE_DOMAIN.crt \ infra.$BASE_DOMAIN.crt app-wildcard.crt sandbox-$BASE_DOMAIN.crt【你应该看到】两条 SAN 正确*.app.teable.lan/*.sandbox.teable.lanverify 四行全OK。确认属主ls -ld $OFFLINE/certs【判据】属于你的用户不是 root。4.4 创建 4 个 TLS Secret【为什么】chart 的 Ingress 里写死了 Secret 名差一个字就找不到证书。cd $OFFLINE/certs kubectl -n $NS create secret tls teable-tls \ --cert$BASE_DOMAIN.crt --key$BASE_DOMAIN.key kubectl -n $NS create secret tls infra.$BASE_DOMAIN-tls \ --certinfra.$BASE_DOMAIN.crt --keyinfra.$BASE_DOMAIN.key kubectl -n $NS create secret tls app-wildcard-tls \ --certapp-wildcard.crt --keyapp-wildcard.key kubectl -n $NS create secret tls sandbox.$BASE_DOMAIN-tls \ --certsandbox-$BASE_DOMAIN.crt --keysandbox-$BASE_DOMAIN.key【判据】kubectl -n $NS get secret | grep tls【你应该看到】恰好 4 行app-wildcard-tls kubernetes.io/tls 2 0s infra.teable.lan-tls kubernetes.io/tls 2 1s sandbox.teable.lan-tls kubernetes.io/tls 2 0s teable-tls kubernetes.io/tls 2 1s验证内容kubectl -n $NS get secret teable-tls -o jsonpath{.data.tls\.crt} \ | base64 -d | openssl x509 -noout -subject -dates【你应该看到】subjectCN teable.lan和有效期。4.5 配集群内 DNS【做什么】让 Pod 能解析infra.teable.lan。【为什么】沙箱启动后会回调这个地址解析不了相关功能直接失败。为什么不改宿主机 hosts宿主机只有一台改 hosts 就够但集群里有几十个 Pod只能改 CoreDNS。CUR$(kubectl -n kube-system get configmap coredns \ -o jsonpath{.data.NodeHosts} 2/dev/null || echo ) NEW$CUR $LAN_IP infra.$BASE_DOMAIN PAYLOAD$(python3 -c import json, sys print(json.dumps({data: {NodeHosts: sys.argv[1]}})) $NEW) kubectl -n kube-system patch configmap coredns --type merge -p $PAYLOAD【判据】kubectl -n kube-system get configmap coredns -o jsonpath{.data.NodeHosts}【你应该看到】包含一行192.168.72.128 infra.teable.lanPod 内验证需要带 nslookup 的镜像离线包里没有 busybox按本节配置 NodeHosts 信任即可。4.6 安装 ingress-nginx【做什么】装入口控制器让它接管 80/443。【为什么】6 个 Ingress 全是className: nginxtraefik 不认这些注解。cd $OFFLINE/ingress-nginx export KUBECONFIG/etc/rancher/k3s/k3s.yaml helm install ingress-nginx ./ingress-nginx \ -n ingress-nginx --create-namespace \ --set controller.image.pullPolicyIfNotPresent \ --set controller.admissionWebhooks.patch.image.pullPolicyIfNotPresent【为什么设 IfNotPresent】chart 默认可能是Always离线会尝试联网检查镜像然后失败。【你应该看到】NAME: ingress-nginx LAST DEPLOYED: ... NAMESPACE: ingress-nginx STATUS: deployed【判据】kubectl -n ingress-nginx get pods kubectl -n ingress-nginx get svc ingress-nginx-controller【你应该看到】controller 1/1 Running Service 的 EXTERNAL-IP 你的 LAN_IP不是 pending如果 30 秒后还是pendingkubectl -n kube-system get pods | grep svclb kubectl -n ingress-nginx describe svc ingress-nginx-controller | tail -204.7 前置总检echo ① 节点 Ready : $(kubectl get nodes --no-headers | awk {print $2}) echo ② StorageClass : $(kubectl get sc --no-headers | awk {print $1,$2}) echo ③ 业务镜像数 : $(sudo k3s ctr images ls | grep -cE teable|opensandbox|minio|postgres|redis) echo ④ 命名空间 : $(kubectl get ns $NS --no-headers | awk {print $2}) echo ⑤ TLS Secret 数 : $(kubectl -n $NS get secret --no-headers | grep -c tls) echo ⑥ ingress-nginx : $(kubectl -n ingress-nginx get deploy --no-headers) echo ⑦ 80/443 监听者 : $(ss -ltn | grep -cE :80\b|:443\b)#项期望①节点Ready②StorageClasslocal-path (default)③业务镜像数≥ 14④命名空间Active⑤TLS Secret恰好 4⑥ingress-nginx1/1⑦80/443 监听者0 个没关系但要确认 DNAT 已指向 ingress第 ⑦ 项补充确认sudo iptables -t nat -S | grep DNAT | grep -E dport (80|443)【你应该看到】两条 DNAT目标是10.42.x.xingress-nginx 的 svclb Pod IP。5. 部署 Teable5.1 镜像名对齐先确认不然后面必挂【为什么】k8s 按名字精确匹配镜像差一个前缀就是ImagePullBackOff。helm template $RELEASE $CHART_DIR -n $NS -f $VALUES \ | grep -oE image: [^] \ | sed s/image: //;s/$// | sort -u /tmp/chart-images.txt sudo k3s ctr images ls -q | sed s|^docker.io/||; s|^library/|| | sort -u /tmp/ctr-images.txt echo chart 引用但本地没有必须为空 comm -23 /tmp/chart-images.txt /tmp/ctr-images.txt【判据】下面这行必须是空的。有输出就说明镜像包里缺东西。归一化那一步是必要的本地是docker.io/library/postgreschart 里写的是postgres不归一化会误报一堆缺失。5.2 渲染检查helm template $RELEASE $CHART_DIR -n $NS -f $VALUES /tmp/pre.yaml echo 行数: $(wc -l /tmp/pre.yaml) echo Certificate 对象数: $(grep -c ^kind: Certificate /tmp/pre.yaml) echo IngressClass: grep ingressClassName: /tmp/pre.yaml | sort -u echo Ingress 主机名: grep -E ^\s- host: /tmp/pre.yaml echo Deployment: $(grep -c ^kind: Deployment /tmp/pre.yaml) echo Ingress: $(grep -c ^kind: Ingress /tmp/pre.yaml)【你应该看到】行数: 3277 Certificate 对象数: 0 IngressClass: ingressClassName: nginx ingressClassName: nginx Ingress 主机名: - host: *.sandbox.teable.lan - host: infra.teable.lan - host: infra.teable.lan - host: infra.teable.lan - host: infra.teable.lan - host: teable.lan Deployment: 9 Ingress: 6为什么Certificate必须是 0我们用的是自己造的 Secret没有装 cert-manager。出现 Certificate 对象说明values.yaml没配对。5.3 helm install绝不加--wait【为什么不能加--wait】MinIO 的建桶 Job 是 post-install hook --wait 会先等所有 Pod Ready才执行 hook 而 Teable 没桶就永远不 Ready → 等 Pod 等 Job等 Job 等 Pod死锁export KUBECONFIG/etc/rancher/k3s/k3s.yaml helm install $RELEASE $CHART_DIR -n $NS -f $VALUES【你应该看到】STATUS: deployed没有Error: timed out waiting for the condition。5.4 观察启动kubectl -n $NS get pods -w或者用轮询脚本for i in $(seq 1 60); do ready$(kubectl -n $NS get deploy --no-headers 2/dev/null \ | awk {split($2,a,/); if (a[1]a[2]) c} END {print c0}) echo 已等 $((i*10))s Deployment ready: $ready/9 [ ${ready:-0} -ge 9 ] break sleep 10 done kubectl -n $NS get pods kubectl -n $NS get deploy正常启动顺序第一批teable-postgres / teable-redis / teable-minio 第二批teable-minio-initCompleted一次性建桶 第三批teable-infra-service / teable-git-registry / opensandbox-* 最后 teable-teableNext.js 冷启动最慢1–3 分钟【判据】9 个 Deployment 全部 1/1 minio-init 是 Completed 没有 Pending / CrashLoopBackOff / ImagePullBackOff teable-teable 重启 1–2 次属正常6. 验证6.1 容器层kubectl -n $NS get pods kubectl -n $NS get pods --no-headers | grep -vE Running|Completed || echo 无异常 Pod【判据】输出无异常 Pod。6.2 入口层IP$(kubectl -n ingress-nginx get svc ingress-nginx-controller \ -o jsonpath{.status.loadBalancer.ingress[0].ip}) echo Ingress IP: $IP for h in $BASE_DOMAIN infra.$BASE_DOMAIN; do code$(curl -sk -o /dev/null -w %{http_code} --max-time 15 \ --resolve $h:443:$IP https://$h/) printf %-30s → %s\n $h $code done【你应该看到】Ingress IP: 192.168.72.128 teable.lan → 307 infra.teable.lan → 307【判据】200或307都正常307 是跳去登录/初始化。6.3 日志层找隐性联网kubectl -n $NS get pods --no-headers | awk {print $1} | while read -r p; do n$(kubectl -n $NS logs $p 21 \ | grep -ciE dial tcp|no such host|i/o timeout|ENOTFOUND|getaddrinfo || true) printf %-48s 网络失败线索: %s\n $p $n done【你应该看到】绝大多数是0。【例外】teable-minio-init可能有几条dial tcp 10.43.x.x:9000: connect: connection refused——这是启动时 MinIO 还没 ready 的正常竞态Job 最终Completed就不用管。【真问题】出现公网地址8.8.8.8、registry.npmjs.orgtimeout/失败才是隐性联网。6.4 功能层用 API 验证curl -sk -c /tmp/teable-cookie.txt -o /tmp/signup.json \ -w signup - %{http_code}\n \ --resolve teable.lan:443:$IP \ -X POST https://teable.lan/api/auth/signup \ -H Content-Type: application/json \ -d {email:adminexample.com,password:Passw0rd!2026} curl -sk -b /tmp/teable-cookie.txt -c /tmp/teable-cookie.txt -o /tmp/signin.json \ -w signin - %{http_code}\n \ --resolve teable.lan:443:$IP \ -X POST https://teable.lan/api/auth/signin \ -H Content-Type: application/json \ -d {email:adminexample.com,password:Passw0rd!2026} curl -sk -b /tmp/teable-cookie.txt -o /tmp/space.json \ -w space - %{http_code}\n \ --resolve teable.lan:443:$IP \ -X POST https://teable.lan/api/space \ -H Content-Type: application/json \ -d {name:my-first-space}【你应该看到】201 / 200 / 201。邮箱只能用一次重复注册会报错属正常。上线后第一件事把这个示例密码改掉。6.5 官方自检cd $HOME/offline/teable-deployment ./helm/doctor.sh $RELEASE $NS【注意路径】teable-deployment在~/offline/下不在$OFFLINEk8s-offline下。【你应该看到】末尾[ok] all checks passed.7. 浏览器打开与注册7.1 配客户端 hosts为什么服务端配不了域名是你自己起的公网 DNS 不认识只能让客户端认。WindowsC:\Windows\System32\drivers\etc\hostsmacOS / Linux/etc/hosts192.168.72.128 teable.lan 192.168.72.128 infra.teable.lan刷新 DNS# Windows ipconfig /flushdns # macOS sudo dscacheutil -flushcache需要*.app.teable.lan/*.sandbox.teable.lan时hosts 不够要用支持通配的 DNSdnsmasq。7.2 打开https://teable.lan证书警告 → 「高级」→「继续前往」第一个注册的账号自动是管理员邮箱要合法格式7.3 确认数据持久化建 Space → 建表 → 加一行 → 刷新页面数据还在7.4 控制台https://infra.teable.lan8. 排查表#现象原因解法E1install.sh 里出现DownloadingINSTALL_K3S_SKIP_DOWNLOAD没生效确认变量写在sudo之后、/tmp/install.sh之前E2kube-system 里有 Pendingairgap 镜像没生效检查/var/lib/rancher/k3s/agent/images/里有没有那个 520M 的 tarE380/443 被占旧 traefik 残留3.0 节重跑卸载并清/var/lib/rancher/k3sE4EXTERNAL-IP 是pendingsvclb 没起来kubectl -n kube-system get pods | grep svclbE5ImagePullBackOff镜像名对不上5.1 的comm -23找缺哪个E6helm install超时加了--wait去掉见 5.3E7Ingress 报找不到证书Secret 名不一致4.4 的判据里核对 4 个名字E8Pod 解析不了infra.xxxCoreDNS 没打 patch4.5 的判据E9页面能开但功能报错隐性联网6.3 的日志扫描9. 安全内网也要做① 改默认密码示例里的 adminexample.com / Passw0rd!2026 必须换 ② 数据库端口不要映射到 0.0.0.0postgres/redis 只在集群内可达 ③ 数据目录要备份local-path 的 PVC 落在 /var/lib/rancher/k3s/storage ④ 证书私钥权限certs/*.key 改 60010. 卸载helm uninstall $RELEASE -n $NS kubectl delete namespace $NS helm uninstall ingress-nginx -n ingress-nginx kubectl delete namespace ingress-nginx sudo /usr/local/bin/k3s-uninstall.sh sudo rm -rf /var/lib/rancher/k3s【判据】卸完 80/443 必须干净回到 3.0 的两条检查。