抖音技术能力大揭密!钜惠大礼、深度体验,尽在火山引擎增长沙龙,就等你来! 立即报名>> 了解详情
写点什么

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

2019 年 9 月 22 日

为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 年 9 月 22 日 08:002235

评论

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

数字货币交易系统定制开发,区块链交易所

135深圳3055源中瑞8032

netfilter/iptables 原理

为为

Service Mesh Linux Kenel

2020年第三季度《全国移动App 风险监测评估报告》

InfoQ_11eaedef67e9

App 移动安全 个人隐私安全

vidyo在数字化办公中提供了什么便利?

dwqcmo

音视频 集成架构 解决方案 智能硬件

腾讯技术官又曝神作,两份堪称‘千古绝唱’操作系统笔记现已被全网疯传

云流

编程 操作系统 计算机

推荐一款MySQL开源客户端,免费+跨平台+使用便捷!

王磊

MySQL

惊险的B站Java后端岗面试之旅,复盘面试经历及面试真题

Java架构之路

Java 程序员 面试 编程语言

手把手带你玩转 openEuler | 如何安装 openEuler

openEuler

Linux 开源 操作系统 openEuler

BATJ内部Java求职面试宝典,尤其应届生如果还没有学过那后悔去吧,也许你已经错过N多家大厂offer;

Java架构师迁哥

[Go 并发编程实战课]02.Mutex 源代码

Custer

go

WebSocket从入门到精通,半小时就够!

JackJiang

html5 网络编程 websocket 即时通讯

解释一下==和equals的区别,你以为就这么简单?那你就草率了

小Q

Java 学习 架构 面试 基础

区块链钱包开发需要注意哪些问题?区块链数字钱包搭建

135深圳3055源中瑞8032

UBBF2020:智能联接,共创行业价值新增长

DT极客

Python 疑难问题:[] 与 list() 哪个快?为什么快?快多少呢?

Python猫

Python 学习 编程 程序员

蚁架构师首推SpringBoot套餐(原理+实战+面试)

小Q

Java 学习 架构 微服务 SpringBoot 2

4年Java经验,备战两月成功拿到美团、京东、字节offer

Java架构之路

Java 程序员 面试 编程语言

面向对象编程会被抛弃吗?这五大问题不容忽视

Java架构师迁哥

合约跟单平台搭建,交易所跟单软件开发商

135深圳3055源中瑞8032

【全球案例】ESL 游戏公司如何通过 Jira 定制化解决方案连接全球团队

Atlassian

项目管理 敏捷 Atlassian Jira

随机森林原理介绍与适用情况(综述篇)

计算机与AI

数据挖掘 学习 数据科学 随机森林

极客时间架构师培训 1 期 - 第 4 周总结

Kaven

图解 K8S 源码 - QoS 篇

郭旭东

Kubernetes Kubernetes源码

甲方日常 30

句子

工作 随笔杂谈 日常 心情

Java零基础到进阶宝典!从小白到大神,金九银十面试这届斩获23K月薪

Java架构追梦

Java 学习 架构 面试 核心知识点

详细分析定制企业应用的价格

Philips

敏捷开发 快速开发

详细讲解:python中的lambda与sorted函数

计算机与AI

Python

Anaconda安装使用和akshare库使用

MySQL从删库到跑路

Python 数据分析 Windows 10 Anaconda akshare

月薪60k的Java开发在阿里是什么级别?对技术能力有哪些要求?

Java架构之路

Java 阿里巴巴 程序员 面试 编程语言

教育场景方案升级| 打通业务前后端,少量开发快速上线(一):互动小班

ZEGO即构

在线教育 低代码

区块链USDT支付开发方案,USDT跨境支付搭建

135深圳3055源中瑞8032

Study Go: From Zero to Hero

Study Go: From Zero to Hero

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