QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

为 Jaeger 安装环境搭建监控基础设施

  • 2019-09-22
  • 本文字数:6191 字

    阅读完需:约 20 分钟

为Jaeger安装环境搭建监控基础设施

本文最初发表于RedHat开发者博客,经原作者 Juraci Paixão Kröhling 和 RedHat 授权由 InfoQ 中文站翻译分享。


在生产环境中部署Jaeger时,持续观察 Jaeger 实例,保证它的行为符合预期是非常重要的。毕竟,Jaeger 停机将会意味着跟踪数据的丢失,这样的话,我们很难理解生产环境的应用中究竟出现了什么问题。


本文将会介绍如何为 Jaeger 安装环境构建监控基础设施。首先,我们会为那些急切想监控 Jaeger 的读者提供现成资源的链接。


在第二部分中,我们会深入了解如何在Kubernetes集群中安装所有的工具,包括PrometheusGrafana和 Jaeger 本身,同时还会学习如何安装所需的工具,从而基于 Jaeger 官方的监控 mixin 自定义告警规则和 dashboard。


提示:如果你已经具有 Grafana、Prometheus 和 Jaeger 组成的可运行环境的话,那么你可能只关心基础 dashboard 和告警定义在什么地方,它们的地址如下:



如果你已经熟悉 mixin 的话,Jaeger 的官方监控 mixin 就可以在主资源仓库获取

预备条件

本指南假设你具备 Kubernetes 的 admin 访问权限。如果以测试为目的的话,有一种了解 Kubernetes 集群的简便方式,那就是在本地运行Minikube


本指南还需要用到jsonnetjb (jsonnet-bundler)。它们可以借助 go get,在本地机器通过如下命令安装:



1. $ go get github.com/google/go-jsonnet/cmd/jsonnet2. $ go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
复制代码

安装 Prometheus、Alertmanager 和 Grafana

在 Kubernetes 之上安装 Prometheus 可以通过多种方式来实现。其中一种方式是使用kube-prometheus项目,但是也可以直接使用Prometheus Operator,还可以使用Prometheus Operator的社区Helm chart。在本指南中,我们会使用 kube-prometheus 来获取 Prometheus、Alertmanager 和 Grafana 实例。


首先,我们使用 jb 生成一个基础 jsonnet 文件,该文件描述了我们的安装需求,将 kube-prometheus 作为依赖添加进来:



1. $ jb init2. $ jb install \3. github.com/jaegertracing/jaeger/monitoring/jaeger-mixin@master \4. github.com/grafana/jsonnet-libs/grafana-builder@master \5. github.com/coreos/kube-prometheus/jsonnet/kube-prometheus@master
复制代码


完成之后,我们需要有一个名为 jsonnetfile.json 的 manifest 文件,它大致如下所示:



1. {2. "dependencies": [3. {4. "name": "mixin",5. "source": {6. "git": {7. "remote": "https://github.com/jpkrohling/jaeger",8. "subdir": "monitoring/mixin"9. }10. },11. "version": "1668-Move-Jaeger-mixing-to-main-repo"12. },13. {14. "name": "grafana-builder",15. "source": {16. "git": {17. "remote": "https://github.com/grafana/jsonnet-libs",18. "subdir": "grafana-builder"19. }20. },21. "version": "master"22. },23. {24. "name": "kube-prometheus",25. "source": {26. "git": {27. "remote": "https://github.com/coreos/kube-prometheus",28. "subdir": "jsonnet/kube-prometheus"29. }30. },31. "version": "master"32. }33. ]34. }
复制代码


install 命令应该还会创建一个名为 vendor 的目录,其中包含了所有的 jsonnet 依赖。现在,我们所需要就是一个 deployment 描述符:创建一个名为 monitoring-setup.jsonnet 的文件,内容如下:



1. local kp =2. (import 'kube-prometheus/kube-prometheus.libsonnet') +3. {4. _config+:: {5. namespace: 'monitoring',6. },7. };8. 9. { ['00namespace-' + name + '.json']: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +10. { ['0prometheus-operator-' + name + '.json']: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +11. { ['node-exporter-' + name + '.json']: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +12. { ['kube-state-metrics-' + name + '.json']: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +13. { ['alertmanager-' + name + '.json']: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +14. { ['prometheus-' + name + '.json']: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +15. { ['prometheus-adapter-' + name + '.json']: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +16. { ['grafana-' + name + '.json']: kp.grafana[name] for name in std.objectFields(kp.grafana) }
复制代码


这样,我们就能生成所需的 deployment manifest,并应用它们:



1. $ jsonnet -J vendor -cm manifests/ monitoring-setup.jsonnet2. $ kubectl apply -f manifests/
复制代码


第一次使用的时候,自定义资源定义(Custom Resource Definition,CRD)可能尚未就绪,这会导致如下的信息:



1. no matches for kind "ServiceMonitor" in version "monitoring.coreos.com/v1"
复制代码


如果出现这种情况的话,只需要再次应用一下这些 manifest 即可,因为它们是幂等的。


几分钟之后,我们应该就会有几个可用的_Deployment_和_Statefulset_资源了:



1. $ kubectl get deployments -n monitoring 2. NAME READY UP-TO-DATE AVAILABLE AGE3. grafana 1/1 1 1 56s4. kube-state-metrics 1/1 1 1 56s5. prometheus-adapter 1/1 1 1 56s6. prometheus-operator 1/1 1 1 57s7. 8. $ kubectl get statefulsets -n monitoring9. NAME READY AGE10. alertmanager-main 3/3 60s11. prometheus-k8s 2/2 50s
复制代码


我们可以直接连接服务的端口,检查一下 Prometheus 是否已经启动:



1. $ kubectl port-forward -n monitoring service/prometheus-k8s 9090:90902. $ firefox http://localhost:9090
复制代码


对 Grafana 执行相同的检查,默认凭证的用户名和密码都是_admin_:



1. $ kubectl port-forward -n monitoring service/grafana 3000:3000`2. `$ firefox http://localhost:3000`
复制代码

安装 Jaeger

Jaeger Operator 默认会安装到“observability”命名空间中。在本指南中,我们会将它放到“monitoring”命名空间中,与 Prometheus 和 Grafana 放到一起。为了实现这一点,我们需要通过 curl 获取 manifest,并将“observability”替换为“monitoring”,然后将输出提供给 kubectl:



1. $ kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/crds/jaegertracing_v1_jaeger_crd.yaml2. $ curl -s https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/service_account.yaml | sed 's/observability/monitoring/gi' | kubectl apply -f -3. $ curl -s https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/role.yaml | sed 's/observability/monitoring/gi' | kubectl apply -f -4. $ curl -s https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/role_binding.yaml | sed 's/observability/monitoring/gi' | kubectl apply -f -5. $ curl -s https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/operator.yaml | sed 's/observability/monitoring/gi' | kubectl apply -f -
复制代码


在撰写本文的时候,最新版本为 v1.13.1,所以你可以修改上述 URL 以匹配所需的版本。几分钟之后,Jaeger Operator 就能启动并运行了:



1. $ kubectl get deployment/jaeger-operator -n monitoring2. NAME READY UP-TO-DATE AVAILABLE AGE3. jaeger-operator 1/1 1 1 23s
复制代码


Jaeger Operator 准备就绪之后,我们就可以创建名为 tracing 的 Jaeger 实例了:



1. kubectl apply -f - <<eof2. apiVersion: jaegertracing.io/v13. kind: Jaeger4. metadata:5. name: tracing6. namespace: monitoring7. EOF</eof
复制代码


稍等片刻,Jaeger 实例就会准备就绪:



1. $ kubectl get deployment/tracing -n monitoring 2. NAME READY UP-TO-DATE AVAILABLE AGE3. tracing 1/1 1 1 17s4. 5. $ kubectl get ingress -n monitoring 6. NAME HOSTS ADDRESS PORTS AGE7. tracing-query \* 192.168.122.181 80 26s
复制代码


我们可以在 Web 浏览器中通过给定的 IP 地址访问 Jaeger UI。在本例中,也就是http://192.168.122.181/,但是你的 IP 可能会有所不同。


现在,所有的内容都运行起来了,接下来我们安装业务应用,并通过 instrument 操作让它为接收到的每个请求都创建 span:



1. $ kubectl apply -n default -f https://raw.githubusercontent.com/jaegertracing/jaeger-operator/v1.13.1/deploy/examples/business-application-injected-sidecar.yaml
复制代码


部署完成之后,我们可以直接打开一个到 Pod 的连接并向其发送请求:



1. $ kubectl get -n default deployment/myapp 2. NAME READY UP-TO-DATE AVAILABLE AGE3. myapp 1/1 1 1 26s4. 5. $ kubectl port-forward deployment/myapp 8080:80806. $ watch -n 0.5 curl localhost:8080
复制代码


这样每秒钟会生成两个 HTTP 请求,在 Jaeger UI 中,我们应该会看到每个 HTTP 请求都会有一个 trace。

创建 PodMonitor

现在,我们已经有了一组功能齐全的监控服务:Prometheus、Grafana、Alertmanager 和 Jaeger。但是,Jaeger deployment 所生成的指标并没有被 Prometheus 所捕获:我们需要创建一个 ServiceMonitor 或 PodMonitor,以便于告诉 Prometheus 到哪里获取数据。


根据组件的不同,指标会由不同的端口来提供:


组件端口
Agent14271
Collector14269
Query16687
All in one14269


我们所创建的 Jaeger 实例并没有指定strategy,所以将会使用默认的 strategy,即 allInOne。我们的 PodMonitor 要告诉 Prometheus 从 14269 端口获取指标:



1. $ kubectl apply -f - <<eof2. apiVersion: monitoring.coreos.com/v13. kind: PodMonitor4. metadata:5. name: tracing6. namespace: monitoring7. spec:8. podMetricsEndpoints:9. - interval: 5s10. targetPort: 1426911. selector:12. matchLabels:13. app: jaeger14. EOF</eof
复制代码


Prometheus 可能需要花费几分钟的时间才能找到这个新的 target。进入 Targets 页面,查找 monitoring/tracing/0 这个 target。Prometheus 捕获到 Jaeger 的指标端点之后,我们就可以在 Prometheus Graph 视图中看到 Jaeger 的指标了。例如,进入 jaeger_collector_traces_saved_by_svc_total 并点击 Execute。图中显示的 trace 数量应该随着时间的推移而增加,它反映了前面步骤中针对业务应用程序运行的 HTTP 请求的数量。


适配 mixin

现在,我们已经在 Prometheus 中获得了来自 Jaeger 实例的指标数据,但是应该在 dashboard 上显示哪些指标,在什么情况下应该生成哪些告警呢?


很难找到一个通用的、适合所有情况的答案来回答这些问题,但是我们在 Grafana 实验室的朋友们为 Jaeger 设计了一个 mixin,它可以作为你自己的 dashboard 和告警的一个起点。此后,该 mixin 贡献了给 Jaeger 项目,并且可以在主存储库下访问。


让我们回到最初的 monitoring-setup.jsonnet,并添加 Jaeger 特定的 dashboard 和告警规则:



1. local jaegerAlerts = (import 'jaeger-mixin/alerts.libsonnet').prometheusAlerts;2. local jaegerDashboard = (import 'jaeger-mixin/mixin.libsonnet').grafanaDashboards;3. 4. local kp =5. (import 'kube-prometheus/kube-prometheus.libsonnet') +6. {7. _config+:: {8. namespace: 'monitoring',9. },10. grafanaDashboards+:: {11. 'jaeger.json': jaegerDashboard['jaeger.json'],12. },13. prometheusAlerts+:: jaegerAlerts,14. };15. 16. { ['00namespace-' + name + '.json']: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +17. { ['0prometheus-operator-' + name + '.json']: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +18. { ['node-exporter-' + name + '.json']: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +19. { ['kube-state-metrics-' + name + '.json']: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +20. { ['alertmanager-' + name + '.json']: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +21. { ['prometheus-' + name + '.json']: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +22. { ['prometheus-adapter-' + name + '.json']: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +23. { ['grafana-' + name + '.json']: kp.grafana[name] for name in std.objectFields(kp.grafana) }
复制代码


接下来,生成新的 manifest:


$ jsonnet -J vendor -cm manifests/ monitoring-setup.jsonnet


这里只会改变几个 manifest,但是我们可以安全地再次应用所有的 manifest:



1. $ kubectl apply -f manifests/
复制代码


稍等片刻之后,将会有一个新的 Grafana pod 替代之前的:



1. $ kubectl get pods -n monitoring -l app=grafana2. NAME READY STATUS RESTARTS AGE3. grafana-558647b59-fkmr4 1/1 Running 0 11m4. grafana-7bcb7f5b9b-6rv2w 0/1 Pending 0 8s
复制代码


注意:当使用 Minikube 时,新 pod 可能会由于 Insufficient cpu 而处于 Pending 状态。我们可以通过运行 kubectl describe -n monitoring pod POD_NAME 来检查原因,并使用 kubectl delete -n monitoring pod POD_NAME 手动删除旧的 pod,或者使用标记–cpus 以更高的值来启动 minikube。


新的 Grafana pod 启动并运行之后,我们应该会看到 Grafana 有一个新的 Jaeger 仪表板,显示 Prometheus 提供的数据。类似地,Prometheus 中也会有一个新的告警规则:查找名称中带有“Jaeger”的规则,比如 JaegerCollectorQueueNotDraining:


总结

在云原生微服务领域中,部署可观察性工具为业务应用程序提供洞察能力是必备的,另外,监视这些工具本身的行为也是必要的。本文展示了在 Kubernetes 中搭建完整技术栈并运行起来的一种方法,最终目标是使用 Jaeger 自己的内部指标来监视 Jaeger。相同的方式可以扩展至让 Prometheus 获取业务应用的指标,并以 Grafana 作为 dashboard 工具来对数据进行可视化。


2019-09-22 08:003563

评论

发布
暂无评论
发现更多内容

Ipfs靠谱吗?ipfs中国授权公司都有哪些?

分布式存储 区块链+ IPFS fil

用区块链加强知识产权保护

CECBC

Web 框架 Gin | Gin 介绍

xcbeyond

Go 语言 gin 8月日更

手把手 Golang 实现静态图像与视频流人脸识别

声网

音视频 人脸识别

CSS 文档中定位指南:static、relative、absolute、fixed、sticky

devpoint

CSS 8月日更

RESTful API

escray

学习 极客时间 如何落地业务建模 8月日更

fil矿机怎么购买?fil矿机在哪买?

fil矿机怎么购买 fil矿机在哪买

从新手村出来,我在 Apache APISIX 社区发出了第一个 PR

API7.ai 技术团队

开源 后端 API网关 APISIX

记一次PHP渗透测试实战教程

网络安全学海

php 网络安全 信息安全 渗透测试 安全漏洞

🏆「作者推荐」【JVM 性能调优】JVM分析与调优技巧分析(原理篇)

洛神灬殇

JVM JVm虚拟机 8月日更

仿imtoken钱包源码,TP钱包源码开发

MySQL知识点整理

一个大红包

8月日更

数据缓存历险记(五)--LRU缓存算法的最终篇

卢卡多多

缓存 LRU Redis 协议 8月日更

ipfs矿机挖币哪家最好?ipfs矿机公司实力排行如何?

ipfs矿机挖币哪家最好 ipfs矿机公司实力排行如何

企业不可忽视的三大关键时刻

石云升

管理经验 关键时刻 体验设计 8月日更

新药开发瓶颈问题或将被打破,北鲲云超算平台开启药物研发“加速度”

北鲲云

Android开发:引入重复包报错Error:Execution failed for task ‘:app:transform...’解决方法

三掌柜

8月日更 8月

基于时间和窗口的算子(六)

Databri_AI

flink 窗口函数 算子

从安卓转到Java开发,我吃透了这份pdf,终于4面拿下美团offer

Java~~~

Java spring 面试 微服务 JVM

【设计模式】代理模式

Andy阿辉

C# 后端 设计模式 8月日更

异步编程的终极解决方案 async/await:用同步的方式去写异步代码

前端依依

大前端 js 经验分享 异步 知识讲解

MinIO Client 使用(一)

耳东@Erdong

Minio 8月日更 mc minio client

区块链难懂?人民日报评论员讲给你听

CECBC

【前端 · 面试 】HTTP 总结(十一)—— HTTPS 概述

编程三昧

面试 https 8月日更

写作 7 堂课——【6. 清单式写作】

LeifChen

清单 写作技巧 8月日更 检查清单

LeetCode题解:80. 删除有序数组中的重复项 II,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

端口占用解决方案

一个大红包

8月日更

融云CTO杨攀:把握核心技术,促进产学研用融合发展

融云 RongCloud

DeFi去中心化平台源码开发|智能合约系统搭建

量化系统19942438797

前端之算法(一)

Augus

数据结构与算法 8月日更

网络攻防学习笔记 Day102

穿过生命散发芬芳

态势感知 网络攻防 8月日更

为Jaeger安装环境搭建监控基础设施_软件工程_Juraci Paixão Kröhling_InfoQ精选文章