SkyWalking OAP 动态配置:基于 Kubernetes ConfigMap 的动态配置中心实践与源码解析
2026/9/20 16:15:42 网站建设 项目流程
  • 可观测性
  • APM
  • 链路追踪
  • 指标监控
  • 日志分析
  • 微服务

【免费下载链接】skywalking

APM, Application Performance Monitoring System

项目地址:https://gitcode.com/gh_mirrors/sk/skywalking
点击查看免费下载

本篇指南围绕 SkyWalking OAP 的 Kubernetes ConfigMap 动态配置实现(k8s-configmap)展开,讲解如何以 ConfigMap 作为动态配置中心(DCC),在不重启 OAP 的情况下动态下发与热更新告警规则、慢 SQL 阈值、Apdex 阈值、端点分组规则等配置。读者阅读后可以掌握application.yml中相关参数的含义与配置方法、Single/Group 两类配置在 ConfigMap 中的组织与存储方式,并能通过源码理解其底层同步机制与实现原理。

动态配置机制概述

SkyWalking OAP 的大部分配置通过application.yml和操作系统环境变量设置,但部分配置支持由上游管理系统动态下发(Dynamic Configuration)。该功能依赖上游服务,因此默认处于关闭状态,需要通过configuration.selector显式启用。

在 dynamic-config.md 中可以看到,SkyWalking 支持两类动态配置:

  • Single Configuration(单一配置):一个配置键对应一个配置值,逻辑结构为{configKey}:{configValue}
  • Group Configuration(分组配置):一个配置键对应一组子配置项,逻辑结构为{configKey}: |{subItemKey1}:{subItemValue1} ...

Kubernetes ConfigMap 是官方支持的动态配置中心实现之一,除此之外还支持 Zookeeper、Etcd、Consul、Apollo、Nacos 以及内置的 Dynamic Configuration Service(DCS)。对于已经运行在 Kubernetes 集群中的 SkyWalking 部署,直接复用 ConfigMap 作为配置中心可以避免引入额外的中间件依赖。

启用 ConfigMap 动态配置

在 OAP 的application.ymlconfiguration段中进行如下配置:

configuration: selector: ${SW_CONFIGURATION:k8s-configmap} # [example] oap-server/server-configuration/configuration-k8s-configmap/src/test/resources/skywalking-dynamic-configmap.example.yaml k8s-configmap: # Sync period in seconds. Defaults to 60 seconds. period: ${SW_CONFIG_CONFIGMAP_PERIOD:60} # Which namespace is configmap deployed in. namespace: ${SW_CLUSTER_K8S_NAMESPACE:default} # Labelselector is used to locate specific configmap labelSelector: ${SW_CLUSTER_K8S_LABEL:app=collector,release=skywalking}

各参数含义如下:

参数环境变量默认值说明
selectorSW_CONFIGURATIONnone(不启用)选择动态配置中心实现,这里必须为k8s-configmap
periodSW_CONFIG_CONFIGMAP_PERIOD60配置同步周期(秒),OAP 会按此周期从 ConfigMap 拉取并比对配置
namespaceSW_CLUSTER_K8S_NAMESPACEdefaultConfigMap 所属的 Kubernetes 命名空间,即下文{namespace}
labelSelectorSW_CLUSTER_K8S_LABELapp=collector,release=skywalking标签选择器,用于定位哪些 ConfigMap 会被选中,即下文{labelSelector}

其中:

  • {namespace}是 ConfigMap 所属的 k8s 命名空间;
  • {labelSelector}用于标识哪些 ConfigMap 会被选中。

注意namespacelabelSelector两项的默认环境变量名沿用了集群模块的命名(SW_CLUSTER_K8S_NAMESPACESW_CLUSTER_K8S_LABEL),说明在典型的 SkyWalking 集群部署场景下,ConfigMap 通常与 OAP 集群位于同一命名空间、使用同一套标签体系,便于统一管理。

例如,以下两个 ConfigMap 都会被上述配置选中:

apiVersion: v1 kind: ConfigMap metadata: name: skywalking-dynamic-config namespace: default labels: app: collector release: skywalking data: configKey1: configValue1 configKey2: configValue2 ...
apiVersion: v1 kind: ConfigMap metadata: name: skywalking-dynamic-config2 namespace: default labels: app: collector release: skywalking data: configKey3: configValue3 ...

底层实现原理(源码级)

k8s-configmap模块位于 oap-server/server-configuration/configuration-k8s-configmap,共包含 4 个核心类,整体工作链路为:Provider 启动校验 → Informer 监听 ConfigMap → WatcherRegister 周期拉取 → configuration-api 分发变更

模块入口与参数校验

ConfigmapConfigurationProvider.java 是模块的 Provider 入口:

  • name()返回"k8s-configmap",与application.yml中的selector值对应;
  • initConfigReader()中,首先校验labelSelectornamespace是否为空,任一为空都会抛出ModuleStartException("the settings of configmap configuration is illegal.")拒绝启动,这解释了为什么这两个参数是必填项;
  • 校验通过后,构建ConfigurationConfigmapInformerConfigmapConfigurationWatcherRegister并返回。

配置项的载体是 ConfigmapConfigurationSettings.java,包含namespacelabelSelectorperiod三个字段,分别对应application.yml中的同名配置。

Informer 监听机制

ConfigurationConfigmapInformer.java 负责与 Kubernetes API Server 交互:

  • 通过SharedKubernetesClient(来自 library-kubernetes-support 模块)获取共享的 fabric8 Kubernetes 客户端;
  • 使用configMaps().inNamespace(namespace).withLabelSelector(labelSelector).inform()建立Informer 监听,即以 watch 机制持续跟踪目标命名空间下符合标签选择器的所有 ConfigMap;
  • configMapData()方法通过Lister列出所有被监听的 ConfigMap,并把它们的data字段合并到同一个Map<String, String>中返回。

从源码可以看出:多个 ConfigMap 的 data 会被合并为一张全局键值表,因此动态配置可以分散存放在 1 个或多个 ConfigMap 文件中,只要它们的标签匹配labelSelector即可。

周期同步与读取逻辑

ConfigmapConfigurationWatcherRegister.java 继承自 FetchingConfigWatcherRegister.java,后者是"周期性拉取"型配置监听器的通用基类:

  • start()会创建一个名为ConfigWatcherSync的守护线程,以scheduleAtFixedRate方式按period(默认 60 秒)周期执行configSync()
  • configSync()分别调用singleConfigsSync()groupConfigsSync(),从配置中心读取全部已注册 watcher 关心的配置键,并与当前值比对、触发变更通知;
  • registerConfigChangeWatcher的逻辑可以看到,watcher 按WatchType.SINGLE/WatchType.GROUP分表注册,重复注册同一配置键会抛出IllegalStateException

ConfigMap 实现只需覆写两个抽象方法:

  • readConfig(Set<String> keys):对每个关心的配置键,从合并后的 ConfigMap data 中取值,组装成ConfigTable
  • readGroupConfig(Set<String> keys):对每个分组配置键,遍历合并后的 data,凡是以key + "."开头的条目都被归入该分组,并以key.length() + 1截取子项键名。例如core.default.endpoint-name-grouping-openapi.customerAPI-v1会被解析为分组core.default.endpoint-name-grouping-openapi下的子项customerAPI-v1

这一前缀匹配规则是整个分组配置机制的核心,也正是下一节中 ConfigMap data 键命名规范的设计依据。

测试验证

模块自带的单元测试 ConfigmapConfigWatcherRegisterTest.java 覆盖了多个场景:

  • 当 Informer 数据为空或不可用时,readConfig/readGroupConfig仍返回包含全部注册键的ConfigTable/GroupConfigTable(值为null或子项为空),即"拉不到配置不报错,只是保持空值";
  • 当 Informer 正常工作时,readConfig能取到 4 个单配置键的值;readGroupConfig能按前缀把分散在多个 ConfigMap 中的 3 个子项(customerAPI-v1、productAPI-v1、productAPI-v2)聚合到core.default.endpoint-name-grouping-openapi分组下。

测试使用的示例数据正是 src/test/resources 下的三个 YAML 文件,可当作现成的配置模板参考。

配置存储与 ConfigMap 设计

动态配置以 ConfigMap 的 data 条目形式存储,如上文示例所示。配置可以组织在 1 个或多个 ConfigMap 文件中。

Single Config(单一配置)

configmap.data下使用如下键值结构:

configKey: configValue

例如动态配置项为:

{agent-analyzer.default.slowDBAccessThreshold}:{default:200,mongodb:50}

对应的 ConfigMap 为:

apiVersion: v1 kind: ConfigMap metadata: name: skywalking-dynamic-config namespace: default labels: app: collector release: skywalking data: agent-analyzer.default.slowDBAccessThreshold: default:200,mongodb:50

即:data 的键是配置键(configKey),data 的值是配置值(configValue),OAP 按period周期读取并热更新。

Group Config(分组配置)

分组配置的data key由配置键与子项键拼接而成,用.分隔以标识其属于某个分组:

configKey.subItemKey1: subItemValue1 configKey.subItemKey2: subItemValue2 ...

例如动态分组配置为:

{core.default.endpoint-name-grouping-openapi}:|{customerAPI-v1}:{value of customerAPI-v1} |{productAPI-v1}:{value of productAPI-v1} |{productAPI-v2}:{value of productAPI-v2}

该分组配置可以拆分为 2 个 ConfigMap 存储。第一个 ConfigMap 存放前两个子项:

apiVersion: v1 kind: ConfigMap metadata: name: skywalking-dynamic-config namespace: default labels: app: collector release: skywalking data: core.default.endpoint-name-grouping-openapi.customerAPI-v1: value of customerAPI-v1 core.default.endpoint-name-grouping-openapi.productAPI-v1: value of productAPI-v1

第二个 ConfigMap 存放第三个子项:

apiVersion: v1 kind: ConfigMap metadata: name: skywalking-dynamic-config2 namespace: default labels: app: collector release: skywalking data: core.default.endpoint-name-grouping-openapi.productAPI-v2: value of productAPI-v2

由于 Informer 会把所有匹配标签的 ConfigMap 的 data 合并后再按前缀解析分组,因此同一个分组配置的子项可以分布在多个 ConfigMap 中,只要它们都满足labelSelector,OAP 就能聚合出完整的组配置。参考测试资源 skywalking-group-dynamic-configmap.example-serviceA.yaml 与 skywalking-group-dynamic-configmap.example-serviceB.yaml,可以看到core.default.endpoint-name-grouping-openapi的三个子项(customerAPI-v1.yamlproductAPI-v1.yamlproductAPI-v2.yaml)正是这样分别存放在两个 ConfigMap 中的,且每个子项的值是 OpenAPI 3.0 规范的 YAML 文件内容。

支持的动态配置项

无论是 Single 还是 Group 配置,data中的configKey都必须与 OAP 内已注册的配置键精确匹配,否则会被 FetchingConfigWatcherRegister.java 以 WARN 日志"doesn't match any WatchType.SINGLE watcher, ignore." 忽略。以下为 dynamic-config.md 中列出的全部受支持配置键。

Single 类型配置键

Config Key值含义值格式示例
agent-analyzer.default.slowDBAccessThreshold慢数据库语句阈值,覆盖application.ymlagent-analyzer/default/slowDBAccessThresholddefault:200,mongodb:50
agent-analyzer.default.uninstrumentedGateways未接入探针的网关列表,覆盖gateways.yml与 uninstrumented-gateways.md 中gateways.yml格式相同
alarm.default.alarm-settings告警规则设置,覆盖alarm-settings.yml与 backend-alarm.md 中alarm-settings.yml格式相同
core.default.apdexThresholdApdex 阈值设置,覆盖service-apdex-threshold.yml与 apdex-threshold.md 中service-apdex-threshold.yml格式相同
core.default.endpoint-name-grouping端点名称分组规则,覆盖endpoint-name-grouping.yml与 endpoint-grouping-rules.md 中endpoint-name-grouping.yml格式相同
core.default.log4j-xmllog4j 日志配置,覆盖log4j2.xml与 dynamical-logging.md 中log4j2.xml格式相同
core.default.searchableTracesTags可检索的 Trace 标签配置,覆盖application.ymlcore/default/searchableTracesTagshttp.method,http.status_code,rpc.status_code,db.type,db.instance,mq.queue,mq.topic,mq.broker
agent-analyzer.default.traceSamplingPolicy默认与服务维度的采样策略,覆盖trace-sampling-policy-settings.yml与 trace-sampling.md 中trace-sampling-policy-settings.yml格式相同
configuration-discovery.default.agentConfigurationsConfigurationDiscovery 设置参见 SkyWalking Java Agent 的 configuration-discovery 文档

Group 类型配置键

Config Key子项键含义值含义值格式示例
core.default.endpoint-name-grouping-openapi与 OpenAPI 定义文件相关的服务名,例如serviceA;若一个服务对应多个文件,则为每个文件增加一个子项,子项键用.拼接服务名与文件名,如serviceA.API-file1serviceA.API-file2OpenAPI 定义文件内容(YAML 格式),用于生成端点名称分组规则与 endpoint-grouping-rules.md 中productAPI-v2.yaml格式相同

在测试资源 skywalking-dynamic-configmap.example.yaml 中可以看到 Single 类型配置的完整写法:agent-analyzer.default.slowDBAccessThreshold使用default:200,mongodb:50这样的行内格式;而alarm.default.alarm-settingscore.default.apdexThresholdagent-analyzer.default.uninstrumentedGateways等包含多行内容的配置,则使用 YAML 的|-块标量语法把整段规则文本作为 data 值。这也是把告警规则等结构化配置放入 ConfigMap 时的推荐写法——data 值是整段文件内容的字符串。

运行前提与注意事项

从实现与配置中可以归纳出以下前提与限制:

  • 默认关闭:动态配置依赖上游服务,configuration.selector默认值为none。要启用 ConfigMap 实现,必须显式设置selector: ${SW_CONFIGURATION:k8s-configmap}
  • 必填参数namespacelabelSelector缺一不可,缺失时 OAP 会因ModuleStartException拒绝启动(见 ConfigmapConfigurationProvider.java);
  • 监听范围:Informer 只监听namespace指定命名空间内、标签匹配labelSelector的 ConfigMap;新创建的符合条件的 ConfigMap 会被自动纳入,删除或修改则会反映到下一次周期同步中;
  • 同步延迟:配置变更后,OAP 最多在下一个period(默认 60 秒)周期内完成拉取与热更新,并非秒级实时;
  • 键必须精确匹配:ConfigMap data 的键必须与受支持配置键完全一致,多余的条目会被忽略;
  • Kubernetes 权限:从实现看,OAP 通过 fabric8 Informer 对目标命名空间的 ConfigMap 执行 list/watch 操作,因此运行 OAP 的 ServiceAccount 需要具备对相应 ConfigMap 的读取权限,具体权限模型取决于部署时的 RBAC 配置。

小结

Kubernetes ConfigMap 为 SkyWalking OAP 提供了一种零额外依赖的动态配置中心方案:通过namespace+labelSelector圈定配置来源,以period周期同步实现配置热更新,并借助"data 键前缀匹配"机制天然支持 Single 与 Group 两类动态配置。配合 dynamic-config.md 中列出的受支持配置项,运维人员可以在不重启 OAP 的前提下调整告警规则、慢 SQL 阈值、Apdex 阈值与端点分组规则等关键参数,适合已深度使用 Kubernetes 的 SkyWalking 生产部署。

  • 可观测性
  • APM
  • 链路追踪
  • 指标监控
  • 日志分析
  • 微服务

【免费下载链接】skywalking

APM, Application Performance Monitoring System

项目地址:https://gitcode.com/gh_mirrors/sk/skywalking
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询