基于Fluent Operator实现K8s元数据的OpenSearch动态索引
解决方案
1. 让FluentBit采集Kubernetes命名空间标签
默认情况下,FluentBit的Kubernetes Filter仅采集Pod级别的元数据,不会主动拉取命名空间的标签。需要修改ClusterFilter配置,添加namespace_labels: true参数:
apiVersion: fluentbit.fluent.io/v1alpha2 kind: ClusterFilter metadata: labels: fluentbit.fluent.io/component: logging fluentbit.fluent.io/enabled: "true" name: kubernetes spec: filters: - kubernetes: annotations: true kubeCAFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt kubeTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token kubeURL: https://kubernetes.default.svc:443 labels: true namespace_labels: true # 新增:开启命名空间标签采集 - nest: addPrefix: kubernetes_ nestedUnder: kubernetes operation: lift - modify: rules: - remove: stream - remove: kubernetes_pod_id - remove: kubernetes_host - remove: kubernetes_container_hash - nest: nestUnder: kubernetes operation: nest removePrefix: kubernetes_ wildcard: - kubernetes_* match: kube.*
配置生效后,日志中的kubernetes字段会新增namespace_labels节点,包含对应命名空间的所有标签。
2. 修正Fluentd的OpenSearch输出配置
原配置中logstash_prefix的Ruby表达式路径错误,且未处理标签不存在的场景,导致表达式直接暴露在索引名称中。需要调整路径并添加默认值:
apiVersion: fluentd.fluent.io/v1alpha1 kind: ClusterOutput metadata: name: cluster-fluentd-output-os labels: output.fluentd.fluent.io/scope: "cluster" output.fluentd.fluent.io/enabled: "true" spec: outputs: - customPlugin: config: | <match **> @type opensearch host "${FLUENT_OPENSEARCH_HOST}" port 443 logstash_format true # 修正路径:命名空间标签在namespace_labels下,添加默认值避免标签缺失时出错 logstash_prefix logs-#{record.dig('kubernetes', 'namespace_labels', 'org') || 'default'} scheme https <endpoint> url "https://${FLUENT_OPENSEARCH_HOST}" region "${FLUENT_OPENSEARCH_REGION}" assume_role_arn "#{ENV['AWS_ROLE_ARN']}" assume_role_web_identity_token_file "#{ENV['AWS_WEB_IDENTITY_TOKEN_FILE']}" </endpoint> </match> logLevel: info
关键调整点:
- 使用
record.dig安全访问嵌套字段,避免字段不存在时抛出异常 - 添加
|| 'default'设置默认值,确保即使org标签缺失,也能生成合法的索引名称 - 修正路径:命名空间标签存储在
kubernetes.namespace_labels而非kubernetes.namespace_name.labels(后者是Pod的标签,不是命名空间的)
3. 验证效果
部署修改后的配置后,日志中的kubernetes字段会包含命名空间标签:
"kubernetes": { "pod_name": "dockerhub-limit-exporter-XXX-XXX", "namespace_name": "observability-system", "namespace_labels": { "org": "your-org-label" }, "labels": { "app.kubernetes.io/instance": "dockerhub-limit-exporter", ... }, ... }
对应的OpenSearch索引名称会变成logs-your-org-label-2023.04.04,不再包含Ruby表达式。
内容的提问来源于stack exchange,提问作者Kaio H. Cunha
相关产品推荐
相关产品推荐

