前言
Kubernetes Ingress: https://github.com/kubernetes/ingress-nginx
Skywalking: https://github.com/apache/skywalking
Skywalking Lua Agent: https://github.com/apache/skywalking-nginx-lua
可使用Skywalking Nginx Lua 或 Skywalking Zipkin Receiver接收数据并分析。Kubernetes Ingress原生提供了ZipKin数据收集能力,但Zipkin Receiver被标示为实验性,推荐使用使用Skywalking Nginx Lua。
设计
在Kubernetes Ingress Nginx的目标版本镜像基础上直接做增强。
在源代码基础上做增强是做合适的, 但集团开发者中心附带的Kubernetes Ingress Nginx版本老旧,且在可见的未来也不会跟上社区的脚步。全新构建旧版本镜像容易出现不可预见的问题,且构建环境无法保证,遂在已有的Kubernetes Ingress Nginx镜像的基础上做扩展最为现实。
- 确保 Kubernetes Ingress Nginx 具备所需的Lua运行环境以及依赖,在某些旧版本Ingress中是无法完成支持的,需要重新编译Nginx。
- Skywalking Nginx Lua的脚本进行修改,解决Kubernetes Ingress冲突。(文件名冲突,因搜索路径无法调用有效的方法)
- Skywalking Nginx Lua脚本导入Kubernetes Ingress之中。
- 增强Kubernetes Ingress Nginx
nginx.tmpl
模板,启用Skywalking Agent。
操作
此操作仅为基本思路,以及操作演示。
此操作仅为基本思路,以及操作演示。
此操作仅为基本思路,以及操作演示。
定制Nginx
构建可参考:https://github.com/kubernetes/ingress-nginx/tree/master/images/nginx
在其基础上进行定制即可。
定制Skywalking Nginx Lua
以0.1.0版本为例
因Lua的模块寻找方式,Skywalking Lua Agent的util.lua
文件会与Kubernetes Ingress的util.lua
产生冲突,需要修改Skywalking Lua Agent的源码来解决冲突。
操作步骤如下:
- 将
util.lua
改名为sutil.lua
- 修改相关调用为
sutil.lua
。具体为修改local Util = require('sutil')
修改为local Util = require('sutil')
(0.1.0版本涵盖文件如下:segment_ref.lua
、span.lua
、tracing_context.lua
)
添加Skywalking Nginx Lua脚本
使用Dockerfile构建新镜像时,将脚本ADD或COPY进镜像之中即可
增强nginx.tmpl模板
https://github.com/apache/skywalking-nginx-lua
主要以下步骤:
- 添加Skywalking Lua脚本扫描路径
- 增加环境变量读取,如:SW_SERVICE_NAME、SW_SERVICE_INSTANCE_NAME、SW_BACKEND_SERVERS
- 添加Tracing使用的缓存
tracing_buffer
- 设置Skywalking Lua Agent的初始化方法,并将相关配置从环境变量中提取。
- 设置http节点的追踪配置。
# Skywalking ENV
env SW_SERVICE_NAME;
env SW_SERVICE_INSTANCE_NAME;
env SW_BACKEND_SERVERS;http {lua_package_path "/Path/to/.../skywalking-nginx-lua/lib/skywalking/?.lua;;";# Buffer represents the register inform and the queue of the finished segmentlua_shared_dict tracing_buffer 100m;# Init is the timer setter and keeper# Setup an infinite loop timer to do register and trace report.init_worker_by_lua_block {local metadata_buffer = ngx.shared.tracing_buffer-- Set service namemetadata_buffer:set('serviceName', os.getenv("SW_SERVICE_NAME"))-- Instance means the number of Nginx deployment, does not mean the worker instancesmetadata_buffer:set('serviceInstanceName', os.getenv("SW_SERVICE_INSTANCE_NAME"))require("client"):startBackendTimer(os.getenv("SW_BACKEND_SERVERS"))}server {listen 8080;location /ingress {default_type text/html;rewrite_by_lua_block {-------------------------------------------------------- NOTICE, this should be changed manually-- This variable represents the upstream logic address-- Please set them as service logic name or DNS name---- Currently, we can not have the upstream real network address------------------------------------------------------require("tracer"):start("{{ buildUpstreamName $server.Hostname $all.Backends $location }}")-- If you want correlation custom data to the downstream service-- require("tracer"):start("upstream service", {custom = "custom_value"})}-- Target upstream serviceproxy_pass http://127.0.0.1:8080/backend;body_filter_by_lua_block {if ngx.arg[2] thenrequire("tracer"):finish()end}log_by_lua_block {require("tracer"):prepareForReport()}}}
}
部署配置
修改Kubernetes Ingress的部署配置,将SW_SERVICE_NAME、SW_SERVICE_INSTANCE_NAME、SW_BACKEND_SERVERS环境变量配置其中即可。
SW_SERVICE_NAME
:服务名称
SW_SERVICE_INSTANCE_NAME
:实例名称,可以取自ID
SW_BACKEND_SERVERS
:后端服务地址,使用http端口。如:http://10.0.27.122:12800
- name: SW_SERVICE_NAMEvalue: Kubernetes Ingress
- name: SW_BACKEND_SERVERSvalue: skywalking-aop.skywalking:12800
- name: SW_SERVICE_INSTANCE_NAMEvalueFrom:fieldRef:fieldPath: metadata.uid