使用 Dash0 实现从零到全栈可观测性
目录
本指南将详细介绍如何将一个极简的 Spring Boot 服务部署到 Kubernetes,并使用 Dash0 Operator 实现完整的可观测性——且无需对应用程序代码进行任何修改。
Dash0 是一个原生支持 OpenTelemetry 的可观测性平台,能够收集并关联链路追踪(traces)、指标(metrics)和日志(logs),同时提供针对 Kubernetes 资源(如 Pod、节点、命名空间、部署、守护进程集、有状态集、作业和定时作业)以及云基础设施(如 AWS)的监控。其 Kubernetes Operator 可以在 Pod 级别自动对工作负载进行插桩,无需更改应用程序代码或容器镜像。
该设置分为两个不同阶段。第一阶段确立“之前”的状态:服务在 Kubernetes 中运行且没有任何插桩,产生的流量对于任何可观测性工具来说都是完全不可见的。第二阶段将 Dash0 Operator 添加到集群中,它会自动对工作负载进行插桩,并开始将链路追踪、指标和日志发送到 Dash0——同样,无需对应用程序本身进行任何更改。
整个工作流程无需本地安装 Docker。Docker 镜像通过 GitHub Actions 构建并推送,Kubernetes 集群则在 GitHub Codespace 中运行。
之前:没有可观测性的服务
第 1 部分:构建应用程序
起点是一个极简的 Spring Boot REST API,没有配置任何可观测性。没有 OpenTelemetry,没有 Micrometer,没有日志框架——只有 web starter 和一个包含两个端点的控制器。这就是“之前”的状态:一个正在运行但完全不可见的服务。
1. 创建 pom.xml。创建一个只包含一个依赖项的 pom.xml:
只有一个依赖,没有遥测——这是刻意为之的。没有任何 OpenTelemetry 或指标库正是“之前”状态的核心意义所在。
2. 创建主应用程序类。创建 src/main/java/com/example/demo/DemoApplication.java:
这是标准的 Spring Boot 入口点——除了启动应用程序所需的最低配置外,没有其他内容。
3. 创建控制器。创建 src/main/java/com/example/demo/OrderController.java:
两个端点都没有日志、插桩或链路追踪——当此服务运行时,你无法了解其运行状态。
4. 构建应用
这会将应用程序打包成 target/ 目录下的一个可执行 JAR 文件,该文件将在下一步被复制到 Docker 镜像中。
第 2 部分:容器化与发布
要在 Kubernetes 中运行该应用,需要将其打包为容器镜像。我们不使用本地构建和推送 Docker 镜像,而是利用 GitHub Actions 在云端完成此操作。这避免了对本地 Docker 安装的需求。
1. 创建 Dockerfile。此 Dockerfile 使用 Azul Zulu 25 作为基础镜像。
2. 创建 GitHub Actions 工作流。创建 .github/workflows/build.yml。该工作流会构建 Maven 项目,使用存储库密钥登录 Docker Hub,并推送镜像。它会在每次推送到主分支时自动触发。
3. 将 Docker Hub 密钥添加到 GitHub。进入 GitHub 仓库的 Settings → Secrets and variables → Actions 并添加:
DOCKER_USERNAME—— 你的 Docker Hub 用户名DOCKER_PASSWORD—— 你的 Docker Hub 密码或访问令牌
推送工作流文件后,GitHub Actions 将自动构建并将镜像推送到 Docker Hub。
延伸阅读:
第 3 部分:部署到 Kubernetes
镜像上传到 Docker Hub 后,我们可以将其部署到 Kubernetes。我们使用 GitHub Codespaces 作为环境,它提供了一个浏览器内的完整 Linux 终端,无需任何本地工具。在此环境中,我们安装 kind,它会在 Codespace 内启动一个集群。
1. 打开 Codespace。进入 GitHub 仓库,点击 Code → Codespaces → Create codespace on main。
2. 安装 kind 并创建集群
3. 创建 Kubernetes 清单。该清单定义了一个包含一个副本的 Deployment 和一个将其暴露在 80 端口的 Service。镜像引用直接指向前一步推送到 Docker Hub 的镜像。
创建 deployment.yaml:
4. 部署应用。应用清单并更新镜像引用以指向正确的 Docker Hub 镜像:
等待 Pod 显示为 Running。
延伸阅读:
第 4 部分:生成流量(初始状态)
由于我们在 Codespace 内部,而不是在本地运行,因此服务无法直接在 localhost 上访问。我们使用 kubectl port-forward 来弥补这一差距。这就是初始状态——服务正在运行并接收流量,但 Dash0 中没有任何显示。没有链路追踪,没有指标,没有日志。
1. 启动端口转发(终端 1)
2. 启动流量循环(终端 2)。打开第二个终端并运行:
之后:使用 Dash0 Operator 添加可观测性
第 5 部分:安装 Dash0 Operator
现在我们添加可观测性——无需触碰应用程序代码、pom.xml 或 Docker 镜像。Dash0 Operator 使用 Helm 安装到集群中。它运行在自己的命名空间中,负责将插桩注入工作负载,并将遥测数据转发到 Dash0。
请注意,正确的 Helm 仓库 URL 是 https://dash0hq.github.io/dash0-operator。请在一行中运行安装命令以避免 shell 解析错误。将 <your-region> 替换为您 Dash0 入口端点中的区域,将 <your-auth-token> 替换为您 Dash0 组织中的身份验证令牌。两者都可以在 Dash0 的 Settings → Auth Tokens 中找到。
1. 添加 Helm 仓库并安装 Operator(终端 3)
2. 验证 Operator 是否正在运行
等待 Operator Pod 显示为 Running。
延伸阅读:
- https://github.com/dash0hq/dash0-operator
- https://artifacthub.io/packages/helm/dash0-operator/dash0-operator
- https://www.dash0.com/docs/dash0/dash0-kubernetes-operator
第 6 部分:配置 Operator
仅安装 Helm Chart 是不够的。Operator 还需要一个 Dash0OperatorConfiguration 资源来了解将遥测数据发送到哪里,以及一个 Dash0Monitoring 资源来了解要对哪个命名空间进行插桩。缺少这两者,数据将无法流入 Dash0。
1. 创建 Operator 配置资源
2. 启用命名空间的监控。此资源用于开启默认命名空间中所有工作负载的插桩。导出配置必须直接包含在资源中。
延伸阅读:
第 7 部分:重启与验证
Operator 通过初始化容器(init container)在 Pod 启动时注入插桩。由于 Pod 在创建监控资源之前已经在运行,因此需要重启它,以便 Operator 对其进行插桩。
1. 重启部署
等待新的 Pod 显示为 Running。
2. 重启端口转发(终端 1)。使用 Ctrl+C 终止现有的端口转发并重启:
终端 2 中的 curl 循环将自动恢复。
3. 打开 Dash0。访问 app.dash0.com。随着插桩后的 Pod 运行且流量流动,遥测数据将在 1 到 2 分钟内开始出现。我们没有对应用程序代码、pom.xml 或 Docker 镜像进行任何更改。唯一添加的就是 Dash0 Operator 和两个 Kubernetes 清单。
检查以下内容:
- Monitoring → Services:
order-service及其实时请求率、错误率和延迟。 - Telemetry → Tracing:每个
/orders请求的独立链路追踪。 - Telemetry → Logging:结构化日志。
- Monitoring → Kubernetes:Pod 和节点的资源使用情况。
延伸阅读: