链路监控 Skywalking
链路监控的软件很多,比如 skywalking、pinpoint、zipkin 等。其中
- Zipkin (opens new window):由 Twitter 公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现。
- Pinpoint (opens new window):一款对 Java 编写的大规模分布式系统的 APM 工具,由韩国人开源的分布式跟踪组件。
- Skywalking (opens new window):国产的优秀 APM 组件,是一个对 JAVA 分布式应用程序集群的业务运行情况进行追踪、告警和分析的系统。
这里主要来介绍 Skywalking 及其安装。
SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案.支持 Java, .Net Core, PHP, NodeJS, Golang, LUA 语言探针,支持 Envoy + Istio 构建的 Service Mesh。
# 安装服务端
这里是安装在 kubernetes 中,使用 helm 安装。
# 安装 helm
使用 helm3,安装如下:
wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
tar zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
2
3
说明:helm3 没有 tiller 这个服务端了,直接用 kubeconfig 进行验证通信,所以建议部署在 master 节点
# 安装 skywalking
skywalking 的安装比较简单,具体可以参照其官方文档 (opens new window)。
这里采用 es 做后端存储。
(1)、下载项目
git clone https://github.com/apache/skywalking-kubernetes.git
(2)、默认安装使用的是 es7 做后端存储,安装步骤如下:
cd chart
helm repo add elastic https://helm.elastic.co
helm dep up skywalking
helm install <release_name> skywalking -n <namespace>
2
3
4
如果要使用 es6 做后端存储,则按照下面的步骤:
helm dep up skywalking
helm install <release_name> skywalking -n <namespace> --values ./skywalking/values-es6.yaml
2
3
如果本身有 ES,如果是 ES7,则用下面的命令安装:
cd chart
helm repo add elastic https://helm.elastic.co
helm dep up skywalking
helm install skywalking skywalking -n skywalking \
--set elasticsearch.enabled=false \
--set elasticsearch.config.host=elasticsearch-client.elastic.svc.default.local \
--set elasticsearch.config.port.http=9200 \
--set elasticsearch.config.user=elastic \
--set elasticsearch.config.password=elastic@123456
2
3
4
5
6
7
8
9
10
11
12
如果是 es6,则用下面的命令:
helm dep up skywalking
helm install <release_name> skywalking -n <namespace> \
--values ./skywalking/values-es6.yaml \
--set elasticsearch.enabled=false \
--set elasticsearch.config.host=<es_host> \
--set elasticsearch.config.port.http=<es_port> \
--set elasticsearch.config.user=<es_user> \
--set elasticsearch.config.password=<es_password>
2
3
4
5
6
7
8
9
然后观察所以 pod 是否处于 running 状态:
# kubectl get pod
NAME READY STATUS RESTARTS AGE
elasticsearch-master-0 1/1 Running 0 16h
elasticsearch-master-1 1/1 Running 0 16h
elasticsearch-master-2 1/1 Running 0 16h
nfs-client-provisioner-f85644675-ftq2v 1/1 Running 7 80d
skywalking-es-init-7968s 0/1 Completed 0 16h
skywalking-es-init-x89pr 0/1 Completed 0 15h
skywalking-oap-694fc79d55-2dmgr 1/1 Running 0 16h
skywalking-oap-694fc79d55-bl5hk 1/1 Running 4 16h
skywalking-ui-6bccffddbd-d2xhs 1/1 Running 0 16h
2
3
4
5
6
7
8
9
10
11
查看其所有的 svc:
# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch-master ClusterIP 10.108.144.131 <none> 9200/TCP,9300/TCP 16h
elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 16h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 83d
skywalking-oap ClusterIP 10.109.142.213 <none> 12800/TCP,11800/TCP 16h
skywalking-ui NodePort 10.109.0.122 <none> 80:30969/TCP 16h
2
3
4
5
6
7
8
将 skywalking-ui 的 svc type 改为 nodeport,然后通过浏览器访问出现如下界面。
到此服务端安装完成了,注意默认安装 es 并没有持久化处理,如果 es 重建会导致数据丢失。
# 安装客户端
这里以接入 java 项目为例。
由于我们应用是部署在 kubernetes 中的,所以有两种方式将 agent 的加入到我们的应用中:
- 在项目的 Docker 镜像中加入 agent
- 以 sidecar 的形式给应用添加 agent
下载对应版本的软件包
wget https://mirrors.tuna.tsinghua.edu.cn/apache/skywalking/8.1.0/apache-skywalking-apm-8.1.0.tar.gz
tar xf apache-skywalking-apm-8.1.0.tar.gz
2
# 在项目的 Docker 镜像中加入 agent
PS:如果每个应用都放一次就太麻烦,简单点的就是放到基础镜像中去。
如下:
FROM harbor-test.coolops.com/coolops/jdk:8u144_test
RUN mkdir -p /usr/skywalking/agent/
ADD apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/
2
3
# 以 sidecar 的形式给应用添加 agent
构建 sidecar 的 Dockerfile
FROM busybox:latest
ENV LANG=C.UTF-8
RUN set -eux && mkdir -p /usr/skywalking/agent/
ADD apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/
WORKDIR /
2
3
4
5
6
7
8
9
然后在使用的时候如下使用:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
name: demo-sw
name: demo-sw
spec:
replicas: 1
selector:
matchLabels:
name: demo-sw
template:
metadata:
labels:
name: demo-sw
spec:
initContainers:
- image: innerpeacez/sw-agent-sidecar:latest
name: sw-agent-sidecar
imagePullPolicy: IfNotPresent
command: ["sh"]
args:
[
"-c",
"mkdir -p /skywalking/agent && cp -r /usr/skywalking/agent/* /skywalking/agent",
]
volumeMounts:
- mountPath: /skywalking/agent
name: sw-agent
containers:
- image: nginx:1.7.9
name: nginx
volumeMounts:
- mountPath: /usr/skywalking/agent
name: sw-agent
ports:
- containerPort: 80
volumes:
- name: sw-agent
emptyDir: {}
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
上面这个 YAML 文件只是作为参考例子,思路是如此而已。
在真正的 java 应用中,我们应该如何启用 agent 呢?
其实很简单。
(1)、如果是部署在 tomcat 中,修改<font style="color:#24292E;background-color:rgba(27, 31, 35, 0.05);">catalina.sh</font>
即可,如下:
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS
(2)、如果是 jar 文件启动,则如下:
java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -Dskywalking.agent.service_name=${SW_AGENT_NAME} -jar yourApp.jar
注意这里有两个环境变量:
- SW_AGENT_COLLECTOR_BACKEND_SERVICES:后端服务的地址
- SW_AGENT_NAME:在 UI 上显示的应用名
所以完整的 demo 如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: <APP_NAME>
name: <APP_NAME>
namespace: <NEMESPACE>
spec:
minReadySeconds: 60
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: <APP_NAME>
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
labels:
app: <APP_NAME>
spec:
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- preference: {}
weight: 100
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: category
operator: In
values:
- other
containers:
- args:
- -jar /opt/<JAR_NAME>.jar
- -javaagent:/usr/skywalking/agent/skywalking-agent.jar
command:
- java
env:
- name: JAVA_HEAP_SIZE
value: 2g
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
value: skywalking-oap.default:11800
- name: SW_AGENT_NAME
value: <APP_NAME>
image: <IMAGE>:<IMAGE_TAG>
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
httpGet:
path: healthCheck
port: tcp-<PORT>
scheme: HTTP
initialDelaySeconds: 60
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: healthCheck
port: tcp-<PORT>
scheme: HTTP
initialDelaySeconds: 55
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: <APP_NAME>
ports:
- containerPort: <PORT>
name: tcp-<PORT>
protocol: TCP
resources:
limits:
cpu: "4"
memory: 3Gi
requests:
cpu: 500m
memory: 2Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: image_pull
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 120
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
参考文档:
1、https://github.com/apache/skywalking-kubernetes (opens new window)
2、http://skywalking.apache.org/zh/blog/2019-08-30-how-to-use-Skywalking-Agent.html (opens new window)