Dozzle 在 Kubernetes 中的部署与配置:实时查看 Pod 日志的完整指南

【免费下载链接】dozzle Realtime log viewer for containers. Supports Docker, Swarm and K8s. 【免费下载链接】dozzle 项目地址: https://gitcode.com/GitHub_Trending/do/dozzle

导读

Dozzle 是一个面向容器的实时日志查看器,原生支持 Docker、Swarm 与 Kubernetes 三种运行环境。本文围绕官方 Kubernetes 支持文档展开,讲解如何通过 DOZZLE_MODE=k8s 在集群内以最小权限 RBAC 部署 Dozzle、如何安装并依赖 Kubernetes Metrics API 展示资源用量,以及如何用 DOZZLE_NAMESPACEDOZZLE_FILTER 精确圈定日志监控范围。读完本文,你将得到一份可直接落地的集群部署清单,并理解其底层在 internal/k8s 中的实现原理。


Kubernetes 模式概述

在 Kubernetes 集群中,Dozzle 以 Pod 的形式运行,通过 Kubernetes API 列出 Pod、拉取容器日志、watch 事件变化,并借助 Metrics API 采集 CPU 与内存使用量。你不再需要像 Docker 模式那样挂载 /var/run/docker.sock,取而代之的是为 Dozzle 创建一个受限的 ServiceAccount 与 RBAC 授权。

从源码结构看,Kubernetes 模式的核心实现集中在 internal/k8s/client.go(Pod 枚举、日志流、事件 watch、attach/exec)、internal/k8s/stats_collector.go(Metrics API 采集)与 internal/k8s/log_reader.go(日志行读取),上层由 internal/support/k8s/k8s_service.go 封装为统一的容器服务接口。


一、在 Kubernetes 中部署 Dozzle

1.1 完整部署清单

DOZZLE_MODE 环境变量设置为 k8s 即可启用 Kubernetes 模式。官方推荐以下整套 YAML(也可见仓库示例 examples/k8s.dozzle.yml),包含 ServiceAccount、ClusterRole、ClusterRoleBinding、PVC、Deployment 与 Service:

# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-viewer
---
# clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-viewer-role
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets", "daemonsets", "statefulsets"]
    verbs: ["get"]
  - apiGroups: ["batch"]
    resources: ["jobs", "cronjobs"]
    verbs: ["get"]
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods"]
    verbs: ["get", "list"]
---
# clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: pod-viewer-binding
subjects:
  - kind: ServiceAccount
    name: pod-viewer
    namespace: default
roleRef:
  kind: ClusterRole
  name: pod-viewer-role
  apiGroup: rbac.authorization.k8s.io
---
# pvc.yaml
# 使用 ReadWriteOnce 加 Recreate 策略时,Pod 滚动更新期间云端配置与
# 通知规则会短暂不可用(新 Pod 要等旧 Pod 释放卷后才能挂载)。
# 如需零停机持久化配置,请改用 ReadWriteMany 存储类(NFS、CephFS 等),
# 并把下方 Deployment 的更新策略改为 RollingUpdate。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dozzle-data
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dozzle
spec:
  selector:
    matchLabels:
      app: dozzle
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: dozzle
    spec:
      serviceAccountName: pod-viewer
      containers:
        - name: dozzle
          image: amir20/dozzle:latest
          ports:
            - containerPort: 8080
          env:
            - name: DOZZLE_MODE
              value: "k8s"
          volumeMounts:
            - name: data
              mountPath: /data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: dozzle-data
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: dozzle-service
spec:
  type: ClusterIP
  selector:
    app: dozzle
  ports:
    - port: 8080
      targetPort: 8080
      protocol: TCP

这份配置逐块完成了四件事:

  • ServiceAccount pod-viewer:为 Dozzle Pod 提供集群内身份;
  • ClusterRole pod-viewer-role:授予读取 Pod 及日志(get/list/watch)、读取节点与工作负载元数据、读取 Pod 指标的最小权限;
  • ClusterRoleBinding:把角色绑定到 ServiceAccount;
  • Deployment + Service:运行 Dozzle 容器并通过 ClusterIP 暴露 8080 端口。

[!WARNING] 如果通过 GitOps 工具(如 Flux CD、Argo CD)把这份清单部署到 default 之外的命名空间,必须同步修改 ClusterRoleBinding 中 Subject 的 namespace,否则 ServiceAccount 找不到,Dozzle 将没有权限访问任何资源。

[!NOTE] Kubernetes 模式是较新的功能,相比 Docker 版本可能存在一些限制。官方文档提示可通过讨论区反馈问题或改进建议(详见 docs/guide/k8s.md)。

1.2 RBAC 与源码的对应关系

权限清单并非凭空设计,而是与 internal/k8s/client.go 的实际调用一一对应:

  • podsget/list/watchListContainersFindContainerContainerEvents(对每个命名空间建立 Pod watch)依赖;
  • pods/logContainerLogsContainerLogsBetweenDates 通过 Pods(namespace).GetLogs(...).Stream(ctx) 拉取日志流;
  • nodesNewK8sClient 启动时会 List 节点,并用首个节点的 Status.NodeInfo.MachineID 派生 host ID;
  • appsbatch 组资源:用于解析 Pod 的 owner 链(Deployment → ReplicaSet → Pod 等),将归属信息写入容器标签;
  • metrics.k8s.io/pods:由 internal/k8s/stats_collector.go 定时查询。

从源码还可以推断两个重要的运行时行为:

  1. 双模式客户端NewK8sClient 会检查 KUBERNETES_SERVICE_HOST 环境变量——在集群内自动使用 rest.InClusterConfig()(打印 "Running in-cluster mode");在本地开发时则回退到 KUBECONFIG~/.kube/config(打印 "Running in local mode..."),因此你也可以把 Dozzle 跑在集群外直接连接集群。
  2. Pod 状态映射phaseToState 将 Pod 的 Pending/Running/Succeeded/Failed/Unknown 分别映射为 created/running/exited/exited/unknown,对应前端展示的容器状态。

1.3 配置持久化与数据目录

Deployment 把 PVC dozzle-data 挂载到容器内的 /data,用于持久化云端配置、通知规则等状态。清单默认使用 ReadWriteOnce + Recreate 策略,其取舍已在 PVC 注释中说明:更新期间配置会短暂不可用;对可用性敏感的场景应改用 ReadWriteMany(NFS、CephFS 等)并将 Deployment 策略切换为 RollingUpdate。示例文件 examples/k8s.dozzle.yml 中还演示了通过 DOZZLE_LEVEL=debug 开启更详细的日志输出以便排查。


二、Metrics API:资源用量数据的来源

Dozzle 依赖 Kubernetes Metrics API(由 metrics-server 实现)获取每个容器的 CPU 与内存使用量。当前版本中,未安装 Metrics API 则无法正常使用 Kubernetes 模式,这是硬性前提。

安装 metrics-server:

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

验证 API 是否工作:

kubectl top pod

如果 kubectl top pod 能正常输出各 Pod 的 CPU/内存占用,说明 Metrics API 已就绪。

从源码看,采集逻辑位于 internal/k8s/stats_collector.go

  • K8sStatsCollector.Start 使用 time.NewTicker(1 * time.Second) 每秒轮询一次 PodMetricses 列表;
  • 对每个 Pod 内每个容器,换算 CPU 百分比(c.Usage.Cpu().MilliValue() / 1000 * 100)并记录 MemoryUsage
  • 网络流量统计默认为 0:源码注释明确说明 Kubernetes Metrics API 默认不暴露网络指标,需要自定义指标或 cAdvisor 集成才能获得;
  • 采集器采用订阅者模型(xsync.Map),并通过 timeToStop = 2 * time.Hour 的延迟停止机制,在没有订阅者后自动释放资源。

因此,在 Kubernetes 模式下,页面上的 CPU、内存数据来自 metrics-server,而网络收发数据会显示为 0,这是实现层面的已知边界。


三、命名空间与过滤:精确圈定监控范围

3.1 按命名空间限定(DOZZLE_NAMESPACE)

默认情况下 Dozzle 监控集群中所有命名空间的 Pod。若只想关注某个命名空间,设置 DOZZLE_NAMESPACE

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dozzle
spec:
  selector:
    matchLabels:
      app: dozzle
  template:
    metadata:
      labels:
        app: dozzle
    spec:
      serviceAccountName: pod-viewer
      containers:
        - name: dozzle
          image: amir20/dozzle:latest
          ports:
            - containerPort: 8080
          env:
            - name: DOZZLE_MODE
              value: "k8s"
            - name: DOZZLE_NAMESPACE
              value: "default"

[!NOTE] DOZZLE_NAMESPACE 支持逗号分隔的多个命名空间。指定多个时,Dozzle 会分别监控每个命名空间并合并结果。

源码层面的印证:在 internal/k8s/client.go 中,namespace 字段是 []string,未设置时默认 []string{metav1.NamespaceAll}(即 "",代表全部命名空间)。ListContainersContainerEvents 都使用 lop.Map 对命名空间列表并行执行 Pod 列举与 watch,再合并结果;同时 internal/support/cli/args.goDOZZLE_NAMESPACE 被解析为可重复的字符串列表(separate 语义),参数解析时会逐个 TrimSpace 清理空白。

3.2 按标签过滤(DOZZLE_FILTER)

DOZZLE_FILTER 的语义与 Docker 的过滤器一致,通过 key=value 形式限定 Dozzle 只展示匹配标签的容器。例如只监控 env=prod 的应用:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dozzle
spec:
  selector:
    matchLabels:
      app: dozzle
  template:
    metadata:
      labels:
        app: dozzle
    spec:
      serviceAccountName: pod-viewer
      containers:
        - name: dozzle
          image: amir20/dozzle:latest
          ports:
            - containerPort: 8080
          env:
            - name: DOZZLE_MODE
              value: "k8s"
            - name: DOZZLE_FILTER
              value: "env=prod"

解析逻辑同样位于 internal/support/cli/args.goDOZZLE_FILTER 支持重复传入多个 key=valueFilterStringsseparate 拆分),解析时按第一个 = 切成键值,构建成 map[string][]string,格式非法(缺少 =)会直接启动失败并提示 each filter should be of the form key=value

在 Kubernetes 模式下,过滤处理比 Docker 更细致(见 internal/k8s/client.gosplitK8sFilters):

  • 符合 K8s 标签命名规范的普通键(如 envapp.kubernetes.io/name)会转换为 Pod 列表的 LabelSelector,下推到 API Server 端完成过滤,性能更好;
  • 元数据类标签@k8s. 前缀,以及 namespaceowner.kindowner.nameowner.key)与不合法的 K8s 标签键则作为元数据在客户端侧通过 matchesContainerLabels 精确匹配;
  • Pod 标签之外,Dozzle 还会自动注入 namespace@k8s.namespace 标签,并沿 owner 链解析出 owner.kindowner.nameowner.key@k8s.owner.N.* 系列标签(包含 apiVersion、kind、namespace、name、uid、key),owner 解析使用带 TTL(5 分钟)与容量上限(4096 条)的缓存,避免大集群中 ReplicaSet 频繁滚动导致内存无界增长。

[!NOTE] 除上述两类环境变量外,Kubernetes 模式下仍支持与 Docker 模式相同的大部分环境变量,如认证(DOZZLE_AUTH_PROVIDER)、端口(DOZZLE_ADDR)、日志级别(DOZZLE_LEVEL)等,具体清单可查阅 internal/support/cli/args.godocs/guide/supported-env-vars.md


四、Kubernetes 模式的功能边界

internal/support/k8s/k8s_service.go 的实现可以明确以下能力边界:

能力Kubernetes 模式下的行为
实时/历史日志流✅ 通过 Pods.GetLogs 获取,ContainerLogs 默认 Follow=trueTimestamps=trueTailLines=500,并支持 SinceTime 回溯
容器列表、事件 watch✅ 基于 Pod watch 与 owner 链解析
资源指标(CPU/内存)✅ 来自 Metrics API,每 1 秒轮询;网络流量为 0
终端 Attach / Exec✅ 通过 remotecommand SPDY 执行器实现,支持终端尺寸动态调整
镜像更新检查 / 容器更新❌ 明确不支持,理由为镜像发布属于集群职责(见 CheckImageUpdate 返回 SkippedUpdateContainer 返回错误)
容器操作(start/stop 等)ContainerActions 未实现(panic("not implemented")

日志读取方面,internal/k8s/log_reader.go 基于 bufio.Reader 逐行读取,并特意处理了"文件末尾无换行符的最后一行"——把残留部分连同 EOF 一起返回,避免丢日志。此外,容器 ID 的格式统一为 namespace:pod:container(见 parsePodContainerID),这也是前端路由与 API 中引用容器的标准标识。


五、前端体验与延伸阅读

部署完成后,Dozzle 的 Web 界面会把集群中的容器按命名空间组织展示。前端相关的页面实现可参考 assets/pages/namespace(命名空间维度日志视图)、assets/stores/k8s.ts(K8s 模式状态管理)与 assets/stores/swarm.ts(对照的 Swarm 模式实现)。

如果希望进一步深入,建议按以下顺序阅读仓库内容:

结语

Dozzle 的 Kubernetes 模式用一套精简的 RBAC 清单换来了集群内任意 Pod 的实时日志、历史回溯与资源指标可视化。部署时要特别留意三个关键点:Metrics API 是硬依赖非 default 命名空间必须同步修改 ClusterRoleBinding 的 Subject网络指标因 API 限制固定为 0。在此基础上,通过 DOZZLE_NAMESPACEDOZZLE_FILTER 把监控范围收敛到具体命名空间与标签,即可在大型集群中保持清晰、低噪的日志视图。

【免费下载链接】dozzle Realtime log viewer for containers. Supports Docker, Swarm and K8s. 【免费下载链接】dozzle 项目地址: https://gitcode.com/GitHub_Trending/do/dozzle

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐