Skip to content

Conversation

jpjamespeterson
Copy link

Ⅰ. Describe what this PR did

Ⅱ. Does this pull request fix one issue?

Ⅲ. Why don't you add test cases (unit test/integration test)?

Ⅳ. Describe how to verify it

Ⅴ. Special notes for reviews

…g/observability: metrics hooks and KEDA/OTel/Prometheus helm templates; multi-cluster: Karmada CPP; volcano: job template; docs and samples; unit tests for tenancy
… adapter; feat(ai-proxy): batch trigger metric; tests: add basic observability and tenancy tests; ci: add GitHub Actions unit test workflow
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link

lingma-agents bot commented Aug 12, 2025

企业级功能增强:多集群、自动扩缩容、可观测性与多租户支持

变更概述
  • 新功能

    • 新增多集群支持(基于 Karmada),通过 ClusterPropagationPolicy 在多个集群之间同步 ConfigMap 和 CRD。
    • 引入 AI 自动扩缩容能力(基于 KEDA),支持根据 LLM 指标(如 token 使用量)进行自动扩缩容。
    • 新增 Gateway API 控制器适配器,用于显式绑定网关资源的协调逻辑。
    • 支持增强的可观测性功能,包括 Prometheus 指标(token 使用和延迟)和 OpenTelemetry 追踪。
    • 实现多租户支持,通过命名空间隔离网关资源,可通过 Helm 配置 controller.tenantNamespaces 启用。
    • 集成 Volcano 以支持批处理 AI 工作负载,可通过 Helm 启用并使用 pkg/volcano 提交批处理任务。
  • 重构

    • 将企业级功能模块化实现,如 Karmada、KEDA、Volcano 等通过构建标签(build tags)控制是否启用。
    • 引入 pkg/gateway 包,提供对 Gateway API 控制器的显式封装和协调接口。
  • 性能优化

    • 通过模块化构建(build tags)减少默认构建的依赖体积和运行时开销。
  • 问题修复

    • 无直接修复问题,但增强了系统的可扩展性和隔离性。
  • 依赖更新

    • 添加了 Prometheus、OpenTelemetry 相关依赖,用于指标和追踪功能。
    • 更新了模块依赖,如 go.mod 中新增了 github.com/prometheus/client_golanggo.opentelemetry.io/otel 等。
  • 安全增强

    • 无直接安全增强,但通过多租户命名空间隔离增强了资源访问控制。
  • 测试更新

    • 新增 observabilitytenancy 包的单元测试,验证指标记录和命名空间访问控制逻辑。
  • 文档

    • 新增多个文档,包括 docs/multicluster.mddocs/autoscaling.mddocs/observability.mddocs/tenancy.mddocs/volcano.md,详细说明各功能的使用方式和 Helm 配置。
  • UI/UX变更

    • 无前端或用户体验变更。
  • 配置调整

    • helm/core/values.yaml 中新增多个功能开关,如 karmada.enabledkeda.enabledobservability.prometheus.enabled 等。
    • helm/core/templates 中新增多个模板文件,如 karmada-cpp.yamlkeda-scaledobject.yamlotel-collector.yaml 等,用于部署相关资源。
  • 数据库变更

    • 无数据库相关变更。
  • 其他

    • 新增 GitHub Actions 工作流文件 .github/workflows/test.yml,用于自动化测试。
变更文件
文件路径 变更说明
.github/workflows/test.yml 新增 GitHub Actions 工作流,用于在 PR 和 push 到 feat/** 和 main 分支时运行单元测试。
README.md 新增企业级功能列表,包括多集群、AI 自动扩缩容、可观测性、多租户和批处理支持的简要说明。
docs/autoscaling.md 新增 KEDA 驱动的 AI 工作负载自动扩缩容文档,说明如何通过 Helm 启用和使用。
docs/multicluster.md 新增 Karmada 多集群配置同步文档,说明如何启用和使用 Karmada 集成。
docs/observability.md 新增 AI 工作负载可观测性文档,说明如何启用 Prometheus 指标和 OpenTelemetry 追踪。
docs/tenancy.md 新增多租户支持文档,说明如何通过命名空间隔离资源。
docs/volcano.md 新增 Volcano 批处理 AI 工作负载文档,说明如何启用和使用 Volcano 集成。
go.mod 新增 Prometheus 和 OpenTelemetry 相关依赖,用于指标和追踪功能。
helm/​core/​templates/​controller-deployment.​yaml 在控制器部署中新增 `HIGRESS_TENANT_NAMESPACES` 环境变量,用于多租户命名空间隔离。
helm/​core/​templates/​karmada-cpp.​yaml 新增 Karmada `ClusterPropagationPolicy` 模板,用于同步 Higress ConfigMap。
helm/​core/​templates/​keda-scaledobject.​yaml 新增 KEDA `ScaledObject` 模板,用于基于 Prometheus 指标的自动扩缩容。
helm/​core/​templates/​otel-collector.​yaml 新增 OpenTelemetry Collector 部署模板,用于收集和导出追踪数据。
helm/​core/​templates/​prometheus.​yaml 新增 Prometheus `ServiceMonitor` 模板,用于监控 Higress 指标。
helm/​core/​templates/​volcano-job.​yaml 新增 Volcano 批处理任务示例模板,用于演示批处理工作负载。
helm/core/values.yaml 新增多个企业级功能的 Helm 配置项,包括 Karmada、KEDA、Observability 和 Volcano。
pkg/autoscaler/keda_scaler.go 新增 KEDA 自动扩缩容实现,通过 Prometheus 指标创建或更新 `ScaledObject`。
pkg/autoscaler/keda_stub.go 新增 KEDA 自动扩缩容的 stub 实现,用于未启用 KEDA 时的构建。
pkg/gateway/controller.go 新增 Gateway API 控制器适配器,用于显式绑定和协调网关资源。
pkg/​ingress/​kube/​gateway/​istio/​controller.​go 在 Istio 网关控制器中新增多租户命名空间过滤逻辑,支持通过环境变量 `HIGRESS_TENANT_NAMESPACES` 控制资源访问。
pkg/karmada/sync.go 新增 Karmada 资源同步实现,用于同步 ConfigMap 和 CRD 到多个集群。
pkg/karmada/sync_stub.go 新增 Karmada 资源同步的 stub 实现,用于未启用 Karmada 时的构建。
pkg/observability/metrics.go 新增 Prometheus 指标实现,用于记录 AI token 使用量和模型延迟。
pkg/observability/tracing.go 新增 OpenTelemetry 追踪实现,用于配置 OTLP 追踪导出。
pkg/tenancy/manager.go 新增多租户管理器,用于验证命名空间隔离和检查资源访问权限。
pkg/volcano/scheduler.go 新增 Volcano 批处理任务调度实现,用于提交批处理任务到集群。
pkg/volcano/scheduler_stub.go 新增 Volcano 批处理调度的 stub 实现,用于未启用 Volcano 时的构建。
plugins/​wasm-go/​extensions/​ai-proxy/​main.​go 在 AI 代理插件中新增指标记录逻辑,用于记录 token 使用量和请求延迟。
plugins/​wasm-go/​extensions/​ai-proxy/​metrics.​go 新增 Wasm 插件指标实现,用于定义和记录 Prometheus 指标。
samples/​keda/​scaledobject.​yaml 新增 KEDA `ScaledObject` 示例文件,用于演示自动扩缩容配置。
test/karmada/sample_cpp.yaml 新增 Karmada `ClusterPropagationPolicy` 示例文件,用于演示多集群配置同步。
test/​observability/​metrics_​test.​go 新增可观测性指标测试,验证指标记录功能。
test/tenancy/manager_test.go 新增多租户管理器测试,验证命名空间隔离和访问控制逻辑。
时序图
sequenceDiagram
    participant HC as Helm Chart
    participant KS as KedaScaler
    participant VS as VolcanoScheduler
    participant KM as KarmadaSync
    participant TM as TenantManager
    participant OM as ObservabilityMetrics
    participant OT as ObservabilityTracing

    HC->>KS: Enable KEDA via Helm values
    KS->>KS: Build with -tags keda
    KS->>KS: Create/Update ScaledObject

    HC->>VS: Enable Volcano via Helm values
    VS->>VS: Build with -tags volcano
    VS->>VS: Schedule Batch Job

    HC->>KM: Enable Karmada via Helm values
    KM->>KM: Build with -tags karmada
    KM->>KM: Sync ConfigMap/CRD

    HC->>TM: Set tenantNamespaces via Helm
    TM->>TM: Validate and check namespace access

    HC->>OM: Enable Prometheus via Helm
    OM->>OM: Record token usage and latency

    HC->>OT: Enable OTel Collector via Helm
    OT->>OT: Setup tracing with OTLP exporter
Loading

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @lingma-agents 分析这个方法的性能瓶颈并提供优化建议。

  • @lingma-agents 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @lingma-agents 请总结上述讨论并提出解决方案。

  • @lingma-agents 请根据讨论内容生成优化代码。

Copy link

@lingma-agents lingma-agents bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔎 代码评审报告

🎯 评审意见概览
严重度 数量 说明
🔴 Blocker 0 阻断性问题,需立即修复。例如:系统崩溃、关键功能不可用或严重安全漏洞。
🟠 Critical 0 严重问题,高优先级修复。例如:核心功能异常或性能瓶颈影响用户体验。
🟡 Major 2 主要问题,建议修复。例如:非核心功能缺陷或代码维护性较差。
🟢 Minor 0 次要问题,酬情优化。例如:代码格式不规范或注释缺失。

总计: 2 个问题

📋 评审意见详情
💡 代码实现建议
以下是文件级别的代码建议,聚焦于代码的可读性、可维护性和潜在问题。
🔹 pkg/autoscaler/keda_scaler.go (1 💬)
🔹 pkg/karmada/sync.go (1 💬)
🚀 架构设计建议
以下是对代码架构和设计的综合分析,聚焦于跨文件交互、系统一致性和潜在优化空间。
🔍1. 多租户隔离逻辑不完整,存在越权访问风险

pkg/ingress/kube/gateway/istio/controller.go 中实现了基于命名空间的租户隔离逻辑,但该逻辑仅在 List 和 Reconcile 方法中部分应用。例如,在 List 方法中对 Gateway 和 VirtualService 进行了过滤,但未对其他资源类型(如 HTTPRoute、TCPRoute 等)进行相同处理。此外,Reconcile 方法中的过滤逻辑虽然覆盖了多种资源,但未与 List 方法保持一致,可能导致数据泄露或越权访问。建议统一租户隔离策略,并确保所有相关资源类型都受到保护。

📌 关键代码

// Tenant namespace filtering
	allowed := []string{}
	if c.client != nil && c.client.RESTConfig() != nil { // placeholder: plumb allowed list from options or env
		// For now, allow the requested namespace only when specified
		if namespace != "" {
			allowed = []string{namespace}
		}
	}
	tenantMgr := &tenancy.TenantManager{}

	switch typ {
	case gvk.Gateway:
		items := filterNamespace(c.state.Gateway, namespace)
		if len(allowed) == 0 {
			return items
		}
		var res []config.Config
		for _, it := range items {
			if tenantMgr.AllowedNamespace(it.Namespace, allowed) {
				res = append(res, it)
			}
		}
		return res
	case gvk.VirtualService:
		items := filterNamespace(c.state.VirtualService, namespace)
		if len(allowed) == 0 {
			return items
		}
		var res []config.Config
		for _, it := range items {
			if tenantMgr.AllowedNamespace(it.Namespace, allowed) {
				res = append(res, it)
			}
		}
		return res
	default:
		return nil
	}
// Apply namespace filtering on inputs if allowed namespaces defined
	if len(allowed) > 0 {
		filter := func(in []config.Config) []config.Config {
			var out []config.Config
			for _, it := range in {
				if tenantMgr.AllowedNamespace(it.Namespace, allowed) {
					out = append(out, it)
				}
			}
			return out
		}
		gateway = filter(gateway)
		httpRoute = filter(httpRoute)
		tcpRoute = filter(tcpRoute)
		tlsRoute = filter(tlsRoute)
	}

⚠️ 潜在风险

可能导致不同租户间的数据泄露或越权访问,影响系统的安全性和合规性。

🔍2. 构建标签依赖管理不当,可能引发编译或运行时错误

项目引入了多个可选功能模块(如 KEDA、Karmada、Volcano),并通过 Go 构建标签(build tags)控制其启用状态。然而,pkg/autoscaler/keda_scaler.go、pkg/karmada/sync.go 和 pkg/volcano/scheduler.go 等文件直接依赖于这些外部库,而没有适当的抽象层或接口隔离。这可能导致在不启用相应构建标签的情况下编译失败,或者在运行时因缺少依赖而导致程序崩溃。建议通过定义通用接口并为每个模块提供实现的方式来解耦依赖关系。

📌 关键代码

//go:build keda

package autoscaler

import (
	context "context"
	"fmt"

	kedav1alpha1 "github.com/kedacore/keda/v2/apis/keda/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)
//go:build karmada

package karmada

import (
	context "context"

	policyv1alpha1 "github.com/karmada-io/api/policy/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)
//go:build volcano

package volcano

import (
	context "context"

	batchv1alpha1 "volcano.sh/apis/pkg/apis/batch/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
)

⚠️ 潜在风险

可能导致编译失败或运行时错误,增加系统维护成本和部署复杂度。

🔍3. 监控指标命名不一致,影响可观测性

在 pkg/observability/metrics.go 中定义的 Prometheus 指标名称与 plugins/wasm-go/extensions/ai-proxy/metrics.go 中定义的指标名称存在不一致。例如,pkg/observability/metrics.go 使用 'higress_ai_token_usage_total' 和 'higress_ai_model_latency_seconds',而 plugins/wasm-go/extensions/ai-proxy/metrics.go 使用 'higress_ai_token_usage_total' 和 'higress_ai_model_latency_ms_p50' 等。这种不一致性会使得监控和告警规则难以统一管理,降低系统的可观测性。建议统一指标命名规范,并确保所有模块使用相同的命名方式。

📌 关键代码

TokenUsage: prometheus.NewCounter(prometheus.CounterOpts{
				Namespace: "higress",
				Subsystem: "ai",
				Name:      "token_usage_total",
				Help:      "Total number of LLM tokens processed by Higress.",
			}),
			ModelLatency: prometheus.NewHistogram(prometheus.HistogramOpts{
				Namespace: "higress",
				Subsystem: "ai",
				Name:      "model_latency_seconds",
				Help:      "Latency of LLM requests handled by Higress.",
				Buckets:   prometheus.DefBuckets,
			}),
const (
	metricTokenUsage       = "higress_ai_token_usage_total"
	metricLatencyMilliP50  = "higress_ai_model_latency_ms_p50"
	metricLatencyMilliP95  = "higress_ai_model_latency_ms_p95"
	metricLatencyMilliP999 = "higress_ai_model_latency_ms_p999"
	ctxStartTimeKey        = "ai_proxy_start_time"
)

⚠️ 潜在风险

导致监控和告警规则混乱,影响问题排查效率和系统稳定性评估。

审查详情
📒 文件清单 (32 个文件)
新增: 26 个文件
📝 变更: 6 个文件

✅ 新增文件:

  • .github/workflows/test.yml
  • docs/autoscaling.md
  • docs/multicluster.md
  • docs/observability.md
  • docs/tenancy.md
  • docs/volcano.md
  • helm/core/templates/karmada-cpp.yaml
  • helm/core/templates/keda-scaledobject.yaml
  • helm/core/templates/otel-collector.yaml
  • helm/core/templates/prometheus.yaml
  • helm/core/templates/volcano-job.yaml
  • pkg/autoscaler/keda_scaler.go
  • pkg/autoscaler/keda_stub.go
  • pkg/gateway/controller.go
  • pkg/karmada/sync.go
  • pkg/karmada/sync_stub.go
  • pkg/observability/metrics.go
  • pkg/observability/tracing.go
  • pkg/tenancy/manager.go
  • pkg/volcano/scheduler.go
  • pkg/volcano/scheduler_stub.go
  • plugins/wasm-go/extensions/ai-proxy/metrics.go
  • samples/keda/scaledobject.yaml
  • test/karmada/sample_cpp.yaml
  • test/observability/metrics_test.go
  • test/tenancy/manager_test.go

📝 变更文件:

  • README.md
  • go.mod
  • helm/core/templates/controller-deployment.yaml
  • helm/core/values.yaml
  • pkg/ingress/kube/gateway/istio/controller.go
  • plugins/wasm-go/extensions/ai-proxy/main.go

💡 小贴士

与 lingma-agents 交流的方式

📜 直接回复评论
直接回复本条评论,lingma-agents 将自动处理您的请求。例如:

  • 在当前代码中添加详细的注释说明。

  • 请详细介绍一下你说的 LRU 改造方案,并使用伪代码加以说明。

📜 在代码行处标记
在文件的特定位置创建评论并 @lingma-agents。例如:

  • @lingma-agents 分析这个方法的性能瓶颈并提供优化建议。

  • @lingma-agents 对这个方法生成优化代码。

📜 在讨论中提问
在任何讨论中 @lingma-agents 来获取帮助。例如:

  • @lingma-agents 请总结上述讨论并提出解决方案。

  • @lingma-agents 请根据讨论内容生成优化代码。

Comment on lines +43 to +47
Metadata: map[string]string{
"serverAddress": "http://prometheus-server.monitoring.svc.cluster.local",
"metricName": metricName,
"threshold": fmt.Sprintf("%d", targetValue),
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KEDA自动伸缩器应允许配置Prometheus服务器地址,而不是硬编码。

🟡 Major | 🧹 Code Smells

📋 问题详情

当前代码在ScaleByLLMMetrics方法中硬编码了Prometheus服务器地址,这使得配置不够灵活。应该允许通过参数或环境变量来配置服务器地址。

💡 解决方案

应该允许通过参数或环境变量来配置Prometheus服务器地址,而不是硬编码。这样可以提高配置的灵活性。

- Metadata: map[string]string{
-   "serverAddress": "http://prometheus-server.monitoring.svc.cluster.local",
-   "metricName":    metricName,
-   "threshold":     fmt.Sprintf("%d", targetValue),
- },
+ Metadata: map[string]string{
+   "serverAddress": os.Getenv("PROMETHEUS_SERVER_ADDRESS"),
+   "metricName":    metricName,
+   "threshold":     fmt.Sprintf("%d", targetValue),
+ },

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

Comment on lines +47 to +49
Placement: &policyv1alpha1.Placement{ // all clusters by default
ClusterAffinity: &policyv1alpha1.ClusterAffinity{},
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Karmada同步器应允许配置集群亲和性,而不是硬编码为所有集群。

🟡 Major | 🧹 Code Smells

📋 问题详情

当前代码在SyncConfigMapSyncCRD方法中硬编码了集群亲和性为所有集群,这可能不符合实际需求。应该允许通过参数或配置来指定集群亲和性。

💡 解决方案

应该允许通过参数或配置来指定集群亲和性,而不是硬编码为所有集群。这样可以提高配置的灵活性。

- Placement: &policyv1alpha1.Placement{ // all clusters by default
-   ClusterAffinity: &policyv1alpha1.ClusterAffinity{},
- },
+ Placement: &policyv1alpha1.Placement{
+   ClusterAffinity: &policyv1alpha1.ClusterAffinity{
+     ClusterNames: []string{os.Getenv("KARMADA_CLUSTER_NAMES")},
+   },
+ },

您的反馈对我们很重要!(建议右键在新标签页中打开以下链接)

有用意见👍无用意见👎错误意见❌

@johnlanni
Copy link
Collaborator

@jpjamespeterson Could you provide some background information on this feature? Also, please sign the CLA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants