专栏首页千里行走istio-3:istio-1.4.2-demo链路体验之jaeger

istio-3:istio-1.4.2-demo链路体验之jaeger

目录:

(1).准备工作

(2).jaeger体验

1.初步跑起

2.面板与功能解析

2.1.概述

2.2.Search

2.2.1.支持的查询条件

2.2.2.Trace耗时分布点位图

2.2.3.compare操作

2.2.4.查看trace详情

2.3.Compare

2.4.Dependencies

2.4.1. Force Directed Graph

2.4.2.DAG Graph

(3).加长链路调用

1.不做代码修改增加调用链flaskapp-server -> httpbin

2.代码修改flaskapp后增加调用链flaskapp-server -> httpbin

(4).ingress开放jaeger服务

(5).面向 DevOps 的诊断与分析系统

(6).思考

1.基础架构思考

2.新技术引入与做事思考

(7).参考资料与引述

(8).笔者相关文章

(9).招聘

a.阅读/实践本文请先行阅读/实践笔者公众号相关文章:

istio-1:部署与体验istio-1.4.2 istio-2:istio1.4.2-demo部署与体验,聊聊一些个人看法

b.本文主要以《深入浅出Istio:Service Mesh快速入门与实践》中的python-flask-demo为例论述。

c.架构实战交流钉钉群号:23394754

(1).准备工作

1.确保istio和istio-demo-app容器化

需要按照之前文章完成istio和istio-demo-app的容器化:

istio-1:部署与体验istio-1.4.2

istio-2:istio1.4.2-demo部署与体验,聊聊一些个人看法

确保istio基础组件正常:

kubectl get pod -n istio-system  
NAME                                     READY   STATUS    RESTARTS  AGE
grafana-f5585fb49-dcvhr                   1/1     Running  1          16d
istio-citadel-744f9798bb-lq4hc            1/1     Running  1          16d
istio-egressgateway-5c7cc9fb4-qwpwc       1/1    Running   1          16d
istio-galley-d4b8f88c8-ft2pv              1/1     Running  1          16d
istio-ingressgateway-b44fbfbf8-5jwm8      1/1    Running   1          16d
istio-pilot-65699c97df-gcnrv              1/1     Running  0          32h
istio-policy-999dfdb69-d6gcb              1/1     Running  11         16d
istio-sidecar-injector-684fcc7cfb-p87tk   1/1    Running   1          16d
istio-telemetry-7cdf8bf67c-59snl          1/1     Running  0          34h
istio-tracing-bc44d8d85-2bgl2             1/1     Running  0          46h
kiali-767f877b4-zzgvq                     1/1     Running  1          16d
prometheus-5d56488ff6-7nrqv               1/1     Running  1          16d

确保istio-demo组件正常:

kubectl get pod -n istio-app
NAME                                      READY   STATUS    RESTARTS  AGE
flaskapp-v1-68498d7745-x7665               2/2     Running  0          7d
flaskapp-v2-5b64f9874-z9k2z                2/2     Running  0          7d
simple-flask-app-client-584588ccbd-rtkv9   2/2    Running   7          7d

2.jaeger-web服务暴露

需要将jaeger-web服务暴露到容器外部,然后可以通过浏览器访问。

需要两次端口转发:

kubectl port-forward -n istio-system$(kubectl get pod -n istio-system -l app=jaeger -ojsonpath='{.items[0].metadata.name}') 16686:16686

ssh -N -f -L 0.0.0.0:16687:127.0.0.1:16686 root@0.0.0.0

然后通过浏览器访问:

http://ip:16687/

(2).jaeger体验

1.初步跑起

进入istio-demo-client:

kubectl exec -it -n istio-appsimple-flask-app-client-584588ccbd-rtkv9 -- /bin/bash

执行命令向istio-demo-flask-server发起请求:

for i in `seq 10000`; do http --body http://flaskapp:7777/env/version;done

稍等几秒让他跑数据,然后访问jaeger-web:

sleep.istio-app:是本例中的isito-demo-client

flaskapp.istio-app:是本例中的istio-demo-server

jaeger-query:jaeger-web

2.面板与功能解析

2.1.概述

jaeger面板共包含三大模块:Search,Compare,Dependencies。

Search

主要是提供多维度多视角的链路(trace)查询,查询方式支持传统下拉框和jsonfile两种形式。

Compare

比较两个trace。

Dependencies

查看服务依赖图/拓扑图。

2.2.Search

2.2.1.支持的查询条件

多维度/多视角查询trace。

Service

2.2.2.Trace耗时分布点位图

可以看到查询结果所有trace在这个时间段内的耗时分布。

2.2.3.compare操作

在查询结果中选择你要对比的trace:

然后点击Compare Trace后跳入Compare模块,然后进行对比分析:

总感觉目前功能有点少。

2.2.4.查看trace详情

在查询结果中左键点击任意一个trace:

会出现一个trace概览:

再点击链路上的具体节点,可以看到这个Trace各节点详情:

Trace查询条件里的tag可以在这里找。

不得不提一点,老外的UI风格非常对我胃口,简约而不简单,这也算是我的做事原则之一吧。

2.3.Compare

这里不赘述了,在Search里顺带提了。

2.4.Dependencies

查看服务依赖图/拓扑图,提供两种图形:DAG,Force Directed Graph。

2.4.1. Force Directed Graph

导引图。

本例形式:

生产完整形式应该是这个程度:

2.4.2.DAG Graph

一条 Trace(调用链)可以被认为是一个由多个 Span 组成的有向无环图(DAG图)。

本例形式:

其中的数字10949是发生的指调用次数。

生产的大概形式:

(3).加长链路调用

目前链路是:istio-demo-client -> istio-demo-flaskapp

1.不做代码修改增加调用链flaskapp-server -> httpbin

我们现在让istio-demo-flaskapp调用另一个服务,然后我们看看是结果。

我们让istio-demo-flaskapp调用httpbin服务,位于:

https://github.com/istio-learning/istio-demo/tree/master/istio-1.4.2/istio-offical-samples/httpbin

将httpbin进行istio化:

istioctl kube-inject -f httpbin.yaml >httpbin-istio.yaml

将httpbin纳入istio管理:

kubectl apply -f httpbin-istio.yaml

我们接下来在simple-flask-app-client的pod中发起请求,要求flaskapp调用httpbin服务的“get”路径,并返回httpbin给出的响应,同时要显示出simple-flask-app-client发出的请求Header的内容:

进入发起Pod:

kubectl exec -it -n istio-appsimple-flask-app-client-584588ccbd-z9mnq -- /bin/bash

执行命令:

http --debug http://flaskapp:7777/fetch?url=http://httpbin:8000/get

fetch代码如下,打印接受到的client发送的request_header以及发送给httpbin服务的request_header,注意观察两者的不同:

@app.route('/fetch')
def fetch_env():
   url = request.args.get('url', '')
   request_headers = dict(request.headers)
    with urlopen(url) as response:
       res = response.read()
       return "{}\n{}".format(json.dumps(request_headers), res)

http命令其完整结果为:

HTTPie 0.9.9
Requests 2.19.1
Pygments 2.2.0
Python 3.6.6 (default, Aug 24 2018,05:04:18)
[GCC 6.4.0]
/usr/bin/python3
Linux 3.10.0-957.27.2.el7.x86_64
 
<Environment {
   "colors": 8,
   "config": {
       "__meta__": {
           "about": "HTTPie configuration file",
           "help": "https://httpie.org/docs#config",
           "httpie": "0.9.9"
       },
       "default_options": "[]"
   },
   "config_dir": "/root/.httpie",
   "is_windows": false,
   "stderr": "<_io.TextIOWrapper name='<stderr>'mode='w' encoding='UTF-8'>",
   "stderr_isatty": true,
   "stdin": "<_io.TextIOWrapper name='<stdin>'mode='r' encoding='UTF-8'>",
   "stdin_encoding": "UTF-8",
   "stdin_isatty": true,
   "stdout": "<_io.TextIOWrapper name='<stdout>'mode='w' encoding='UTF-8'>",
   "stdout_encoding": "UTF-8",
   "stdout_isatty": true
}>
 
>>> requests.request(**{
   "allow_redirects": false,
   "auth": "None",
   "cert": "None",
   "data": {},
   "files": {},
    "headers": {
       "User-Agent": "HTTPie/0.9.9"
   },
   "method": "get",
   "params": {},
   "proxies": {},
   "stream": true,
   "timeout": 30,
   "url":"http://flaskapp:7777/fetch?url=http://httpbin:8000/get",
   "verify": true
})
 
HTTP/1.1 200 OK
content-length: 785
content-type: text/html; charset=utf-8
date: Sun, 12 Jan 2020 02:09:06 GMT
server: envoy
x-envoy-upstream-service-time: 9
 
{"Host":"flaskapp:7777", "User-Agent": "HTTPie/0.9.9","Accept-Encoding": "gzip, deflate", "Accept":"*/*", "X-Forwarded-Proto": "http","X-Request-Id": "d8e64f39-554f-9ce8-b57a-50100a244248","Content-Length": "0", "X-B3-Traceid":"70581e6826c6b85d142280f15bd5e0eb", "X-B3-Spanid":"d1c1b20bbbfc2c68", "X-B3-Parentspanid": "142280f15bd5e0eb","X-B3-Sampled": "1"}
b'{\n "args": {}, \n "headers": {\n   "Accept-Encoding": "identity", \n    "Content-Length": "0",\n    "Host":"httpbin:8000", \n   "User-Agent": "Python-urllib/3.6", \n    "X-B3-Parentspanid":"d5ed195b2fb6fb97", \n   "X-B3-Sampled": "1", \n    "X-B3-Spanid":"2d3c5ab545b4fa95", \n   "X-B3-Traceid": "1a3a407555647b51d5ed195b2fb6fb97"\n  }, \n "origin": "127.0.0.1", \n  "url": "http://httpbin:8000/get"\n}\n'

此时会发现,在simple-flaskapp-client(sleep)的pod中的httpie客户端发出的请求Header的原始内容为:

"allow_redirects": false,
   "auth": "None",
   "cert": "None",
   "data": {},
   "files": {},
   "headers": {
       "User-Agent": "HTTPie/0.9.9"
   },
   "method": "get",
   "params": {},
   "proxies": {},
   "stream": true,
   "timeout": 30,
   "url":"http://flaskapp:7777/fetch?url=http://httpbin:8000/get",
   "verify": true

而flaskapp-server收到的请求Header的内容却复杂得多,注意X-Request-Id

{
         "Host":"flaskapp:7777",
         "User-Agent":"HTTPie/0.9.9",
         "Accept-Encoding":"gzip, deflate",
         "Accept":"*/*",
         "X-Forwarded-Proto":"http",
         "X-Request-Id":"d8e64f39-554f-9ce8-b57a-50100a244248",
         "Content-Length":"0",
         "X-B3-Traceid":"70581e6826c6b85d142280f15bd5e0eb",
         "X-B3-Spanid":"d1c1b20bbbfc2c68",
         "X-B3-Parentspanid":"142280f15bd5e0eb",
         "X-B3-Sampled":"1"
}

我们再看flaskapp-server发向httpbin的请求header,可以发现没有将flaskapp-server接收到的X-Request-Id向后传递给httpbin,那么我们可以进行一个合理推测,即我们看不到simple-flask-client -> simple-flask-server -> httpbin链路,看到的应该是两条割裂链路,即,simple-flask-client-> simple-flask-server 与 simple-flask-server-> httpbin,事实也确实如此,注意看两个链路的X-B3-Traceid是不同的,说明是两个Trace。

"Accept-Encoding":"identity",
         "Content-Length":"0",
         "Host":"httpbin:8000",
         "User-Agent":"Python-urllib/3.6",
         "X-B3-Parentspanid":"d5ed195b2fb6fb97",
         "X-B3-Sampled":"1",
         "X-B3-Spanid":"2d3c5ab545b4fa95",
         "X-B3-Traceid":"1a3a407555647b51d5ed195b2fb6fb97"

我们查看Trace,很明显是两个割裂的,并不是我们预期的完整调用链:client -> server -> httpbin:

原因就在于没有将X-Request-Id等与链路相关的Header向后传递,所以造成无法将不同的调用识别为同一个Trace的结果。

2.代码修改flaskapp后增加调用链flaskapp-server -> httpbin

我们增加fetch_with_header方法,以区别fetch方法,将接收到的reqeust中Trace相关的header向后传递给httpbin:

TRACE_HEADERS = [
   'x-request-id',
   'x-b3-parentspanid',
   'x-b3-sampled',
   'x-b3-spanid',
   'x-b3-traceid',
   'x-b3-flags',
   'x-ot-span-context'
]
 
@app.route('/fetch_with_header')
def fetch_with_headers():
   url = request.args.get('url', '')
   request_headers = dict(request.headers)
   new_header = {}
   for key in request_headers.keys():
       if key.lower() in TRACE_HEADERS:
           new_header[key] = request_headers[key]
 
   req = Request(url, headers = new_header)
   res =urlopen(req).read()
   #打印原request_header,request_header,Httpbin返回的response
   return "{}\n{}\n{}".format(json.dumps(request_headers),json.dumps(new_header), res)

然后发起请求:

http --debug http://flaskapp:7777/fetch_with_header?url=http://httpbin:8000/get

完整结果如下:

HTTPie 0.9.9
Requests 2.19.1
Pygments 2.2.0
Python 3.6.6 (default, Aug 24 2018,05:04:18)
[GCC 6.4.0]
/usr/bin/python3
Linux 3.10.0-957.27.2.el7.x86_64
 
<Environment {
   "colors": 8,
   "config": {
       "__meta__": {
           "about": "HTTPie configuration file",
           "help": "https://httpie.org/docs#config",
           "httpie": "0.9.9"
       },
       "default_options": "[]"
   },
   "config_dir": "/root/.httpie",
   "is_windows": false,
   "stderr": "<_io.TextIOWrapper name='<stderr>'mode='w' encoding='UTF-8'>",
   "stderr_isatty": true,
   "stdin": "<_io.TextIOWrapper name='<stdin>'mode='r' encoding='UTF-8'>",
   "stdin_encoding": "UTF-8",
   "stdin_isatty": true,
   "stdout": "<_io.TextIOWrapper name='<stdout>'mode='w' encoding='UTF-8'>",
   "stdout_encoding": "UTF-8",
   "stdout_isatty": true
}>
 
>>> requests.request(**{
   "allow_redirects": false,
   "auth": "None",
   "cert": "None",
   "data": {},
   "files": {},
   "headers": {
       "User-Agent": "HTTPie/0.9.9"
   },
   "method": "get",
   "params": {},
   "proxies": {},
   "stream": true,
   "timeout": 30,
   "url":"http://flaskapp:7777/fetch_with_header?url=http://httpbin:8000/get",
   "verify": true
})
 
HTTP/1.1 200 OK
content-length: 991
content-type: text/html; charset=utf-8
date: Sun, 12 Jan 2020 07:06:59 GMT
server: envoy
x-envoy-upstream-service-time: 11
 
{"Host":"flaskapp:7777", "User-Agent": "HTTPie/0.9.9","Accept-Encoding": "gzip, deflate", "Accept":"*/*", "X-Forwarded-Proto": "http","X-Request-Id": "6d442409-6a77-9eed-89d6-e55d4a6bbca8","Content-Length": "0", "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90", "X-B3-Spanid":"d242b2985286bb23", "X-B3-Parentspanid":"f0eff6b65f626b90", "X-B3-Sampled": "1"}
{"X-Request-Id":"6d442409-6a77-9eed-89d6-e55d4a6bbca8", "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90", "X-B3-Spanid":"d242b2985286bb23", "X-B3-Parentspanid":"f0eff6b65f626b90", "X-B3-Sampled": "1"}
b'{\n "args": {}, \n "headers": {\n   "Accept-Encoding": "identity", \n    "Content-Length": "0",\n    "Host":"httpbin:8000", \n   "User-Agent": "Python-urllib/3.6", \n    "X-B3-Parentspanid":"eb582674eccb9c14", \n   "X-B3-Sampled": "1", \n    "X-B3-Spanid":"421ffd362db50cc2", \n   "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90"\n }, \n  "origin":"127.0.0.1", \n "url": "http://httpbin:8000/get"\n}\n'

我们对比下“flaskapp-server收到的请求Header”与“flaskapp-server发送给httpbin的Header”:

flaskapp-server收到的请求Header的内容:

         "Host":"flaskapp:7777",
         "User-Agent":"HTTPie/0.9.9",
         "Accept-Encoding":"gzip, deflate",
         "Accept":"*/*",
         "X-Forwarded-Proto":"http",
         "X-Request-Id":"6d442409-6a77-9eed-89d6-e55d4a6bbca8",
         "Content-Length":"0",
         "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90",
         "X-B3-Spanid":"d242b2985286bb23",
         "X-B3-Parentspanid":"f0eff6b65f626b90",
         "X-B3-Sampled":"1"

flask-server发送到httpbin的reqeustHeader内容:

         "X-Request-Id":"6d442409-6a77-9eed-89d6-e55d4a6bbca8",
         "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90",
         "X-B3-Spanid":"d242b2985286bb23",
         "X-B3-Parentspanid":"f0eff6b65f626b90",
         "X-B3-Sampled":"1"

httpbin返回的response内容为,注意观察X-B3-Traceid,和前边的链是一致的,说明通过X-Request-Id将两个请求链结到了一起:

         "Accept-Encoding":"identity",
         "Content-Length":"0",
         "Host":"httpbin:8000",
         "User-Agent":"Python-urllib/3.6",
         "X-B3-Parentspanid":"eb582674eccb9c14",
         "X-B3-Sampled":"1",
         "X-B3-Spanid":"421ffd362db50cc2",
         "X-B3-Traceid":"8a211f31f620a1bff0eff6b65f626b90"

将修改后代码的Trace和修改代码前的Trace做比较,你会发现确实生效了:

观察具体的生效Trace,是完整的链路:flask-client -> flask-server -> httpbin

点开每个Span,你会发现都有一个X-Request-Id,并且值都一样,验证了整个Trace是通过X-Request-Id串联到一起的:

(4).ingress开放jaeger服务

本文提供ingress配置文件,下载然后执行:

https://github.com/hepyu/k8s-app-config/blob/master/yaml/min-cluster-allinone/istio/istio-1.4.2/istio-demo-jaeger-ingress.yaml

本地配置host后访问域名即可:jaeger-istio-demo.inc-inc.com

(5).面向 DevOps 的诊断与分析系统

本节论述节选自(笔者完全认同):

作者:猫耳呀 链接:https://www.jianshu.com/p/0859dac9320c 来源:简书

面向 DevOps 的诊断与分析系统,包括集中式日志系统(Logging),集中式度量系统(Metrics)和分布式追踪系统(Tracing)。

Logging,Metrics 和 Tracing 有各自专注的部分。

Logging - 用于记录离散的事件。例如,应用程序的调试信息或错误信息。它是我们诊断问题的依据。

Metrics - 用于记录可聚合的数据。例如,队列的当前深度可被定义为一个度量值,在元素入队或出队时被更新;HTTP 请求个数可被定义为一个计数器,新请求到来时进行累加。

Tracing - 用于记录请求范围内的信息。例如,一次远程方法调用的执行过程和耗时。它是我们排查系统性能问题的利器。

通过上述信息,我们可以对已有系统进行分类。

Trace领域:

zipkin,skywakling等。

Metric领域:

Prometheus 开始专注于 metrics,随着时间推移可能会集成更多的 tracing 功能,但不太可能深入 logging 领域。

笔者观点:

不认为prometheus可以替代Trace,比如从性能和实现角度来说Prometheus是时序数据库,而trace体量很大,prometheus作者设计的初衷就不是干这个的。

在metric领域,prometheus是无可争议的事实标准。

logging领域:

ELK,阿里云日志服务这样的系统,但同时也不断地集成其他领域的特性到系统中来,正向上图中的圆心靠近。

(6).思考

1.基础架构思考

我们都知道go由于语言本身特性是做不到java中skywalking那样非侵入性的trace支持,但是我们通过细节体验可以得出一个结论:可以将jaeger的支持放到基础框架中,这样可以是go的业务服务默认具备trace能力,实际上也可以达到“非侵入”目的。

jaeger相对skywalking优势:

jaeger更加轻量级;jaeger可以统一所有语言的Trace标准,这点非常好;目前看jaeger将会成为容器化背景下的事实标准,会有大量优秀公司和开发者“帮我们干活”。

这样综合看来,skywalking相对于jaeger的非侵入优势远不足以cover掉jaeger作为“统一标准能力”带来的收益。

2.新技术引入与做事思考

在互联网存量时代,细节更加重要,尤其对于新技术的引入,对于细节的了解程度以及基于此拓展的认知与方法论直接决定了你提出方案/论据的完备性与闭合性,这样才能大幅提高和通过公司级质疑与论证的概率。

同时才能不断的去论证/评估你对新技术终结程度;互联网存量时代下,对事务尤其是对重要事务的终结能力直接决定了公司/Team/个人的竞争力,以及赤裸裸的生存率。

(7).参考资料与引述

开放分布式追踪(OpenTracing)入门与 Jaeger 实现

https://www.jianshu.com/p/0859dac9320c

jaeger实战

https://www.dazhuanlan.com/2019/10/16/5da60eedcea1c/

Metrics, tracing, and logging

http://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html

《深入浅出Istio:Service Mesh快速入门与实践》

本文分享自微信公众号 - 千里行走(a_thousands_of_miles),作者:千里行走

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-01-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • istio-2:istio1.4.2-demo部署与体验,聊聊一些个人看法

    b.本文主要以《深入浅出Istio:Service Mesh快速入门与实践》中的python-flask-demo为例论述。

    千里行走
  • istio-1:部署与体验istio-1.4.2

    istio搁置有一段时间了,并且现在开始介入的是最新版本1.4.2,所以难免有些错误的地方,非常欢迎指正与讨论。

    千里行走
  • kubernetes-20:redis-cluster容器化

    笔者使用Redis容器化只用于本地环境,用于自己一些项目的调试(https://github.com/hepyu/saf)。

    千里行走
  • Istio Helm Chart 详解 - Mixer

    Mixer 是 Istio 的核心组件之一,负责服务网格中的遥测和策略两部分重要功能,因此 Mixer 的部署也分成了 Policy 和 Telemetry 两...

    崔秀龙
  • 教程 | OpenCV4中的极坐标变换

    极坐标变换就是将图像在直角坐标系与极坐标系中互相变换,形式如图3-26所示,它可以将一圆形图像变换成一个矩形图像,常用于处理钟表、圆盘等图像。圆形图案边缘上的文...

    OpenCV学堂
  • 【从零学习OpenCV 4】极坐标变换

    经过几个月的努力,小白终于完成了市面上第一本OpenCV 4入门书籍《从零学习OpenCV 4》。为了更让小伙伴更早的了解最新版的OpenCV 4,小白与出版社...

    小白学视觉
  • 抖音VS快手:两个世界的交战

    毫无疑问,抖音和快手是短视频行业的双寡头——前者自称DAU已经突破3亿,后者则计划在2020年春节达到3亿DAU。它们在短视频领域各自拥有不可撼动的基本牌,20...

    iCDO互联网数据官
  • PostgreSQL 10 流复制问题记录

    王果壳
  • 晶核教育创始人&CEO吴瑕:发力职业教育市场,从根本上解决行业人才短缺问题

    VRPinea
  • 10亿身家施一公!创办的医药公司冲刺IPO,西湖大学校长产学两开花

    这家上市公司之所以如此受关注,是因为中科院院士、西湖大学校长、清华大学教授施一公是这家公司的联合创始人。

    量子位

扫码关注云+社区

领取腾讯云代金券