logconfig crd需loglistener安装后才生效,否则apply失败;paths须匹配容器内真实日志路径,go应用推荐用/proc/1/fd/1和/proc/1/fd/2;selector需精确匹配pod标签;namespace决定作用域;go应用应输出json结构化日志并注入k8s元信息。

LogConfig CRD 必须在 LogListener 安装后才生效
直接 apply LogConfig YAML 会失败,因为 Kubernetes 不认识这个资源类型。LogListener 是腾讯云 CLS 提供的采集器 DaemonSet,它注册了 logconfig.cls.cloud.tencent.com 这个 CRD。没装 LogListener,kubectl apply -f LogConfig.yaml 会报错 error: unable to recognize "LogConfig.yaml": no matches for kind "LogConfig" in version "cls.cloud.tencent.com/v1"。
实操建议:
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
- 先确认 LogListener 已运行:
kubectl get daemonset -n cls-log-listener,看到 READY 列为1/1或对应节点数才算就绪 - LogListener 的 ServiceAccount 必须有权限操作
logconfig.cls.cloud.tencent.com资源,检查其 ClusterRoleBinding 是否绑定到正确 ClusterRole - 若用 Helm 安装 LogListener,确保启用了
crd.create=true参数(部分旧 chart 默认关闭)
LogConfig 中的 paths 必须匹配容器内实际日志路径
很多人写 paths: ["/var/log/myapp/*.log"] 却收不到日志,根本原因是 Pod 内容器根本没有挂载宿主机目录,或者日志根本没写到那个位置。Go 应用默认 stdout/stderr 输出,不是文件。
实操建议:
- 如果 Go 服务用
log.Printf或zap.L().Info打印日志,应配置paths: ["/proc/1/fd/1", "/proc/1/fd/2"]—— 这是容器主进程(PID 1)的标准输出/错误文件描述符,LogListener 通过读取这些 fd 实时捕获日志 - 若坚持写文件(比如用
lumberjack滚动),必须在 Deployment 中显式挂载空目录或 hostPath,并确保 Go 程序打开的是挂载后的路径,例如:volumeMounts: [{name: log-dir, mountPath: /app/logs}],然后paths: ["/app/logs/*.log"] - 避免使用
/var/log/containers/*.log:那是 kubelet 写的容器运行时日志(含 Pod 名、容器名等元数据),不是你的应用日志;CLS 的 LogListener 默认不采集这个路径,除非你明确配置且理解格式差异
LogConfig 的 selector 必须与 Pod label 精确匹配
selector.matchLabels 是标签选择器,不是字符串模糊匹配。写成 app: go-app 就只匹配带 app=go-app 标签的 Pod,哪怕你 Deployment 里写了 app: go-backend 也完全不会生效。
实操建议:
- 先用
kubectl get pods --show-labels确认目标 Pod 真实标签,注意大小写和连字符(如app.kubernetes.io/name和app是两个不同 key) - LogConfig 的
namespace字段决定作用域:填default只管 default 命名空间;留空或设为*(取决于 LogListener 版本)才可能跨命名空间生效,但多数生产环境禁用该行为 - 多个 LogConfig 可共存,但 selector 不能重叠,否则同一 Pod 日志可能被重复采集、发送两遍
Go 应用自身要适配结构化日志输出
LogListener 能采集原始文本,但如果你希望字段可检索(比如 level=error、trace_id=xxx),Go 程序必须输出 JSON 格式日志,且字段名需与 CLS 控制台里的解析规则对齐。
实操建议:
- 用
zap.NewProductionEncoderConfig()并设置EncodeLevel = zapcore.CapitalLevelEncoder,避免自定义 encoder 把 level 编成小写导致 CLS 解析失败 - 在日志中显式注入 Kubernetes 元信息:用
zap.String("pod_name", os.Getenv("HOSTNAME")),配合 Downward API 注入fieldRef: fieldPath: metadata.name,这样日志里就有"pod_name":"go-app-5c7b9d4f86-abcde" - 别依赖
klog:Kubernetes 的klog在非 k8s 二进制中行为不稳定,Go 应用应统一用zap或zerolog,并关闭klog的全局初始化(防止冲突)
exec 进容器,ls -l /proc/1/fd/{1,2} 看输出是否指向 pipe,再 cat /proc/1/fd/1 确认有没有实时内容,比反复改 YAML 有效得多。golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










