You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tanka/Jsonnet:多Grafana实例配置模板导入与循环调用问题

解决Tanka中Grafana ConfigMap复用的问题

问题根源

Jsonnet的import是静态解析的,不支持动态计算的导入路径,也无法在导入阶段传递instance这类动态变量——这就是你遇到"computed imports are not allowed"错误的原因。正确的做法是将ConfigMap的生成逻辑封装成可接收参数的函数,放在单独文件中复用,而非直接导入静态配置。

解决方案步骤

1. 提取ConfigMap逻辑到单独文件

创建grafana-configmap.libsonnet文件,将原来内联的ConfigMap逻辑封装为函数,接收instance和全局 ingress 配置作为参数:

local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet';

// 生成Grafana ini ConfigMap的函数
newGrafanaIniConfigMap(instance, ingressConfig):: {
  local configMap = k.core.v1.configMap,
  grafana_ini: configMap.new(
    'grafana-ini-' + instance.handle, {
      'grafana.ini': std.manifestIni(
        {
          main: {
            app_mode: 'production',
            instance_name: instance.handle,
          },
          sections: {
            server: {
              protocol: 'http',
              http_port: '3000',
              domain: 'dashboard.' + ingressConfig.realm + '.' + ingressConfig.tld + '/' + instance.handle + '/',
              root_url: ingressConfig.protocol + 'dashboard.' + ingressConfig.realm + '.' + ingressConfig.tld + '/' + instance.handle + '/',
              serve_from_sub_path: true,
            },
          },
        }
      )
    }
  ),
}

2. 修改主文件调用函数

在原主文件中导入该函数,在生成每个Grafana实例时,传入对应的instance和全局配置:

local tanka = import 'github.com/grafana/jsonnet-libs/tanka-util/main.libsonnet';
local helm = tanka.helm.new(std.thisFile);

local k = import 'github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet';
// 导入单独的ConfigMap生成函数
local grafanaConfigMap = import 'grafana-configmap.libsonnet';

(import 'config.libsonnet') +

{
  local configMap = k.core.v1.configMap,
  local container = k.core.v1.container,
  local stateful = k.apps.v1.statefulSet,
  local ingrdatasourcesess = k.networking.v1.ingress,
  local port = k.core.v1.containerPort,
  local service = k.core.v1.service,
  local pvc = k.core.v1.persistentVolumeClaim,

  local ports = [port.new('http', 3000)],

  grafana: {
    g(instance):: {

      local this = self,
      // 调用函数生成当前实例的ConfigMap
      local grafanaIniConfig = grafanaConfigMap.newGrafanaIniConfigMap(instance, $._config.ingress),

      deployment:
        stateful.new(
          name='grafana-' + instance.handle,
          replicas=1,
          containers=[
            container.new(
              name='grafana-' + instance.handle,
              image=$._config.grafana.image + instance.theme + ':' + $._config.grafana.version
            )
            + container.withPorts(ports),
          ],
        )
        + stateful.metadata.withLabels({ 'io.kompose.service': 'grafana-' + instance.handle })
        + stateful.configMapVolumeMount(grafanaIniConfig.grafana_ini, '/etc/grafana/grafana.ini', k.core.v1.volumeMount.withSubPath('grafana.ini'))
        + stateful.spec.withServiceName('grafana-' + instance.handle)
        + stateful.spec.selector.withMatchLabels({ 'io.kompose.service': 'grafana-' + instance.handle })
        + stateful.spec.template.metadata.withLabels({ 'io.kompose.service': 'grafana-' + instance.handle })
        + stateful.spec.template.spec.withImagePullSecrets({
          name: 'registry.gitlab.com',
        })
        + stateful.spec.template.spec.withRestartPolicy('Always'),    

      service:
        k.util.serviceFor(self.deployment)
        + service.mixin.spec.withType('ClusterIP'),

      configMaps: grafanaIniConfig,
    },
    deploys: [self.g(instance) for instance in $._config.grafana.instances],
  },
}

核心优势

  • 规避了Jsonnet静态导入的限制,通过函数动态生成每个实例的ConfigMap
  • 代码结构更清晰,ConfigMap逻辑独立维护,可读性和可维护性提升
  • 函数可在多个场景复用,后续新增Grafana实例或修改配置只需调整函数逻辑

内容的提问来源于stack exchange,提问作者strowi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 12:54:21