=== 一、主机「测试连接」永远显示旧错误(真实 bug)===
HostService.Validate 的失败分支也写 status=active,且从不写 statusMessage:
if info, err := client.GetHostInfo(ctx); err == nil { 更新 os/arch }
else { s.Update(id, {status:"active"}) } // ← 失败也标记成功
结果:连不上也显示正常,页面永远停在几分钟前的旧错误文案,
用户改了 IP 再点测试,还以为"改了还是不行"。
改为区分成功/失败并写清原因:
成功 → status=active + os/arch + statusMessage="连接成功"
失败 → status=error + statusMessage=FormatSSHError(err)
=== 二、回环地址在平台里必然连不上 ===
平台跑在容器/Pod 内,127.0.0.1 指向平台自身。
- 新建主机时拦截:hostIP 为 127.0.0.1/localhost/::1 直接报错并解释原因
- 前端表单同步校验 + 文案
- SSH 错误映射补充:连接被拒绝时提示可能是地址填了回环
=== 三、主机模式采集系统日志(两处会导致采集失败)===
1. pipeline 一律套 cri 阶段:cri 只认容器运行时格式,
套在 /var/log/messages 这类 syslog 上会取不到时间戳、整行被丢。
→ appPipelineStages() 按路径判断:容器日志用 cri,普通文本日志只做限流。
2. promtailExternalLabels 写死 8 空格缩进:主机模板 external_labels 只有 4 空格,
一旦给采集器配置了标签就生成非法 YAML,Promtail 装不上。
→ 增加 indent 参数,主机 6 空格 / DaemonSet 8 空格。
3. 新增 system 采集任务:
/var/log/{messages,secure,cron,maillog,syslog,dmesg}
正则解析 syslog 时间戳(Jan _2 15:04:05,Asia/Shanghai)+ 限流
测试:TestHostPromtailConfigValid / CRIPathKeepsCRIStage / PlainFileHasNoCRIStage
TestPromtailManifestParses 全部通过
=== 四、资源用量 CPU 解析(nanocores)===
metrics-server 返回的 CPU 常是纳核(如 "194533645n"=194.5m)。
原解析只处理 "m",导致 194 亿核、页面出现"CPU 已达 limit 的 4863341125%"。
→ parseQuantityMilli 支持 n/u/m/整核
实测:CPU 当前=178m,峰值=3300m,建议"峰值占 limit 82%,可考虑提前扩容"
=== 五、其他 ===
- 添加集群默认改用 Token 认证(最小权限、可随时吊销)
- RBAC 片段补 metrics.k8s.io(资源面板需要,独立 API 组常被漏授)
- 文案去掉 Grafana 需求描述(平台自身不部署 Grafana)
镜像:lghost/lokistack:latest + v0.1 = sha256:7bddd0f4d1f1
35 lines
1.3 KiB
Go
35 lines
1.3 KiB
Go
package services
|
|
|
|
import "strings"
|
|
|
|
// FormatSSHError 将底层 SSH 错误翻译为中文友好提示,便于用户排查
|
|
func FormatSSHError(err error) string {
|
|
if err == nil {
|
|
return ""
|
|
}
|
|
msg := err.Error()
|
|
lower := strings.ToLower(msg)
|
|
|
|
switch {
|
|
case strings.Contains(lower, "i/o timeout") ||
|
|
strings.Contains(lower, "deadline exceeded") ||
|
|
strings.Contains(lower, "connection timed out"):
|
|
return "连接超时,请检查主机网络或 SSH 端口是否可达"
|
|
case strings.Contains(lower, "connection refused"):
|
|
return "连接被拒绝:目标端口未开放、SSH 服务未运行,或地址填了 127.0.0.1" +
|
|
"(平台在容器内运行,回环地址指向平台自身,请改成服务器的实际 IP)"
|
|
case strings.Contains(lower, "no such host") ||
|
|
strings.Contains(lower, "no route to host"):
|
|
return "无法解析或到达目标主机,请检查 IP 地址"
|
|
case strings.Contains(lower, "permission denied") ||
|
|
strings.Contains(lower, "unable to authenticate") ||
|
|
strings.Contains(lower, "handshake") ||
|
|
strings.Contains(lower, "password"):
|
|
return "认证失败,请检查用户名、密码或 SSH 密钥"
|
|
case strings.Contains(lower, "no supported methods"):
|
|
return "SSH 协商失败,服务端未支持当前认证方式"
|
|
default:
|
|
return msg
|
|
}
|
|
}
|