链路监控的软件很多,比如skywalking、pinpoint、zipkin等。其中

  • Zipkin:由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现。
  • Pinpoint:一款对Java编写的大规模分布式系统的APM工具,由韩国人开源的分布式跟踪组件。
  • Skywalking:国产的优秀APM组件,是一个对JAVA分布式应用程序集群的业务运行情况进行追踪、告警和分析的系统。

这里主要来介绍Skywalking及其安装。
SkyWalking 是观察性分析平台和应用性能管理系统。提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案.支持Java, .Net Core, PHP, NodeJS, Golang, LUA语言探针,支持Envoy + Istio构建的Service Mesh。

安装服务端

这里是安装在kubernetes中,使用helm安装。

安装helm

使用helm3,安装如下:

  1. wget https://get.helm.sh/helm-v3.0.0-linux-amd64.tar.gz
  2. tar zxvf helm-v3.0.0-linux-amd64.tar.gz
  3. mv linux-amd64/helm /usr/bin/

说明:helm3没有tiller这个服务端了,直接用kubeconfig进行验证通信,所以建议部署在master节点

安装skywalking

skywalking的安装比较简单,具体可以参照其官方文档
这里采用es做后端存储。

(1)、下载项目

  1. git clone https://github.com/apache/skywalking-kubernetes.git

(2)、默认安装使用的是es7做后端存储,安装步骤如下:

  1. $ cd chart
  2. $ helm repo add elastic https://helm.elastic.co
  3. $ helm dep up skywalking
  4. $ helm install <release_name> skywalking -n <namespace>

如果要使用es6做后端存储,则按照下面的步骤:

  1. $ helm dep up skywalking
  2. $ helm install <release_name> skywalking -n <namespace> --values ./skywalking/values-es6.yaml

如果本身有ES,如果是ES7,则用下面的命令安装:

  1. $ cd chart
  2. $ helm repo add elastic https://helm.elastic.co
  3. $ helm dep up skywalking
  4. $ helm install skywalking skywalking -n skywalking \
  5. --set elasticsearch.enabled=false \
  6. --set elasticsearch.config.host=elasticsearch-client.elastic.svc.default.local \
  7. --set elasticsearch.config.port.http=9200 \
  8. --set elasticsearch.config.user=elastic \
  9. --set elasticsearch.config.password=elastic@123456

如果是es6,则用下面的命令:

  1. $ helm dep up skywalking
  2. $ helm install <release_name> skywalking -n <namespace> \
  3. --values ./skywalking/values-es6.yaml \
  4. --set elasticsearch.enabled=false \
  5. --set elasticsearch.config.host=<es_host> \
  6. --set elasticsearch.config.port.http=<es_port> \
  7. --set elasticsearch.config.user=<es_user> \
  8. --set elasticsearch.config.password=<es_password>

然后观察所以pod是否处于running状态:

  1. # kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. elasticsearch-master-0 1/1 Running 0 16h
  4. elasticsearch-master-1 1/1 Running 0 16h
  5. elasticsearch-master-2 1/1 Running 0 16h
  6. nfs-client-provisioner-f85644675-ftq2v 1/1 Running 7 80d
  7. skywalking-es-init-7968s 0/1 Completed 0 16h
  8. skywalking-es-init-x89pr 0/1 Completed 0 15h
  9. skywalking-oap-694fc79d55-2dmgr 1/1 Running 0 16h
  10. skywalking-oap-694fc79d55-bl5hk 1/1 Running 4 16h
  11. skywalking-ui-6bccffddbd-d2xhs 1/1 Running 0 16h

查看其所有的svc:

  1. # kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. elasticsearch-master ClusterIP 10.108.144.131 <none> 9200/TCP,9300/TCP 16h
  4. elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 16h
  5. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 83d
  6. skywalking-oap ClusterIP 10.109.142.213 <none> 12800/TCP,11800/TCP 16h
  7. skywalking-ui NodePort 10.109.0.122 <none> 80:30969/TCP 16h

将skywalking-ui的svc type改为nodeport,然后通过浏览器访问出现如下界面。
image.png
到此服务端安装完成了,注意默认安装es并没有持久化处理,如果es重建会导致数据丢失。

安装客户端

这里以接入java项目为例。
由于我们应用是部署在kubernetes中的,所以有两种方式将agent的加入到我们的应用中:

  • 在项目的Docker镜像中加入agent
  • 以sidecar的形式给应用添加agent

下载对应版本的软件包

  1. wget https://mirrors.tuna.tsinghua.edu.cn/apache/skywalking/8.1.0/apache-skywalking-apm-8.1.0.tar.gz
  2. tar xf apache-skywalking-apm-8.1.0.tar.gz

在项目的Docker镜像中加入agent

PS:如果每个应用都放一次就太麻烦,简单点的就是放到基础镜像中去。

如下:

  1. FROM harbor-test.coolops.com/coolops/jdk:8u144_test
  2. RUN mkdir -p /usr/skywalking/agent/
  3. ADD apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/

以sidecar的形式给应用添加agent

构建sidecar的Dockerfile

  1. FROM busybox:latest
  2. ENV LANG=C.UTF-8
  3. RUN set -eux && mkdir -p /usr/skywalking/agent/
  4. ADD apache-skywalking-apm-bin/agent/ /usr/skywalking/agent/
  5. WORKDIR /

然后在使用的时候如下使用:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. name: demo-sw
  6. name: demo-sw
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. name: demo-sw
  12. template:
  13. metadata:
  14. labels:
  15. name: demo-sw
  16. spec:
  17. initContainers:
  18. - image: innerpeacez/sw-agent-sidecar:latest
  19. name: sw-agent-sidecar
  20. imagePullPolicy: IfNotPresent
  21. command: ['sh']
  22. args: ['-c','mkdir -p /skywalking/agent && cp -r /usr/skywalking/agent/* /skywalking/agent']
  23. volumeMounts:
  24. - mountPath: /skywalking/agent
  25. name: sw-agent
  26. containers:
  27. - image: nginx:1.7.9
  28. name: nginx
  29. volumeMounts:
  30. - mountPath: /usr/skywalking/agent
  31. name: sw-agent
  32. ports:
  33. - containerPort: 80
  34. volumes:
  35. - name: sw-agent
  36. emptyDir: {}

上面这个YAML文件只是作为参考例子,思路是如此而已。

在真正的java应用中,我们应该如何启用agent呢?
其实很简单。
(1)、如果是部署在tomcat中,修改catalina.sh即可,如下:

  1. CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS

(2)、如果是jar文件启动,则如下:

  1. 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如下:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: <APP_NAME>
  6. name: <APP_NAME>
  7. namespace: <NEMESPACE>
  8. spec:
  9. minReadySeconds: 60
  10. progressDeadlineSeconds: 600
  11. replicas: 1
  12. revisionHistoryLimit: 10
  13. selector:
  14. matchLabels:
  15. app: <APP_NAME>
  16. strategy:
  17. rollingUpdate:
  18. maxSurge: 25%
  19. maxUnavailable: 25%
  20. type: RollingUpdate
  21. template:
  22. metadata:
  23. labels:
  24. app: <APP_NAME>
  25. spec:
  26. affinity:
  27. nodeAffinity:
  28. preferredDuringSchedulingIgnoredDuringExecution:
  29. - preference: {}
  30. weight: 100
  31. requiredDuringSchedulingIgnoredDuringExecution:
  32. nodeSelectorTerms:
  33. - matchExpressions:
  34. - key: category
  35. operator: In
  36. values:
  37. - other
  38. containers:
  39. - args:
  40. - -jar /opt/<JAR_NAME>.jar
  41. - -javaagent:/usr/skywalking/agent/skywalking-agent.jar
  42. command:
  43. - java
  44. env:
  45. - name: JAVA_HEAP_SIZE
  46. value: 2g
  47. - name: POD_NAME
  48. valueFrom:
  49. fieldRef:
  50. apiVersion: v1
  51. fieldPath: metadata.name
  52. - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
  53. value: skywalking-oap.default:11800
  54. - name: SW_AGENT_NAME
  55. value: <APP_NAME>
  56. image: <IMAGE>:<IMAGE_TAG>
  57. imagePullPolicy: Always
  58. livenessProbe:
  59. failureThreshold: 3
  60. httpGet:
  61. path: healthCheck
  62. port: tcp-<PORT>
  63. scheme: HTTP
  64. initialDelaySeconds: 60
  65. periodSeconds: 10
  66. successThreshold: 1
  67. timeoutSeconds: 1
  68. readinessProbe:
  69. failureThreshold: 3
  70. httpGet:
  71. path: healthCheck
  72. port: tcp-<PORT>
  73. scheme: HTTP
  74. initialDelaySeconds: 55
  75. periodSeconds: 10
  76. successThreshold: 1
  77. timeoutSeconds: 1
  78. name: <APP_NAME>
  79. ports:
  80. - containerPort: <PORT>
  81. name: tcp-<PORT>
  82. protocol: TCP
  83. resources:
  84. limits:
  85. cpu: '4'
  86. memory: 3Gi
  87. requests:
  88. cpu: 500m
  89. memory: 2Gi
  90. terminationMessagePath: /dev/termination-log
  91. terminationMessagePolicy: File
  92. dnsPolicy: ClusterFirst
  93. imagePullSecrets:
  94. - name: image_pull
  95. restartPolicy: Always
  96. schedulerName: default-scheduler
  97. securityContext: {}
  98. terminationGracePeriodSeconds: 120

参考文档:
1、https://github.com/apache/skywalking-kubernetes
2、http://skywalking.apache.org/zh/blog/2019-08-30-how-to-use-Skywalking-Agent.html
3、https://github.com/apache/skywalking/blob/5.x/docs/cn/Deploy-skywalking-agent-CN.md