feat(logs): 数据源连接方式自动探测
部署完成及启动时实测 cluster-svc(API proxy) 与 url 直连, 选择可用方式并落库,兼容平台/Loki 分别在主机或集群内的组合。
This commit is contained in:
1 parent
b433b5f9dd
commit
7624baa564
3 files changed
+61
No files matched your search
@@ -84,6 +84,8 @@ func main() {
|
|||||||
|
|
||||||
// 清理旧版本删除部署后残留的托管数据源(幂等)
|
// 清理旧版本删除部署后残留的托管数据源(幂等)
|
||||||
services.CleanupOrphanManagedLogSources()
|
services.CleanupOrphanManagedLogSources()
|
||||||
|
// 异步重新探测运行中部署的数据源连接方式(平台/Loki 可能在主机或集群内)
|
||||||
|
go services.EnsureLogSourcesForRunningDeployments()
|
||||||
// 补齐/升级内置告警规则(幂等):启动即执行,存量环境也能拿到「默认启用+绑默认通道」
|
// 补齐/升级内置告警规则(幂等):启动即执行,存量环境也能拿到「默认启用+绑默认通道」
|
||||||
seed.SeedAlertRules()
|
seed.SeedAlertRules()
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -485,6 +486,32 @@ func CleanupOrphanManagedLogSources() {
|
|||||||
db.Unlock()
|
db.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AutoDetectLogSource 探测数据源的可用连接方式,返回最终选择(cluster-svc / url)。
|
||||||
|
//
|
||||||
|
// 交付环境组合很多:平台可能在主机或集群内,Loki 也可能在主机或集群内。
|
||||||
|
// cluster-svc 走 kube-apiserver 的 service proxy,不依赖集群 DNS;url 直连
|
||||||
|
// 则需要平台能访问到该地址。这里按「代理优先、URL 兜底」实测,避免按部署
|
||||||
|
// 模式硬编码导致某种组合连不上。
|
||||||
|
func AutoDetectLogSource(ctx context.Context, src *models.LogSource) string {
|
||||||
|
if src.ClusterID != nil {
|
||||||
|
probe := *src
|
||||||
|
probe.TargetType = "cluster-svc"
|
||||||
|
if _, status, err := lokiProxyGET(ctx, &probe, "/ready", nil); err == nil && status == 200 {
|
||||||
|
src.TargetType = "cluster-svc"
|
||||||
|
return "cluster-svc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if src.URL != "" {
|
||||||
|
probe := *src
|
||||||
|
probe.TargetType = "url"
|
||||||
|
if _, status, err := lokiProxyGET(ctx, &probe, "/ready", nil); err == nil && status == 200 {
|
||||||
|
src.TargetType = "url"
|
||||||
|
return "url"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// EnsureLogSourceForDeployment 部署成功后自动注册查询数据源(host→url;k8s→cluster-svc)。
|
// EnsureLogSourceForDeployment 部署成功后自动注册查询数据源(host→url;k8s→cluster-svc)。
|
||||||
// 已存在同名数据源时:平台托管的自动刷新连接信息,用户手填的不覆盖。
|
// 已存在同名数据源时:平台托管的自动刷新连接信息,用户手填的不覆盖。
|
||||||
func EnsureLogSourceForDeployment(d *models.LokiDeployment) {
|
func EnsureLogSourceForDeployment(d *models.LokiDeployment) {
|
||||||
@@ -506,8 +533,18 @@ func EnsureLogSourceForDeployment(d *models.LokiDeployment) {
|
|||||||
// 这里换成主机真实 IP,平台才能连上。
|
// 这里换成主机真实 IP,平台才能连上。
|
||||||
target.URL = reachableEndpoint(d)
|
target.URL = reachableEndpoint(d)
|
||||||
target.ClusterID = nil
|
target.ClusterID = nil
|
||||||
|
} else {
|
||||||
|
// k8s 部署:集群内 Service 地址也记下来,作为 URL 直连候选
|
||||||
|
target.URL = d.Endpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 实测可用性后决定连接方式:主机/集群内平台、主机/集群内 Loki 都兼容
|
||||||
|
detectCtx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
|
||||||
|
if method := AutoDetectLogSource(detectCtx, target); method != "" {
|
||||||
|
log.Printf("[log-source] %q 自动选择连接方式: %s", target.Name, method)
|
||||||
|
}
|
||||||
|
cancel()
|
||||||
|
|
||||||
db := repository.GetDB()
|
db := repository.GetDB()
|
||||||
db.Lock()
|
db.Lock()
|
||||||
for i := range db.LogSources {
|
for i := range db.LogSources {
|
||||||
|
|||||||
@@ -236,3 +236,25 @@ kubectl -n log get secret lokistack-token -o jsonpath='{.data.token}' | base64 -
|
|||||||
- 如果集群策略要求短期凭证,可改用 `kubectl -n log create token lokistack --duration=24h` 定期轮换。
|
- 如果集群策略要求短期凭证,可改用 `kubectl -n log create token lokistack --duration=24h` 定期轮换。
|
||||||
- 上面的 Namespace 由管理员创建,平台 Token 本身没有集群级权限;只有确实需要平台自建命名空间时,才额外授予 `namespaces: create/get` 的 ClusterRole(create 无法按名称限制,预建 `log` 更安全)。
|
- 上面的 Namespace 由管理员创建,平台 Token 本身没有集群级权限;只有确实需要平台自建命名空间时,才额外授予 `namespaces: create/get` 的 ClusterRole(create 无法按名称限制,预建 `log` 更安全)。
|
||||||
|
|
||||||
|
|
||||||
|
## 10. 数据源连接方式(部署后自动探测)
|
||||||
|
|
||||||
|
平台自动注册的数据源不再按部署模式硬编码,部署完成后会实测两种方式:
|
||||||
|
|
||||||
|
1. **cluster-svc**:经 kube-apiserver 的 service proxy 访问
|
||||||
|
`/<namespace>/services/loki:3100/proxy`,不依赖集群 DNS / ClusterIP 直通;
|
||||||
|
2. **url**:直接访问 Loki 地址(Service DNS、主机 IP:3100 或 Ingress 域名)。
|
||||||
|
|
||||||
|
先试 cluster-svc,失败再试 url,选通的写入数据源。
|
||||||
|
|
||||||
|
| 平台位置 | Loki 位置 | 实际可用方式 |
|
||||||
|
|---|---|---|
|
||||||
|
| 集群内 | 集群内 | cluster-svc |
|
||||||
|
| 主机 | 集群内 | cluster-svc(平台能访问 apiserver:6443 时);否则 url(NodePort/Ingress) |
|
||||||
|
| 集群内 | 主机 | url(主机 IP:3100,需网络可达) |
|
||||||
|
| 主机 | 主机 | url |
|
||||||
|
|
||||||
|
注意:
|
||||||
|
- `cluster-svc` 需要凭据具备 `services/proxy` 权限(本文第 9 节的 Role 已包含);
|
||||||
|
- 平台与 API Server / Loki 之间的网络必须放行;跨 VPC 时走 VPN、专线或公网 Ingress;
|
||||||
|
- 自动探测只决定“连接方式”,不会隐藏数据源;连接失败时“测试连接”会返回具体错误。
|
||||||
Reference in new issue
Block a user