使用SkyWalking监控Nginx链路信息
1、前言
本篇只记录如何安装及配置Nginx LUA Agent展开,详细的记录了nginx lua模块的安装过程及如配置Nginx LUA Agent,并全程使用docker+k8s进行部署,SkyWalking的服务端也采用k8s部署,数据存储使用7.10的es完成,ES连接方式为HTTPS,具体踩坑过程后续进行记录;
2、SkyWalking简介与架构
官方手册:SkyWalking Overview
- SkyWalking:一个开放源代码的可观察性平台,用于收集,分析,聚合和可视化来自服务和云本机基础结构的数据。SkyWalking提供了一种简便的方法来维护您的分布式系统的清晰视图,即使在整个云中也是如此。它是一个现代的APM,专门为基于云的基于容器的分布式系统而设计,如下图:
从逻辑上讲,SkyWalking分为四个部分:探针,服务后端,存储和UI,如下图:
- 探针:收集数据并重新格式化以符合SkyWalking的要求(不同的探针支持不同的来源);
- 服务后端:支持数据聚合,分析和流处理,涵盖跟踪,指标和日志;
- 存储:支持ElasticSearch,H2,MySQL,TiDB,InfluxDB存储SkyWalking数据
- UI:是一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。
3、为什么要使用SkyWalking?
- SkyWalking提供了用于在许多不同情况下观察和监视分布式系统的解决方案。首先,与传统方法一样,SkyWalking为服务提供自动仪器代理,例如Java,C#,Node.js,Go,PHP和Nginx LUA。在多语言,持续部署的环境中,云本机基础架构变得越来越强大,但也越来越复杂。SkyWalking的服务网格接收器使SkyWalking能够从Istio / Envoy和Linkerd等服务网格框架接收遥测数据,从而使用户能够了解整个分布式系统,
- SkyWalking使用服务名称,服务实例,端点提供可观察性功能,详细含义如下:
- 服务名称:表示一组工作负载,SkyWalking也可以使用您在Istio等平台中定义的名称;
- 服务实例:服务组中的每个单独工作负载都称为实例,像pods在Kubernetes中的定义一样;
- 端点:服务中用于传入请求的路径,例如HTTP URI路径或gRPC服务类+方法签名;
4、部署环境介绍
平台 | IP | NGINX版本 | Agent版本 | SkyWalking版本 | |
---|---|---|---|---|---|
CentOS Linux release 7.7.1908 | 192.168.6.10 | 1.12.1 | skywalking-nginx-lua-0.3.0 | 8.1.0 |
5、编译NGINX
5.1、安装luajit编译器
1 | #下载luajit编译器 |
5.2、增加环境变量
1 | #增加LUAJIT环境变量 |
5.3、安装nginx lua模块
1 | wget https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz -O ngx_devel_kit-0.3.0.tar.gz |
5.4、Bulid Nginx
1 | #nginx编译参数如下(这里包含了其他模块,具体各个模块的安装这里不记录): |
5.5、Test Nginx Lua
1 | #在nginx.conf,server段中增加如下配置 |
5.5、下载skywalking lua脚本
1 | wget https://github.com/apache/skywalking-nginx-lua/archive/v0.3.0.tar.gz |
5.6、修改nginx.conf配置文件
提示:配置项(lua_package_path、metadata_buffer:set、startBackendTimer)要根据实际部署情况进行调整;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 #user www;
worker_processes 2;
error_log /usr/local/nginx/logs/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /usr/local/nginx/conf/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /usr/local/nginx/logs/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /usr/local/nginx/conf/conf.d/*.conf;
############################################################################################
#LUA脚本存放路径
lua_package_path "/usr/local/skywalking-nginx-lua-0.3.0/lib/?.lua;;";
lua_shared_dict tracing_buffer 100m;
init_worker_by_lua_block {
local metadata_buffer = ngx.shared.tracing_buffer
#服务名称
metadata_buffer:set('serviceName', 'szzt_nginx112')
#实例名称
metadata_buffer:set('serviceInstanceName', 'centos2009-858f6fcf97-m69tp')
#skywalking后端地址
require("skywalking.client"):startBackendTimer("http://10.244.1.19:12800")
}
server {
listen 60000;
#lua_code_cache off;
location /ingress {
default_type text/html;
rewrite_by_lua_block {
require("skywalking.tracer"):start("upstream service")
}
proxy_pass http://127.0.0.1:60000/tier2/lb;
body_filter_by_lua_block {
if ngx.arg[2] then
require("skywalking.tracer"):finish()
end
}
log_by_lua_block {
require("skywalking.tracer"):prepareForReport()
}
}
location /tier2/lb {
default_type text/html;
rewrite_by_lua_block {
require("skywalking.tracer"):start("backend service")
}
proxy_pass http://127.0.0.1:60000/backend;
body_filter_by_lua_block {
if ngx.arg[2] then
require("skywalking.tracer"):finish()
end
}
log_by_lua_block {
require("skywalking.tracer"):prepareForReport()
}
}
# ------------------------------------------------------
# -- Mock backend business service as the upsteeam
# ------------------------------------------------------
location /backend {
default_type text/html;
content_by_lua_block {
ngx.say("<p>Backend service for testing only.</p>")
ngx.say("<p>Backend sw8 received headers: " .. ngx.req.get_headers()["sw8"] .. "</p>")
}
}
# ------------------------------------------------------
# -- Mock OAP server to provide register and trace collection
# ------------------------------------------------------
location /v3/management/reportProperties {
default_type text/html;
lua_need_request_body on;
content_by_lua_block {
local cjson = require('cjson')
ngx.log(ngx.DEBUG, 'Instance report request = ', ngx.req.get_body_data())
local reportInfo = {}
ngx.say(cjson.encode(reportInfo))
}
}
location /v3/management/keepAlive {
default_type text/html;
lua_need_request_body on;
content_by_lua_block {
local cjson = require('cjson')
ngx.log(ngx.DEBUG, 'KeepAlive request = ', ngx.req.get_body_data())
local keepAliveInfo = {}
ngx.say(cjson.encode(keepAliveInfo))
}
}
location /v3/segments {
default_type text/html;
lua_need_request_body on;
content_by_lua_block {
local cjson = require('cjson')
ngx.log(ngx.DEBUG, 'Received segment = ', ngx.req.get_body_data())
}
}
}
}
5.7、重载配置文件
1 | #重载nginx |
5.8、进行简单压测
1 | ab -c 100 -n 1000 http://127.0.0.1:60000/ingress |
5.7、登录skywalking UI进行查看
提示:实例名可看做是一个容器,一台服务器,一个OS进程,但必须唯一,用于区分和标识,具体UI使用详解,请阅读官方手册:Visualization
6、使用K8S部署NGINX
提示:使用k8s部署基于skywalking的nginx,存在如下几个关键点,1、必须保证服务实例唯一,服务名称根据项目来定 2、skywalking的地址使用coredns的域名出现无法识别,必须填写clusterIP 3、nginx.conf配置文件是不支持容器变量传递,则放弃使用configmap进行存储和挂载,使用envsubst实现
6.1、准备构建Docker镜像的所需资源文件
1 | [root@centos2009-858f6fcf97-m69tp nginx112]# ll |
6.2、构建基于skywalking的nginx生产镜像
1 | #构建过程直接-t打上标签 |
6.3、部署一个nginx容器进行测试
1 | #用制作好的镜像,create的一个容器 |
6.4、使用k8s部署
提示:k8s配置文件篇幅过长这里不展示,按照如下指令操作,可完成PVC存储、configmap配置中心、集群暴露端口svc及pod相关等资源的创建;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #按照文件数据顺序,依次使用Kubectl apply -f xxx.yml,即可完成nginx集群部署,重点对6号文件进行调整,里面需增加SVC_NAME、SW_ADDR的ENV,用于配置文件变量替换
[root@DEVOPSSRV01 nginx_deployment]# ll
total 28
-rw-r--r-- 1 root root 292 Jan 7 14:44 1.nginx_pv.yml
-rw-r--r-- 1 root root 217 Jan 7 14:44 2.nginx_pvc_web1.yml
-rw-r--r-- 1 root root 4653 Mar 2 11:04 3.nginx-config.yml
-rw-r--r-- 1 root root 519 Mar 2 11:04 4.www-config.yml
-rw-r--r-- 1 root root 354 Mar 2 11:39 5.nginx_svc.yml
-rw-r--r-- 1 root root 1386 Mar 2 11:13 6.nginx_deployment_v3.yml
#使用命令查看创建后的资源运行状态
[root@DEVOPSSRV01 nginx_deployment]# kubectl get pod,svc -n nginx-production -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/nginx112-59fcbcbccc-5d7ms 1/1 Running 0 5h32m 10.244.1.24 tssrv02.novalocal <none> <none>
pod/nginx112-59fcbcbccc-mfglm 1/1 Running 0 5h32m 10.244.2.195 dbsrv01.novalocal <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/nginx-svc NodePort 10.98.3.73 <none> 60000:30002/TCP,80:30006/TCP 5h36m app=web_server
6.5、登录k8s dashboard查看资源情况
- pods资源
- configmaps资源
6.6、登录skywalking UI查看资源情况
- 可用简单的压测命令进行测试后,在登录查看,在k8s上创建了几个POD,这里应当看到对应的几个实例