Kubernetes 部署
本文介绍如何使用 Helm 在 Kubernetes 上部署 DOG Stack,并将集群的容器日志、kubelet / 节点 / 集群指标以及 Kubernetes Events 采集进来。完成后,可以在 Doris 中查询这些数据,并在 Grafana 仪表盘中查看。如果需要在单机上部署,请参见 Docker Compose 部署。
Kubernetes 上的 DOG Stack 由两个相互独立的 Helm Chart 组成:
| Chart | 作用 | 工作负载 |
|---|---|---|
ai-observe-stack | DOG Stack 后端,只需安装一次。接收 OTLP 数据、写入 Doris,并通过 Grafana 展示。它本身不采集任何数据。 | OpenTelemetry 网关(StatefulSet)、集成 Doris App 插件的 Grafana(Deployment),以及可选的由 Doris Operator 管理的 Doris 集群 |
dog-k8s-collector | Kubernetes 采集器。在每个需要采集的集群中安装一次,指向网关。 | agent(DaemonSet,每个节点一个):容器日志、kubelet 与节点指标、节点本地 OTLP 入口;cluster(Deployment,每个集群一个):集群指标与 Kubernetes Events |
数据流如下:
applications (OTLP SDK) ───────┐
│ OTLP
dog-k8s-collector ─────────────┤
agent (DaemonSet) │
cluster (Deployment) ▼
ai-observe-stack
gateway OpenTelemetry Collector receives OTLP, writes Doris
doris Apache Doris stores logs, metrics, traces
grafana Grafana + Doris App shows them
两个 Chart 之间没有 Helm 依赖关系,分别安装、分别升级。多个 Kubernetes 集群可以写入同一个 DOG Stack,通过集群名称区分。
如果已经有运行中的 DOG Stack(使用本 Chart 安装、以其他方式部署或位于其他集群),可以直接跳到步骤 2:安装 Kubernetes 采集器,只需要知道其网关的 OTLP gRPC 地址。
本文按 AI Observe Stack 源码提交 2c1fbee83170 核对。下方检出命令固定该提交,避免主分支更新导致参数变化。该提交的 Helm Chart 版本为 0.2.0,默认 Doris 镜像为 4.0.3。
前提条件
- Kubernetes 1.24 及以上版本、Helm 3.8 及以上版本,并已配置
kubectl访问集群。 - 集群级 RBAC 权限:采集器会创建 ClusterRole 和 ClusterRoleBinding。
- 默认网关发送队列需要 PersistentVolume 供应器,连接外部 Doris 时也一样。临时试用可设置
gateway.persistence.enabled: false,但 Pod 替换会丢失内存中的队列数据。 - 节点能够拉取镜像
otel/opentelemetry-collector-contrib、otel/opentelemetry-collector-k8s、grafana/grafana、velodb/doris-app-plugin和busybox。使用私有镜像仓库时,在ai-observe-stack中设置global.imagePullSecrets,在dog-k8s-collector中设置imagePullSecrets,并将镜像参数指向镜像源:ai-observe-stack中的gateway.image.repository、grafana.image.repository、dorisPlugin.image.repository以及global.helperImages.busybox/global.helperImages.curl;dog-k8s-collector中的agent.image.repository和cluster.image.repository。 - Doris,以下二选一:
- 已有 Doris 集群:FE 的 9030(MySQL 协议)和 8030(HTTP)端口可以从 Kubernetes 集群访问,并准备一个能创建目标数据库和表、导入数据及查询 Grafana 所用表的账号。网关通过 Stream Load 写入数据:FE 会将每个请求重定向到 BE 在 Doris 中注册的地址(可通过
SHOW BACKENDS查看),因此网关 Pod 还需要能够访问这些 BE 地址及 BE 的 HTTP 端口(默认 8040)。 - 由 Chart 部署 Doris:集群中有 PersistentVolume 供应器,且 FE 和 BE 各自至少有 2 核 CPU 和 4 GiB 内存。
- 已有 Doris 集群:FE 的 9030(MySQL 协议)和 8030(HTTP)端口可以从 Kubernetes 集群访问,并准备一个能创建目标数据库和表、导入数据及查询 Grafana 所用表的账号。网关通过 Stream Load 写入数据:FE 会将每个请求重定向到 BE 在 Doris 中注册的地址(可通过
本文命令使用 Release 名称 dog 和命名空间 dog,下表中的对象名称由此生成。如果使用其他名称,请相应替换。
| 对象 | 名称 |
|---|---|
| 网关 StatefulSet 与 Service | dog-ai-observe-stack-otel-gateway |
| Grafana Deployment 与 Service | dog-ai-observe-stack-grafana |
| Grafana 管理员 Secret | dog-ai-observe-stack-grafana-admin |
| DorisCluster(由 Chart 部署 Doris 时) | dog-ai-observe-stack-doris |
| 采集器 agent DaemonSet | dog-k8s-collector-agent |
| 采集器 cluster Deployment | dog-k8s-collector-cluster |
获取 Chart
克隆仓库并下载 Chart 依赖。Doris Operator 子 Chart 声明在 Chart 的依赖中,因此即使连接已有 Doris,也需要执行这一步。请使用 helm dependency update,它不需要预先执行 helm repo add。
git clone https://github.com/ai-observe/ai-observe-stack.git
cd ai-observe-stack
git checkout 2c1fbee831701178c7dddba857e88130ef292949
cd helm-charts
helm dependency update ./ai-observe-stack
后续命令均在 helm-charts 目录下执行。
步骤 1:安装 DOG Stack 后端
选择 Doris 的部署方式:
| 方式 A:使用已有 Doris | 方式 B:由 Chart 部署 Doris | |
|---|---|---|
| 适用场景 | 已有 Doris 或 SelectDB 集群;生产环境 | 没有可用 Doris 时的试用和开发 |
| 数据位置 | 已有的 Doris 集群 | Kubernetes 集群内的 PVC |
方式 A:使用已有 Doris
-
创建命名空间,并将 Doris 账号保存到 Secret 中。Secret 必须包含
username和password两个键。kubectl create namespace dog
kubectl create secret generic doris-credentials -n dog \
--from-literal=username='<DORIS_USER>' --from-literal=password='<DORIS_PASSWORD>' -
创建 values 文件
dog-values.yaml:doris:
mode: external
database: otel # 网关会自动创建该数据库及其中的表
external:
host: <DORIS_FE_HOST> # 集群内可访问的 FE 地址
port: 9030 # MySQL 协议端口
feHttpPort: 8030 # HTTP 端口,用于 Stream Load
existingSecret: doris-credentials
internal:
operator:
enabled: false # 不安装 Doris Operator仓库中的
examples/ai-observe-stack/minimal-external-doris.yaml即为该文件。 -
安装:
helm install dog ./ai-observe-stack -n dog -f dog-values.yaml
方式 B:由 Chart 部署 Doris
仓库提供两种规格:
examples/ai-observe-stack/dev.yaml:FE 和 BE 各一个,不开启持久化,一个网关,开启调试输出。仅用于试用。examples/ai-observe-stack/prod.yaml:FE 和 BE 各三个,开启持久化,三个网关,并配置 Ingress。可作为生产配置的起点。使用前需要修改其中与环境相关的配置:storageClass(示例为 AWS 的gp3)、Ingress 的 class、域名和 TLS 证书签发者,以及 Grafana 密码(CHANGE_ME)。
cp examples/ai-observe-stack/dev.yaml dog-values.yaml
helm install dog ./ai-observe-stack -n dog --create-namespace -f dog-values.yaml
后续升级继续使用 dog-values.yaml。部署生产环境时,改为复制 prod.yaml,完成上面列出的环境配置后再安装。
Doris FE 和 BE 拉取镜像并完成初始化需要 2 到 5 分钟。网关会等待 FE 的 9030 和 8030 端口可访问、且至少有一个 BE 在线后再启动。
Doris Operator 是集群级组件,一个 Kubernetes 集群中只能运行一个。在同一集群中安装第二个 DOG Stack 时,需要设置 doris.internal.operator.enabled: false。
验证后端
安装完成后,Helm 会输出 NOTES,其中包含网关的 OTLP gRPC 地址 dog-ai-observe-stack-otel-gateway.dog.svc:4317,请记录下来,步骤 2 中需要使用。
-
检查 Pod 是否运行。应能看到网关 Pod(默认两个副本,即
dog-ai-observe-stack-otel-gateway-0和-1;dev.yaml为一个副本)、Grafana Pod,以及方式 B 下的 Doris FE 和 BE Pod,状态均为Running。kubectl get pods -n dog -
运行内置的链路测试。该测试通过网关发送一条日志,并检查其是否写入 Doris。
helm test dog -n dog --logs输出以
OK: record found in Doris结尾。 -
获取 Grafana 管理员密码(默认为
admin):kubectl get secret -n dog dog-ai-observe-stack-grafana-admin -o jsonpath='{.data.admin-password}' | base64 -d; echo -
访问 Grafana:
kubectl port-forward -n dog svc/dog-ai-observe-stack-grafana 3000:3000打开 http://localhost:3000,使用
admin和上一步获取的密码登录。此时还没有数据写入网关,仪表盘为空。
步骤 2:安装 Kubernetes 采集器
步骤 1 安装的后端只负责接收数据。采集器从 Kubernetes 集群中采集数据并发送给网关:agent 在每个节点上读取所有容器的 stdout 和 stderr,并采集 kubelet 与节点指标;cluster 采集器采集集群级指标和 Kubernetes Events。每条记录都会附带 Pod、命名空间、工作负载和集群名称。如果不安装采集器,只有直接向网关发送 OTLP 数据的应用能够接入 DOG Stack,不会有容器日志、节点与集群指标以及 Events。每个需要观测的 Kubernetes 集群中都需要安装一个采集器 Release。
在被采集集群中准备命名空间。即使跳过步骤 1,也要执行以下幂等命令:
kubectl create namespace dog --dry-run=client -o yaml | kubectl apply -f -
-
确认在待采集的集群中可以访问网关。请将地址替换为实际地址。
kubectl run -it --rm otlp-check --image=busybox:1.36 --restart=Never -- \
sh -c 'sleep 2; nc -zv dog-ai-observe-stack-otel-gateway.dog.svc 4317'输出中出现
open表示网关可访问。网关地址取决于 DOG Stack 的部署位置:DOG Stack 部署位置 网关地址( host:port,不带http://)使用本 Chart 安装在同一集群 <release>-ai-observe-stack-otel-gateway.<namespace>.svc:4317自建的带 Doris exporter 的 OpenTelemetry Collector 其 OTLP gRPC Service,通常为 <service>.<namespace>.svc:4317其他 Kubernetes 集群 通过 LoadBalancer( gateway.service.type: LoadBalancer)或单独配置的 gRPC Ingress 暴露网关地址。本 Chart 的 Ingress 仅暴露 OTLP/HTTP,不暴露 OTLP/gRPC。集群之间需要开放所选端口 -
agent 以 root 身份运行,并挂载节点的
/var/log/pods、/(只读)和/var/lib/otelcol。如果命名空间启用了restricted级别的 Pod Security Standard,需要放宽:kubectl label namespace dog pod-security.kubernetes.io/enforce=privileged --overwrite -
创建 values 文件
collector-values.yaml:gateway:
endpoint: dog-ai-observe-stack-otel-gateway.dog.svc:4317
clusterName: my-cluster
platform: generic参数 是否必填 默认值 说明 gateway.endpoint是 无 网关的 OTLP gRPC 地址,格式为 host:port。clusterName否 Release 名称 以 k8s.cluster.name写入每条记录,用于区分集群。platform否 generic可选 generic、k3s、eks、gke、aks、ack、openshift。决定云资源探测器和 journald 单元名称。不确定时使用generic。timezone否 UTC日志时间戳不带时区时所采用的 IANA 时区。解析规则可以通过 timestamp.timezone覆盖。 -
安装:
helm install dog-k8s-collector ./dog-k8s-collector -n dog -f collector-values.yaml
采集器默认开启以下采集预设:
| 预设 | 默认 | 采集内容 | 运行位置 |
|---|---|---|---|
logsCollection | 开启 | 所有命名空间中所有容器的 stdout 和 stderr | agent |
kubeletMetrics | 开启 | 节点、Pod、容器和卷的 CPU、内存、网络和文件系统,以及相对 limit 的使用率 | agent |
hostMetrics | 开启 | 节点自身的 CPU、内存、负载、磁盘、文件系统和网络 | agent |
otlp | 开启 | 供应用 SDK 使用的节点本地 OTLP 入口 | agent |
clusterMetrics | 开启 | Deployment 可用性、节点状态、Pod 阶段、配额等 | cluster |
kubernetesEvents | 开启 | Kubernetes Events,以日志形式存储 | cluster |
prometheusScrape | 关闭 | 带有 prometheus.io/scrape 注解的 Pod | agent |
journald | 关闭 | 节点 journal 日志,需要包含 journalctl 的镜像 | agent |
examples/ai-observe-stack/dev.yaml 开启了网关的调试输出,会将采样数据打印到网关日志中。当采集器与网关位于同一集群时,需要排除网关的日志文件,否则每条记录都会被重复采集:
logs:
excludePaths:
- /var/log/pods/dog_dog-ai-observe-stack-otel-gateway-*/*/*.log
步骤 3:验证采集
-
检查采集器 Pod。每个节点一个 agent Pod,另有一个 cluster Pod:
kubectl get pods -n dog -l app.kubernetes.io/instance=dog-k8s-collector -o wideNAME READY STATUS NODE
dog-k8s-collector-agent-7x2kq 1/1 Running node-1
dog-k8s-collector-agent-p9m4c 1/1 Running node-2
dog-k8s-collector-cluster-6f5d9c8b7d-hq2xn 1/1 Running node-1 -
检查 agent 没有报错。以下命令应当没有任何输出:
kubectl logs -n dog ds/dog-k8s-collector-agent | grep '"level":"error"' -
在 Doris 中查询数据。使用方式 A 时,用 MySQL 客户端连接已有 Doris FE 的 9030 端口;使用方式 B 时,先转发 FE 端口,再用 MySQL 客户端连接:
kubectl port-forward -n dog svc/dog-ai-observe-stack-doris-fe-service 9030:9030
mysql -h127.0.0.1 -P9030 -urootSELECT service_name, count(*) AS records
FROM otel.otel_logs
WHERE timestamp > now() - interval 5 minute
AND cast(resource_attributes['k8s.cluster.name'] as string) = 'my-cluster'
GROUP BY 1 ORDER BY 2 DESC;agent 启动后 30 秒内会写入第一批数据。
service_name为 Pod 所属工作负载的名称,按 Deployment、StatefulSet、DaemonSet、CronJob、Job 的顺序查找;独立运行的 Pod 则为 Pod 名称。Kubernetes Events 显示为kubernetes-events。只采集安装之后写入的日志行,节点上已有的日志文件不会重新读取。 -
打开 Grafana,检查以下仪表盘:
- Logs Explorer:按命名空间、服务、日志级别和文本过滤日志。
- Kubernetes Events:Warning 数量、主要原因和事件列表。
- K8s Observability:节点和 Pod 的 CPU 与内存。
- Collector Self-Monitoring:agent、cluster 采集器和网关的队列长度、失败和拒绝情况。
端到端示例
以下 Pod 每秒输出一行 JSON 日志,可以验证从容器日志到 Doris 的完整链路:
kubectl create namespace demo
kubectl run json-app -n demo --image=busybox:1.36 --restart=Never -- sh -c \
'i=0; while true; do i=$((i+1)); echo "{\"time\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"level\":\"info\",\"msg\":\"tick $i\"}"; sleep 1; done'
约 30 秒后,在 Doris 中查询:
SELECT timestamp, severity_text, body, cast(resource_attributes['k8s.pod.name'] as string) AS pod
FROM otel.otel_logs
WHERE cast(resource_attributes['k8s.namespace.name'] as string) = 'demo'
ORDER BY timestamp DESC LIMIT 5;
如果返回 severity_text 为 INFO、body 类似 tick 42 的记录,说明容器日志已被采集、JSON 已被解析,并附加了 Kubernetes 元数据。验证完成后执行 kubectl delete namespace demo 清理。
配置采集
修改采集配置时,编辑 collector-values.yaml 后执行:
helm upgrade dog-k8s-collector ./dog-k8s-collector -n dog -f collector-values.yaml
只有受影响的 agent 或 cluster 采集器会重启。agent.storage.enabled=true 时,同一节点和存储路径上的读取位置会保留,减少重复读取,但不保证恰好一次交付:重试可能产生重复记录,节点/存储丢失或队列耗尽也可能丢失数据。
选择命名空间和容器
logs:
namespaces:
include: ["*"] # 或列表,例如 [shop, payment]
exclude: [kube-system, monitoring]
containers:
exclude: [istio-proxy, linkerd-proxy] # 容器名称,在所有命名空间中排除
排除优先于包含。采集器自身的 Pod 不会被采集。
解析日志
-
JSON 日志:以
{开头的行会被自动解析。level或severity写入severity_text,message或msg写入body,其余字段写入log_attributes。字段名不同时,可设置logs.json.severityFields和logs.json.messageFields。 -
常见文本格式:在规则中使用内置预设。
selector.container匹配的是容器名称,而不是 Pod 或 Deployment 名称。logs:
rules:
- name: shop-api
selector: {namespace: "^shop$", container: "^api$"}
preset: java-spring预设 适用格式 java-springSpring Boot 3 默认控制台格式,自动合并异常堆栈 python-loggingPython logging.basicConfig默认格式go-zap-consolezap console encoder glogC++ 和 Go glog nginx-access、nginx-errornginx combined 访问日志和错误日志 mysql、postgres、redis官方镜像的默认格式 doris-fe、doris-fe-audit、doris-beApache Doris FE、FE 审计和 BE 日志 json-generic单行 JSON Doris FE 的运行日志和审计日志输出在同一个容器中。如果需要同时解析,请使用相同的 selector 添加两条规则,分别设置
preset: doris-fe和preset: doris-fe-audit。 -
自定义格式:编写带命名分组的正则表达式,分组
ts为时间戳,level为日志级别,msg为消息:logs:
rules:
- name: shop-worker
selector: {namespace: "^shop$", container: "^worker$"}
regex: '^(?P<ts>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z)\s+(?P<level>[a-z]+)\s+(?P<msg>(?s:.*))$'
timestamp: {layout: "%Y-%m-%dT%H:%M:%S.%L%z"}
severity: {field: level}
multiline: {firstLinePattern: '^\d{4}-\d{2}-\d{2}T'} # 堆栈行合并到上一条记录
drop: ['GET /healthz'] # 在节点上直接丢弃如果日志时间戳不带时区,且容器不在 UTC 时区运行,需要在
timestamp中增加timezone,例如timestamp: {layout: "...", timezone: Asia/Shanghai}。规则按顺序匹配,第一个匹配的规则生效。每条记录的dog.log.rule属性标明了解析它的规则。部署规则之前,可以使用仓库中的
hack/test-rule.sh对样例日志进行测试,该脚本依赖 helm、yq 和 Docker:kubectl logs -n shop -l app=worker -c worker --tail=30 > worker.log
hack/test-rule.sh -f collector-values.yaml -n shop -c worker worker.log
接收应用的 OTLP 数据
接入 OpenTelemetry SDK 的应用可以将 Trace、指标和日志发送到所在节点的 agent,agent 会附加 Pod、命名空间和工作负载元数据。先在节点上开放 agent 端口:
presets:
otlp:
hostPortHttp: 4318
hostPortGrpc: 4317
然后在应用的 Pod 模板中设置地址:
env:
- name: HOST_IP
valueFrom: {fieldRef: {fieldPath: status.hostIP}}
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://$(HOST_IP):4318
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: http/protobuf
- name: OTEL_SERVICE_NAME
value: checkout
抓取 Prometheus 指标
设置 presets.prometheusScrape.enabled: true,然后为应用 Pod 添加注解 prometheus.io/scrape: "true"、prometheus.io/port 和 prometheus.io/path。指标写入 otel_metrics_* 表,service_name 为工作负载名称。
采集多个集群
在每个集群中各安装一个采集器 Release,gateway.endpoint 指向同一个网关(跨集群时使用 LoadBalancer 或单独配置的 gRPC Ingress 地址),并为每个集群设置不同的 clusterName。查询和仪表盘通过 k8s.cluster.name 过滤。
生产环境建议
| 项目 | 参数 | 说明 |
|---|---|---|
| Doris 副本和磁盘 | doris.internal.cluster.fe.replicas、doris.internal.cluster.be.replicas、doris.internal.cluster.persistence | FE 和 BE 各至少三个,并设置 gateway.dorisExporter.replicationNum: 3。 |
| 网关副本和队列 | gateway.replicas、gateway.persistence.size、gateway.dorisExporter.sendingQueue | 每个网关副本的发送队列保存在各自的 PVC 上。写入出现延迟时,在 Collector Self-Monitoring 仪表盘中观察 otelcol_exporter_queue_size。 |
| 数据保留 | gateway.dorisExporter.historyDays | 默认 7 天。 |
| Grafana 密码 | grafana.adminPassword 或 grafana.existingSecret | 默认密码为 admin。 |
| 外部访问 | ingress、gateway.service.type | 为 Grafana 配置 Ingress;集群外的应用通过 OTLP/HTTP Ingress 路径或 LoadBalancer 写入。 |
| 调试输出 | gateway.debug.enabled: false | dev.yaml 中为开启状态。 |
| 采集范围 | logs.namespaces.exclude | 通常排除 kube-system。 |
| 采集器资源 | agent.resources、agent.queueSize | 每个 agent 默认申请 100m CPU 和 128 MiB 内存,上限为 1 CPU 和 512 MiB。网关不可达期间,每个节点最多在本地磁盘缓存 agent.queueSize 条记录(默认 20,000 条)。 |
仓库中的 examples/ai-observe-stack/prod.yaml 可作为生产 values 文件的起点。
默认 gateway.timeGuard.enabled=true 会将超出可写分区时间窗口的记录时间改为接收时间:日志在 log.original_time_unix_nano、Trace 在 span.original_start_time_unix_nano 保留原时间,指标时间直接重写。需要回填历史数据时,应同时调整 gateway.dorisExporter.createHistoryDays 和时间保护配置。网关向 Doris 发送失败的默认重试时限为 10 分钟(gateway.dorisExporter.retryMaxElapsedTime),超时批次会记录错误并丢弃。
升级与卸载
升级或修改配置:
helm upgrade dog ./ai-observe-stack -n dog -f dog-values.yaml
helm upgrade dog-k8s-collector ./dog-k8s-collector -n dog -f collector-values.yaml
卸载:
helm uninstall dog-k8s-collector -n dog
helm uninstall dog -n dog
卸载采集器不会影响 DOG Stack 以及 Doris 中的数据。节点上 /var/lib/otelcol 中的文件读取位置会保留,重新安装后从上次的位置继续采集。使用方式 A 时,卸载 DOG Stack 不会删除已有 Doris 中的数据库。
Helm 不会删除网关的 PersistentVolumeClaim、Doris 的 PersistentVolumeClaim(方式 B 开启持久化时)以及已完成的 helm test Pod。如需删除:
kubectl delete pvc -n dog -l app.kubernetes.io/instance=dog
kubectl delete pvc -n dog -l 'app.doris.ownerreference/name in (dog-ai-observe-stack-doris-fe,dog-ai-observe-stack-doris-be)'
kubectl delete pod -n dog dog-ai-observe-stack-test-pipeline --ignore-not-found
使用方式 B 时,Helm 也不会删除随 Doris Operator 安装的 CustomResourceDefinition dorisclusters.doris.selectdb.com,因为 Helm 从不删除 CRD。删除该 CRD 会同时删除 Kubernetes 集群中所有的 DorisCluster,因此仅在集群中没有其他由 Doris Operator 管理的 Doris 集群时才删除:
kubectl delete crd dorisclusters.doris.selectdb.com
常见问题
| 现象 | 原因与解决方法 |
|---|---|
helm install 报错 missing in charts/ directory: doris-operator | 未下载 Chart 依赖。执行 helm dependency update ./ai-observe-stack。 |
helm dependency build 报错 no repository definition for https://charts.selectdb.com | helm dependency build 只使用通过 helm repo add 添加的仓库。改为执行 helm dependency update ./ai-observe-stack。 |
helm install 报错 gateway.endpoint is required | 将采集器的 gateway.endpoint 设置为网关地址。 |
helm install 报错 additional properties 'xxx' not allowed | values 文件中有拼写错误的顶层键。 |
helm test 失败,或网关日志中出现 Doris 相关错误 | 检查 Doris FE 的 9030 和 8030 端口是否可访问,以及账号是否能创建目标数据库/表、导入和查询数据。使用 kubectl logs -n dog dog-ai-observe-stack-otel-gateway-0 查看网关日志。 |
agent Pod 报 CreateContainerConfigError、被 Pod Security 拒绝,或日志中出现 /var/log/pods 的 permission denied | 命名空间启用了 restricted。添加 privileged 标签,参见步骤 2。 |
agent 日志出现 connection refused 或 Unavailable | 网关地址错误、网关未运行,或网络策略阻止了 4317 端口。问题修复前,记录会缓存在节点上,修复后自动发送。 |
agent Pod 一直处于 ContainerCreating 状态,事件显示 MountVolume.SetUp failed for volume "zoneinfo" | 节点上没有时区数据库(部分精简操作系统镜像)。设置 agent.tzdata.hostPath: "",并将 timezone 以及所有规则的 timestamp.timezone 保持为 UTC。 |
| 某个命名空间没有日志 | 被 logs.namespaces.exclude 或 logs.containers.exclude 排除,或安装后没有写入新的日志行。 |
有日志但 service_name 为空 | agent 无法读取 Pod 元数据。检查 agent 日志中是否有 RBAC forbidden 错误。 |
解析规则不生效(dog.log.rule 为空) | selector.container 填写的是 Pod 名称而不是容器名称,或更靠前的规则先匹配。使用 hack/test-rule.sh 验证。 |
| 日志时间相差若干小时 | 日志行不带时区、容器不在 UTC 时区运行,且未设置 timestamp.timezone。 |
查看 agent 实际运行的配置:
kubectl get cm -n dog dog-k8s-collector-agent-config -o jsonpath='{.data.config\.yaml}'
两个 Chart 的完整参数说明,请参见仓库 helm-charts 目录下各 Chart 的 USER_GUIDE_zh.md 和 values.yaml。