- 可观测性
- APM
- 链路追踪
- 指标监控
- 日志分析
- 微服务
【免费下载链接】skywalking
APM, Application Performance Monitoring System
本篇指南围绕 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.yml的configuration段中进行如下配置:
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}各参数含义如下:
| 参数 | 环境变量 | 默认值 | 说明 |
|---|---|---|---|
selector | SW_CONFIGURATION | none(不启用) | 选择动态配置中心实现,这里必须为k8s-configmap |
period | SW_CONFIG_CONFIGMAP_PERIOD | 60 | 配置同步周期(秒),OAP 会按此周期从 ConfigMap 拉取并比对配置 |
namespace | SW_CLUSTER_K8S_NAMESPACE | default | ConfigMap 所属的 Kubernetes 命名空间,即下文{namespace} |
labelSelector | SW_CLUSTER_K8S_LABEL | app=collector,release=skywalking | 标签选择器,用于定位哪些 ConfigMap 会被选中,即下文{labelSelector} |
其中:
{namespace}是 ConfigMap 所属的 k8s 命名空间;{labelSelector}用于标识哪些 ConfigMap 会被选中。
注意namespace与labelSelector两项的默认环境变量名沿用了集群模块的命名(SW_CLUSTER_K8S_NAMESPACE、SW_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()中,首先校验labelSelector与namespace是否为空,任一为空都会抛出ModuleStartException("the settings of configmap configuration is illegal.")拒绝启动,这解释了为什么这两个参数是必填项; - 校验通过后,构建
ConfigurationConfigmapInformer与ConfigmapConfigurationWatcherRegister并返回。
配置项的载体是 ConfigmapConfigurationSettings.java,包含namespace、labelSelector、period三个字段,分别对应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.yaml、productAPI-v1.yaml、productAPI-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.yml中agent-analyzer/default/slowDBAccessThreshold | default: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.apdexThreshold | Apdex 阈值设置,覆盖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-xml | log4j 日志配置,覆盖log4j2.xml | 与 dynamical-logging.md 中log4j2.xml格式相同 |
core.default.searchableTracesTags | 可检索的 Trace 标签配置,覆盖application.yml中core/default/searchableTracesTags | http.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.agentConfigurations | ConfigurationDiscovery 设置 | 参见 SkyWalking Java Agent 的 configuration-discovery 文档 |
Group 类型配置键
| Config Key | 子项键含义 | 值含义 | 值格式示例 |
|---|---|---|---|
core.default.endpoint-name-grouping-openapi | 与 OpenAPI 定义文件相关的服务名,例如serviceA;若一个服务对应多个文件,则为每个文件增加一个子项,子项键用.拼接服务名与文件名,如serviceA.API-file1、serviceA.API-file2 | OpenAPI 定义文件内容(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-settings、core.default.apdexThreshold、agent-analyzer.default.uninstrumentedGateways等包含多行内容的配置,则使用 YAML 的|-块标量语法把整段规则文本作为 data 值。这也是把告警规则等结构化配置放入 ConfigMap 时的推荐写法——data 值是整段文件内容的字符串。
运行前提与注意事项
从实现与配置中可以归纳出以下前提与限制:
- 默认关闭:动态配置依赖上游服务,
configuration.selector默认值为none。要启用 ConfigMap 实现,必须显式设置selector: ${SW_CONFIGURATION:k8s-configmap}; - 必填参数:
namespace与labelSelector缺一不可,缺失时 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
相关推荐
Apache SkyWalking 动态配置之 Kubernetes ConfigMap 实现:原理、配置与实战
Apache SkyWalking 动态配置之 Kubernetes ConfigMap 实现:原理、配置与实战 导读 Apache SkyWalking OA
可观测性后端微服务云原生SkyWalking OAP 动态配置中心接入 Consul 完整指南:配置、存储模型与源码实现
SkyWalking OAP 动态配置中心接入 Consul 完整指南:配置、存储模型与源码实现 本文以 Apache SkyWalking OAP 后端内置的
可观测性后端微服务云原生Apache SkyWalking OAP 接入 Apollo 配置中心实现动态配置(Dynamic Configuration Apollo Implementation)
Apache SkyWalking OAP 接入 Apollo 配置中心实现动态配置(Dynamic Configuration Apollo Implemen
可观测性后端微服务云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考