概述
前面我给大家分享了关于分布式链路追踪的基本原理和 SkyWalking的k8s部署玩法,如果还没来得及看的朋友可以看我上俩篇文章。
今天要给大家分享是我们日常工作中最常见的一种场景,那就是部署在k8s环境下的Java微服务,要接入SkyWalking的具体玩法,通过这个过程咱们可以更深入的理解SkyWalking进行数据采集的逻辑,也能更深刻地从运维角度理解日常工作中所写的Java微服务被无侵入的方式接入分布式链路追踪系统的过程!
Java微服务接入SkyWalking的方式
SkyWalking
的数据采集主要是通过**业务探针(Agent)**来实现的,针对不同的编程语言 SkyWalking 提供了对应的 Agent 实现。Java微服务接入SkyWalking可以使用SkyWalking Java Agent
来上报监控数据。
这就需要Java微服务在部署启动的过程中需要获取 SkyWalking Java Agent
探针包,并在启动参数中通过 --javaagent:xxx
进行参数指定。而具体的集成方式大致有以下三种:
- 使用官方提供的基础镜像;
- 将agent包构建到已存在的基础镜像中;
- 通过 sidecar 模式挂载agent;
其中前两种方式主要是通过在构建Docker镜像
的过程中将Agent依赖打包集成到Java服务的Docker镜像中,而 sidecar 模式则是利用k8s的相关特性来实现在容器启动时挂载Agent相关依赖。
如果微服务是直接部署在Kubernetes集群,那么采用sidecar模式来使用SkyWalking Agent会更加方便,因为这种方式不需要修改原来的基础镜像,也不需要重新构建新的服务镜像,而是会以sidecar模式,通过共享的volume将agent所需的相关文件直接挂载到已经存在的服务镜像中。
构建SkyWalking-Agent镜像
在开始以sidecar方式,将一个用Spring Cloud框架编写的Java微服务接入SkyWalking之前,我们需要构建SkyWalking Java Agent
的公共镜像,具体步骤如下:
1 2 3 4 5 6
| FROM busybox:latest LABEL www.boysec.cn wangxiansen
ENV LANG=C.UTF-8
RUN wget -q https://dlcdn.apache.org/skywalking/java-agent/9.1.0/apache-skywalking-java-agent-9.1.0.tgz -O -|tar -xz -C /opt/
|
在上述Dockefile文件中使用是的bosybox镜像,而不是SkyWalking的发行镜像,这样可以确保构建出来的sidecar镜像保持最小。
完成Docker文件编写后,执行镜像构建命令
1 2 3 4 5
| #执行镜像构建命令 $ docker build . -t wangxiansen/skywalking-agent:sidecar-9.1.0 # 为了验证构建的镜像是否成功,可以通过命令查看本地构建的镜像 $ docker images|grep sidecar wangxiansen/skywalking-agent sidecar-9.1.0 f4b8b30bd947 4 hours ago 38.7MB
|
我已经将打包好的镜像推送至hub.docker.com
仓库中,如果需要可直接下载使用。
微服务接入SkyWalking服务
上面我们通过手工构建的方式构建了SkyWalking Java Agent的公共Docker镜像,并将其Push到了镜像仓库,接下来我们将演示如何通过编写Kubernetes服务发布文件,来将Java服务发布到K8s集群的过程中自动以SideCar的形式集成Agent、并接入SkyWalking服务。
本次演示还是使用的 Kubernetes之交付dubbo微服务 这篇文章内容,这里需要你安装java8+
和maven
环境。
编译dubbo-demo-service
1 2 3 4 5
| git clone https://gitee.com/dabou/dubbo-demo-service.git cd dubbo-demo-service mvn clean package -Dmaven.test.skip=true mkdir project_dir mv /dubbo-demo-service/dubbo-server/target/dubbo-server.jar dubbo-demo-service/project_dir
|
创建Dockefile
1 2 3
| cat Dockerfile FROM wangxiansen/base_jre8:8u112 ADD project_dir /opt/project_dir
|
编译dubbo-demo-web
1 2 3 4 5
| git clone https://gitee.com/dabou/dubbo-demo-web.git cd dubbo-demo-web mvn clean package -Dmaven.test.skip=true mkdir project_dir mv /dubbo-demo-web/dubbo-client/target/dubbo-client.jar dubbo-demo-web/project_dir
|
创建Dockefile
1 2 3
| cat Dockerfile FROM wangxiansen/base_jre8:8u112 ADD project_dir /opt/project_dir
|
微服务发布进行埋点
到这里你并没有发现为了将Java服务接入SkyWalking,你需要在Java微服务本身做任何动作,而接下来在k8s部署文件中的将演示,为什么要将这种方式称之为SideCar。
其主要原理是通过Kubernetes的初始化容器initContainers
来实现的,initContainers是一种专用容器,可以在应用容器启动之前运行,可以用于完成应用启动前的必要初始化工作。
编辑 dubbo-demo-service 资源配置清单
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
| kind: Deployment apiVersion: apps/v1 metadata: name: dubbo-demo-service namespace: app labels: name: dubbo-demo-service spec: replicas: 1 selector: matchLabels: name: dubbo-demo-service template: metadata: labels: app: dubbo-demo-service name: dubbo-demo-service spec: volumes: - name: sw-agent emptyDir: {} initContainers: - name: sw-agent-sidecar image: wangxiansen/skywalking-agent:sidecar-9.1.0 imagePullPolicy: IfNotPresent command: - sh - -c - >- mkdir -p /skywalking/agent; # 创建挂载目录 cp -r /opt/skywalking-agent/* /skywalking/agent # 复制skywalking-agent目录内容 volumeMounts: - name: sw-agent mountPath: "/skywalking/agent" containers: - name: dubbo-demo-service image: wangxiansen/dubbo-demo-consumer:test imagePullPolicy: IfNotPresent ports: - containerPort: 20880 protocol: TCP env: - name: JAR_BALL value: "-javaagent:/skywalking/agent/skywalking-agent.jar dubbo-server.jar" - name: ZK_ADDRES value: "zk.od.com:2181" - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES value: "oap-svc.skywalking:11800" - name: SW_AGENT_NAME value: "dubbo" resources: limits: cpu: 300m memory: 400Mi requests: cpu: 200m memory: 400Mi volumeMounts: - name: sw-agent mountPath: "/skywalking/agent" restartPolicy: Always terminationGracePeriodSeconds: 30 securityContext: runAsUser: 0 schedulerName: default-scheduler strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 revisionHistoryLimit: 7 progressDeadlineSeconds: 600
|
编辑 dubbo-demo-web 资源配置清单
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
| kind: Deployment apiVersion: apps/v1 metadata: name: dubbo-demo-consumer namespace: app labels: name: dubbo-demo-consumer spec: replicas: 1 selector: matchLabels: name: dubbo-demo-consumer template: metadata: labels: app: dubbo-demo-consumer name: dubbo-demo-consumer spec: volumes: - name: sw-agent emptyDir: {} initContainers: - name: sw-agent-sidecar image: wangxiansen/skywalking-agent:sidecar-9.1.0 imagePullPolicy: IfNotPresent command: - sh - -c - >- mkdir -p /skywalking/agent; cp -r /opt/skywalking-agent/* /skywalking/agent volumeMounts: - name: sw-agent mountPath: "/skywalking/agent" containers: - name: dubbo-demo-consumer image: wangxiansen/dubbo-demo-service:test imagePullPolicy: IfNotPresent ports: - containerPort: 8080 protocol: TCP - containerPort: 20880 protocol: TCP env: - name: JAR_BALL value: "-javaagent:/skywalking/agent/skywalking-agent.jar dubbo-client.jar" - name: ZK_ADDRES value: "zk.od.com:2181" - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES value: "oap-svc.skywalking:11800" - name: SW_AGENT_NAME value: "dubbo" resources: limits: cpu: 400m memory: 500Mi requests: cpu: 300m memory: 500Mi volumeMounts: - name: sw-agent mountPath: "/skywalking/agent" restartPolicy: Always terminationGracePeriodSeconds: 30 securityContext: runAsUser: 0 schedulerName: default-scheduler strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 maxSurge: 1 revisionHistoryLimit: 7 progressDeadlineSeconds: 600 --- kind: Service apiVersion: v1 metadata: name: dubbo-demo-consumer namespace: app spec: ports: - protocol: TCP port: 8080 targetPort: 8080 selector: app: dubbo-demo-consumer clusterIP: None type: ClusterIP sessionAffinity: None --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: dubbo-demo-consumer namespace: app spec: entryPoints: - web routes: - match: Host(`dome.od.com`) kind: Rule services: - name: dubbo-demo-consumer port: 8080
|
以上是挂载sidecar的k8s发布文件,以微服务dubbo
为例,主要是通过共享 volume 的方式挂载agent。其中initContainers通过 sw-agent 卷挂载了 skywalking-agent 镜像中的 /skywalking/agent,并将上面构建好的镜像中的 agent 目录 cp 到 /skywalking/agent 目录,完成之后微服务容器启动时也挂载了skywalking-agent卷,并将其挂载到容器的 /skywalking/agent 目录,这样就完成了共享过程。
部署启动微服务,并验证其是否已经正常接入SkyWalking监控
1 2
| kubectl apply -f dubbo-demo-service.yaml kubectl apply -f dubbo-demo-web.yaml
|
查看相关Pod是否运行成功:
1 2 3 4
| $ kubectl get pods -n app NAME READY STATUS RESTARTS AGE dubbo-demo-consumer-647855d4f6-v7j64 1/1 Running 0 14m dubbo-demo-service-6fd4f5685c-n2jbx 1/1 Running 0 14m
|
运行成功了!此时可以访问下服务的测试接口,多刷几次,也可以制作一些错误,之后通过SkyWalking UI查看是否有监控数据。
如上图所示,在访问微服务测试接口后可以看到SpringCloud微服务已经通过Agent像SkyWalking上报了APM监控数据!