ToB企服应用市场:ToB评测及商务社交产业平台

标题: 手摸手教你把Ingress Nginx集成进Skywalking [打印本页]

作者: 泉缘泉    时间: 2024-5-18 04:58
标题: 手摸手教你把Ingress Nginx集成进Skywalking
背景

在微服务大行其道的今天,如何观测众多微服务、快速理清服务间的依靠、如何对服务之间的调用性能举行衡量,成了摆在各人眼前的难题。对此,Skywalking应运而生,它是托管在 Apache 基金会下的开源项目,旨在帮助开发者监控分布式程序的性能、了解各个服务的调用关系和运行环境。
Skywalking支持多种语言和框架,包含Java、Golang、Python等,功能强盛、界面友爱等特点使其迅速成为业界最流行的APM软件之一。然而在运用Skywalking的过程中,我们常常更关注服务之间的调用链路、性能数据,往往会忽略流量入口(网关)到服务之间的Trace串联,导致我们常常在网关层面观测到一个错误调用后,无法通过TraceID快速查察本次调用的链路,从而白白浪费宝贵的排障时间。
本文重点介绍如何将 Ingress Nginx 集成进 Skywalking,将其作为 Skywalking 的一个节点,并且在access log 中打印TraceID,从而在出现故障的时候,可以通过日志中的TraceID快速找到调用链路,达到快速故障定位的效果。
注:本文使用的 Kubernetes 版本是 1.24.15,Ingress Nginx controller 版本是 v1.8.1,Skywalking版本是9.2.0。
方案

在介绍方案之前,我们先了解一下相关的背景知识,用于更好的理解集成方案。

了解了上述原理后,我们的方案就显而易见了,就是将 Skywalking Nginx Lua 集成进 Ingress Nginx中,并编写插件,在不同阶段执行相关操作:
步骤

1. 集成Skywalking Nginx Lua进Ingress Nginx

Skywalking Nginx Lua 的焦点是它的 lib 目次,里边包含了所有需要用到的函数操作,所以我们需要将该 lib 目次的内容放到 Ingress Nginx 的Pod 中,让我们编写的插件可以或许调用到它。具体我们可以将 lib 目次放到网盘中,然后通过 Volume 的形式挂载进去,也可以将 lib 的内容写入configmap,然后挂载Volume到Pod中。本文选择第二种方式,将 lib 的内容放到 configmap 中,然后挂载进去,虽说这种方式不敷优雅,但幸亏不用依靠网盘。
我们先clone Skywalking Nginx Lua 这个库,然后将 lib 下的所有.lua文件打平放到同一个目次中
  1. git clone https://github.com/apache/skywalking-nginx-lua.git
  2. mkdir sk-lua-cm
  3. cp skywalking-nginx-lua/lib/skywalking/*.lua sk-lua-cm/
  4. cp skywalking-nginx-lua/lib/skywalking/dependencies/*.lua sk-lua-cm/
  5. cp skywalking-nginx-lua/lib/resty/*.lua sk-lua-cm/
复制代码
再通过 kubectl 命令将sk-lua-cm中的所有文件创建到一个configmap中,留意将 -n 后边的参数换成你本身Ingress Nginx 地点的 namespace。
  1. kubectl create cm skywalking-nginx-lua-agent --from-file=./sk-lua-cm/ -n ingress-nginx
复制代码
2. 编写Ingress Nginx 的插件

引入了 Skywalking 的 lib 后就可以编写对应的 Ingress Nginx 自定义插件了,代码比较简单,以下是代码详情(命名为main.lua)。
  1. local _M = {}
  2. function _M.init_worker()
  3.   local metadata_buffer = ngx.shared.tracing_buffer
  4.   require("skywalking.util").set_randomseed()
  5.   local serviceName = os.getenv("SKY_SERVICE_NAME")
  6.   if not serviceName then
  7.     serviceName="ingress-nginx"
  8.   end
  9.   metadata_buffer:set('serviceName', serviceName)
  10.   local serviceInstanceName = os.getenv("SKY_INSTANCE_NAME")
  11.   if not serviceInstanceName then
  12.     serviceName="ingress-nginx"
  13.   end
  14.   metadata_buffer:set('serviceInstanceName', serviceName)
  15.   metadata_buffer:set('includeHostInEntrySpan', false)
  16.   require("skywalking.client"):startBackendTimer(os.getenv("SKY_OAP_ADDR"))
  17.   skywalking_tracer = require("skywalking.tracer")
  18. end
  19. function _M.rewrite()
  20.   local upstreamName = ngx.var.proxy_upstream_name
  21.   skywalking_tracer:start(upstreamName)
  22.   if ngx.var.http_sw8 ~= "" then
  23.     local sw8Str = ngx.var.http_sw8
  24.     local sw8Item = require('skywalking.util').split(sw8Str, "-")
  25.     if #sw8Item >= 2 then
  26.       ngx.req.set_header("trace_id", ngx.decode_base64(sw8Item[2]))
  27.     end
  28.   end
  29. end
  30. function _M.body_filter()
  31.   if ngx.arg[2] then
  32.     skywalking_tracer:finish()
  33.   end
  34. end
  35. function _M.log()
  36.   skywalking_tracer:prepareForReport()
  37. end
  38. return _M
复制代码
划重点:在上述代码中获取了几个环境变量,需要记住,后边需要用到。
编写好插件代码后就可以基于此创建configmap了,依然需要留意 -n 后边的namespace,需要改成你实际Ingress Nginx地点的 namespace。
  1. kubectl create cm skywalking-lua-plug --from-file=main.lua -n ingress-nginx
复制代码
3. 挂载相关 Lua 脚本进 Ingress Nginx Controller 的 Pod 中

修改 Ingress Nginx Controller 的 Deployment 配置,主要修改以下几点:
a. 环境变量
  1. - name: SKY_OAP_ADDR
  2.   value: http://skywalking-oap.skywalking.svc.cluster.local:12800
  3. - name: SKY_SERVICE_NAME
  4.   value: ingress-nginx
  5. - name: SKY_INSTANCE_NAME
  6.   value: ingress-nginx
复制代码
b. volumes 声明
  1. - name: sky-nginx-plugin
  2.   configMap:
  3.     name: skywalking-lua-plug
  4. - name: skywalking-nginx-lua-agent
  5.   configMap:
  6.     name: skywalking-nginx-lua-agent
复制代码
c. volumeMounts 声明
  1. - mountPath: /etc/nginx/lua/plugins/skywalking/main.lua
  2.   subPath: "main.lua"
  3.   name: sky-nginx-plugin
  4. - mountPath: /etc/nginx/lua/resty/http.lua
  5.   subPath: "http.lua"
  6.   name: skywalking-nginx-lua-agent
  7. - mountPath: /etc/nginx/lua/tablepool.lua
  8.   subPath: "tablepool.lua"
  9.   name: skywalking-nginx-lua-agent
  10. - mountPath: /etc/nginx/lua/resty/http_headers.lua
  11.   subPath: "http_headers.lua"
  12.   name: skywalking-nginx-lua-agent
  13. - mountPath: /etc/nginx/lua/resty/jit-uuid.lua
  14.   subPath: "jit-uuid.lua"
  15.   name: skywalking-nginx-lua-agent
  16. - mountPath: /etc/nginx/lua/skywalking/client.lua
  17.   subPath: "client.lua"
  18.   name: skywalking-nginx-lua-agent
  19. - mountPath: /etc/nginx/lua/skywalking/constants.lua
  20.   subPath: "constants.lua"
  21.   name: skywalking-nginx-lua-agent
  22. - mountPath: /etc/nginx/lua/skywalking/correlation_context.lua
  23.   subPath: "correlation_context.lua"
  24.   name: skywalking-nginx-lua-agent
  25. - mountPath: /etc/nginx/lua/skywalking/dependencies/base64.lua
  26.   subPath: "base64.lua"
  27.   name: skywalking-nginx-lua-agent
  28. - mountPath: /etc/nginx/lua/skywalking/management.lua
  29.   subPath: "management.lua"
  30.   name: skywalking-nginx-lua-agent
  31. - mountPath: /etc/nginx/lua/skywalking/segment.lua
  32.   subPath: "segment.lua"
  33.   name: skywalking-nginx-lua-agent
  34. - mountPath: /etc/nginx/lua/skywalking/segment_ref.lua
  35.   subPath: "segment_ref.lua"
  36.   name: skywalking-nginx-lua-agent
  37. - mountPath: /etc/nginx/lua/skywalking/span.lua
  38.   subPath: "span.lua"
  39.   name: skywalking-nginx-lua-agent
  40. - mountPath: /etc/nginx/lua/skywalking/span_layer.lua
  41.   subPath: "span_layer.lua"
  42.   name: skywalking-nginx-lua-agent
  43. - mountPath: /etc/nginx/lua/skywalking/tracer.lua
  44.   subPath: "tracer.lua"
  45.   name: skywalking-nginx-lua-agent
  46. - mountPath: /etc/nginx/lua/skywalking/tracing_context.lua
  47.   subPath: "tracing_context.lua"
  48.   name: skywalking-nginx-lua-agent
  49. - mountPath: /etc/nginx/lua/skywalking/util.lua
  50.   subPath: "util.lua"
  51.   name: skywalking-nginx-lua-agent
复制代码
4. 修改 Ingress Nginx Controller 所使用的configmap配置
  1. plugins: "skywalking"
  2. lua-shared-dicts: "tracing_buffer: 100m"
  3. main-snippet: |
  4.   env SKY_SERVICE_NAME;
  5.   env SKY_INSTANCE_NAME;
  6.   env SKY_OAP_ADDR;
  7. log-format-upstream: |
  8.   $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] [$proxy_alternative_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $request_id $http_trace_id
复制代码
该配置中配置了如下几个信息:
5. 重启 Pod 生效

把下列的 xxx 换成 Ingress Nginx Controller 的 Pod 名称
  1. kubectl delete pod xxxx -n=ingress-nginx
复制代码
效果展示

本节展示终极在Skywalking UI 上的展示效果。



如何更好使用Trace?

通过上述介绍,我们已经把 Ingress Nginx 集成进了Skywalking,接下来介绍一下如何更好的使用Trace数据来快速定位故障。
数据建设




串联买通

通过Flashcat的串联能力,建立北极星和灭火图的串联。

故障定位路径

当建设好对应的指标和关联后,就可以开启我们的故障定位之旅了。






通过Trace链路可以看到Redis的端口不通导致更新失败了,这个时候我们就需要去排查依靠的Redis是否正常了。
当然,以上只是Flashcat在整合可观测性三大支柱(Metrics、Log、Trace)方面的一个小例子,如果您对Flashcat这套产品感兴趣,可以随时与我们交换:https://flashcat.cloud/contact/

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4