Dozzle 在 Kubernetes 中的部署与配置:实时查看 Pod 日志的完整指南
Dozzle 在 Kubernetes 中的部署与配置:实时查看 Pod 日志的完整指南
导读
Dozzle 是一个面向容器的实时日志查看器,原生支持 Docker、Swarm 与 Kubernetes 三种运行环境。本文围绕官方 Kubernetes 支持文档展开,讲解如何通过 DOZZLE_MODE=k8s 在集群内以最小权限 RBAC 部署 Dozzle、如何安装并依赖 Kubernetes Metrics API 展示资源用量,以及如何用 DOZZLE_NAMESPACE 与 DOZZLE_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 的实际调用一一对应:
pods的get/list/watch:ListContainers、FindContainer、ContainerEvents(对每个命名空间建立 Pod watch)依赖;pods/log:ContainerLogs与ContainerLogsBetweenDates通过Pods(namespace).GetLogs(...).Stream(ctx)拉取日志流;nodes:NewK8sClient启动时会List节点,并用首个节点的Status.NodeInfo.MachineID派生 host ID;apps、batch组资源:用于解析 Pod 的 owner 链(Deployment → ReplicaSet → Pod 等),将归属信息写入容器标签;metrics.k8s.io/pods:由 internal/k8s/stats_collector.go 定时查询。
从源码还可以推断两个重要的运行时行为:
- 双模式客户端:
NewK8sClient会检查KUBERNETES_SERVICE_HOST环境变量——在集群内自动使用rest.InClusterConfig()(打印 "Running in-cluster mode");在本地开发时则回退到KUBECONFIG或~/.kube/config(打印 "Running in local mode..."),因此你也可以把 Dozzle 跑在集群外直接连接集群。 - 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}(即 "",代表全部命名空间)。ListContainers 与 ContainerEvents 都使用 lop.Map 对命名空间列表并行执行 Pod 列举与 watch,再合并结果;同时 internal/support/cli/args.go 中 DOZZLE_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.go:DOZZLE_FILTER 支持重复传入多个 key=value(FilterStrings 以 separate 拆分),解析时按第一个 = 切成键值,构建成 map[string][]string,格式非法(缺少 =)会直接启动失败并提示 each filter should be of the form key=value。
在 Kubernetes 模式下,过滤处理比 Docker 更细致(见 internal/k8s/client.go 的 splitK8sFilters):
- 符合 K8s 标签命名规范的普通键(如
env、app.kubernetes.io/name)会转换为 Pod 列表的LabelSelector,下推到 API Server 端完成过滤,性能更好; - 元数据类标签(
@k8s.前缀,以及namespace、owner.kind、owner.name、owner.key)与不合法的 K8s 标签键则作为元数据在客户端侧通过matchesContainerLabels精确匹配; - Pod 标签之外,Dozzle 还会自动注入
namespace与@k8s.namespace标签,并沿 owner 链解析出owner.kind、owner.name、owner.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.go 与 docs/guide/supported-env-vars.md。
四、Kubernetes 模式的功能边界
从 internal/support/k8s/k8s_service.go 的实现可以明确以下能力边界:
| 能力 | Kubernetes 模式下的行为 |
|---|---|
| 实时/历史日志流 | ✅ 通过 Pods.GetLogs 获取,ContainerLogs 默认 Follow=true、Timestamps=true、TailLines=500,并支持 SinceTime 回溯 |
| 容器列表、事件 watch | ✅ 基于 Pod watch 与 owner 链解析 |
| 资源指标(CPU/内存) | ✅ 来自 Metrics API,每 1 秒轮询;网络流量为 0 |
| 终端 Attach / Exec | ✅ 通过 remotecommand SPDY 执行器实现,支持终端尺寸动态调整 |
| 镜像更新检查 / 容器更新 | ❌ 明确不支持,理由为镜像发布属于集群职责(见 CheckImageUpdate 返回 Skipped、UpdateContainer 返回错误) |
| 容器操作(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 模式实现)。
如果希望进一步深入,建议按以下顺序阅读仓库内容:
- internal/k8s/client.go:客户端核心,覆盖连接建立、Pod→容器映射、owner 链解析、过滤下推与 watch;
- internal/k8s/stats_collector.go:Metrics API 采集与订阅模型;
- internal/k8s/log_reader.go:日志行读取与末尾无换行行的处理;
- internal/support/k8s/k8s_service.go:K8s 模式对统一容器服务接口的适配及功能边界;
- examples/k8s.dozzle.yml:可直接套用的最小部署示例(含 debug 日志选项);
- docs/guide/k8s.md:本文对应的英文原文,另有多语言版本位于 docs/zh/guide/k8s.md、docs/es/guide/k8s.md。
结语
Dozzle 的 Kubernetes 模式用一套精简的 RBAC 清单换来了集群内任意 Pod 的实时日志、历史回溯与资源指标可视化。部署时要特别留意三个关键点:Metrics API 是硬依赖、非 default 命名空间必须同步修改 ClusterRoleBinding 的 Subject、网络指标因 API 限制固定为 0。在此基础上,通过 DOZZLE_NAMESPACE 与 DOZZLE_FILTER 把监控范围收敛到具体命名空间与标签,即可在大型集群中保持清晰、低噪的日志视图。
更多推荐
所有评论(0)