小言_互联网的博客

k8s微服务接入SkyWalking,怎么玩?

319人阅读  评论(0)

大家好!我是"无敌码农"!前两天我在《分布式链路追踪,要怎么玩下?》这篇文章中给大家分享了关于分布式链路追踪的基本原理和SkyWalking的k8s部署玩法,如果还没来得及看的朋友可以点击上面链接回顾下!

今天要给大家分享是我们日常工作中最常见的一种场景,那就是部署在k8s环境下的Java微服务,要接入SkyWalking的具体玩法,通过这个过程咱们可以更深入的理解SkyWalking进行数据采集的逻辑,也能更深刻地从运维角度理解日常工作中所写的Java微服务被无侵入的方式接入分布式链路追踪系统的过程!

废话不多说,接下来就让我们开启干货模式吧!

Java微服务接入SkyWalking的方式


在上篇文章关于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)、下载SkyWalking官方发行包,并解压到指定目录


   
  1. #下载skywalking -8.3 .0  for es7版本的发布包,与部署的skywalking后端版本一致
  2. $ wget https: //mirror.bit.edu.cn/apache/skywalking/8.3.0/apache-skywalking-apm-es7-8.3.0.tar.gz
  3. #将下载的发布包解压到当前目录
  4. $ tar -zxvf apache-skywalking-apm-es7 -8.3 .0.tar.gz

2)、构建skywalking-agentsidecar镜像并push至hub私有镜像仓库

在前面步骤中解压的skywalking发行包的同级目录编写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-es7/agent /usr/skywalking/agent
  5. WORKDIR

在上述Dockefile文件中使用是的bosybox镜像,而不是SkyWalking的发行镜像,这样可以确保构建出来的sidecar镜像保持最小。

完成Docker文件编写后,执行镜像构建命令:


   
  1. #执行镜像构建命令
  2. $ docker build .  -t springcloud-action/skywalking-agent-sidecar: 8.3 .0
  3. Sending build context to Docker daemon   556.5MB
  4. Step  1/ 5 : FROM busybox:latest
  5. latest: Pulling from library/busybox
  6. d60bca25ef07: Pull complete 
  7. Digest: sha256: 49dae530fd5fee674a6b0d3da89a380fc93746095e7eca0f1b70188a95fd5d71
  8. Status: Downloaded newer image  for busybox:latest
  9.  ---> a77dce18d0ec
  10. Step  2/ 5 : ENV LANG=C.UTF -8
  11.  ---> Running in e95b4c25ebf3
  12. Removing intermediate container e95b4c25ebf3
  13.  --->  83f22bccb6f3
  14. Step  3/ 5 : RUN set -eux && mkdir -p /usr/skywalking/agent
  15.  ---> Running in  49c2eac2b6ab
  16. + mkdir -p /usr/skywalking/agent
  17. Removing intermediate container  49c2eac2b6ab
  18.  --->  89cf3ce8238e
  19. Step  4/ 5 : add apache-skywalking-apm-bin/agent /usr/skywalking/agent
  20.  --->  91fe5f06948f
  21. Step  5/ 5 : WORKDIR /
  22.  ---> Running in  6a64553f1870
  23. Removing intermediate container  6a64553f1870
  24.  --->  7e73ddba48bb
  25. Successfully built  7e73ddba48bb
  26. Successfully tagged springcloud-action/skywalking-agent-sidecar: 8.3 .0为了验证构建的镜像是否成功,可以通过命令查看本地构建的镜像,命令如下:

   
  1. #查看本地镜像信息
  2. $ docker images
  3. REPOSITORY                                                   TAG                   IMAGE ID            CREATED             SIZE
  4. springcloud-action/skywalking-agent-sidecar                            8.3 .0                  7e73ddba48bb         2 minutes ago        32.2MB
  5. ...

3)、将打包的镜像推送到harbor镜像仓库

为了便于后续微服务直接使用已经构建好的SkyWalking Agent SideCar镜像,我们可以将其push至私有Harbor镜像仓库中。具体命令如下:


   
  1. #登录镜像仓库,输入用户名密码(admin/Harbor12345)
  2. $ docker login http: //10.211.55.2:8080
  3. Username: admin
  4. Password: 
  5. Login Succeeded

这里的Harbor私有镜像仓库一般公司都会自己搭建,在本公众号「Devops技术专栏」的相关文章中也有相应介绍。接下来我们对构建的镜像打tag并上传,具体如下:


   
  1. #这里将原先构建的镜像安装{镜像仓库地址}/项目名称/镜像名称的方式打tag
  2. $ docker tag springcloud-action/skywalking-agent-sidecar: 8.3 .0  10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar

之后可以具体查看已经打过tag镜像信息,命令如下:


   
  1. $ docker images
  2. REPOSITORY                                                       TAG                   IMAGE ID            CREATED             SIZE
  3. springcloud-action/skywalking-agent-sidecar                       8.3 .0                 e21040c57e42         2 weeks ago          32.2MB
  4. 10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar     latest                e21040c57e42         2 weeks ago          32.2MB
  5. ...

接下来我们将打过tag的镜像推送至私有Harbor仓库,具体操作如下:


   
  1. #将镜像推送到Harbor私有镜像仓库
  2. $ docker push  10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar
  3. The push refers to repository [ 10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar]
  4. e80d641c3ed9: Layer already exists 
  5. 11fe582bd430: Layer already exists 
  6. 1dad141bdb55: Layer already exists 
  7. latest: digest: sha256:b495c18c3ae35f563ad4db91c3db66f245e6038be0ced635d16d0e3d3f3bcb80 size:  946

完成后可以进入harbor仓库进行查看,如下图所示:

SideCar模式接入SkyWalking服务

上面我们通过手工构建的方式构建了SkyWalking Java Agent的公共Docker镜像,并将其Push到了我们的私有Harbor镜像仓库,接下来我们将演示如何通过编写Kubernetes服务发布文件,来将Java服务发布到K8s集群的过程中自动以SideCar的形式集成Agent、并接入SkyWalking服务。

这个过程才是作为一个Java程序员最关心的步骤。在开始下面步骤前,你应该通过IDEA构建一个Spring Boot微服务工程,具体构建的过程就不掩饰了,但重点是你这个Spring Boot工程应该支持构建Docker镜像,以Maven为例,需要在pom.xml文件中添加打包插件,具体如下:


   
  1. <!--添加将Java应用打包为Docker Image的Maven插件-->
  2. <plugin>
  3.     <groupId>com.spotify</groupId>
  4.     <artifactId>dockerfile-maven-plugin</artifactId>
  5.     <version> 1.4 .13</version>
  6.     <executions>
  7.         <execution>
  8.             <id>build-image</id>
  9.             <phase> package</phase>
  10.             <goals>
  11.                 <goal>build</goal>
  12.             </goals>
  13.         </execution>
  14.     </executions>
  15.     <configuration>
  16.         <!--指定Dockerfile文件位置-->
  17.         <dockerfile>docker/Dockerfile</dockerfile>
  18.         <repository>${docker.repository}/springcloud-action/${app.name}</repository>
  19.         <!--<tag>${project.version}</tag>-->
  20.         <buildArgs>
  21.             <!--提供参数向Dockerfile传递-->
  22.             <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
  23.         </buildArgs>
  24.     </configuration>
  25. </plugin>

其中<configuration>标签中指定的Dockerfile文件内容如下:


   
  1. FROM openjdk: 8u191-jre-alpine3 .9
  2. ENTRYPOINT [ "/usr/bin/java""-jar""/app.jar"]
  3. ARG JAR_FILE
  4. ADD ${JAR_FILE} /app.jar
  5. EXPOSE  8080

这就是一个简单的镜像构建文件,如果不采用sidecar方式,那么就需要在服务镜像构建文件中添加SkyWalking Agent的相关集成,但这里我们是sidecar方式,所以服务镜像构建文件就不用那么复杂了!

此外<configuration>标签中关于镜像仓库地址、应用名称的动态参数在pom.xml文件中的定义如下(把玩时以自己实际环境为准):


   
  1. <properties>
  2.     <!--定义Docker镜像仓库地址-->
  3.     <docker.repository> 10.211 .55 .2: 8080</docker.repository>
  4.     <!--定义项目名称作为镜像名称生成的组成部分-->
  5.     <app.name>chapter10-monitor-demo</app.name>
  6. </properties>

接下来具体讲述接入步骤:

1)、将Java微服务工程打包成Docker镜像并Push到Harbor镜像仓库


   
  1. # Maven项目构建,会自动根据pom.xml中的相关插件配置进行docker镜像构建
  2. $ mvn clean install -X

查看本地新构建的镜像信息,具体如下:


   
  1. $ docker images
  2. REPOSITORY                                                       TAG                   IMAGE ID            CREATED             SIZE
  3. 10.211 .55 .2: 8080/springcloud-action/chapter10-monitor-demo       latest                 3ae132cdfeb7         12 seconds ago       121MB
  4. 10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar     latest                e21040c57e42         2 weeks ago          32.2MB
  5. springcloud-action/skywalking-agent-sidecar                       8.3 .0                 e21040c57e42         2 weeks ago          32.2MB
  6. ...

将微服务镜像push到Harbor镜像仓库:


   
  1. $ docker push  10.211 .55 .2: 8080/springcloud-action/chapter10-monitor-demo 
  2. The push refers to repository [ 10.211 .55 .2: 8080/springcloud-action/chapter10-monitor-demo]
  3. 5f3427edfc10: Pushed 
  4. 925523484e00: Layer already exists 
  5. 344fb4b275b7: Layer already exists 
  6. bcf2f368fe23: Layer already exists 
  7. latest: digest: sha256:b424180c56b28a9a7704a1f6476f4247fad12cc27721c21fce32149a8f344dee size:  1159

3)、微服务Kubernetes发布文件集成SkyWalking Agent实现埋点

到这里你并没有发现为了将Java服务接入SkyWalking,你需要在Java微服务本身做任何动作,而接下来在k8s部署文件中的将演示,为什么要将这种方式称之为SideCar。

其主要原理是通过Kubernetes的初始化容器initContainers来实现的,initContainers是一种专用容器,可以在应用容器启动之前运行,可以用于完成应用启动前的必要初始化工作。具体的Kubernetes部署文件(deploy-skywalking.yml)内容如下:


   
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4.   name: chapter10-monitor-demo
  5. spec:
  6.   selector:
  7.     matchLabels:
  8.       app: chapter10-monitor-demo
  9.   replicas:  1
  10.   #设置滚动升级策略
  11.   #Kubernetes在等待设置的时间后才开始进行升级,例如 5
  12.   minReadySeconds:  5
  13.   strategy:
  14.      type: RollingUpdate
  15.     rollingUpdate:
  16.       #升级过程中最多可以比原先设置多出的Pod数量
  17.       maxSurge:  1
  18.       #升级过程中Deployment控制器最多可以删除多少个旧Pod,主要用于提供缓冲时间
  19.       maxUnavailable:  1
  20.   template:
  21.     metadata:
  22.       labels:
  23.         app: chapter10-monitor-demo
  24.     spec:
  25.       #构建初始化镜像(通过初始化镜像的方式集成SkyWalking Agent)
  26.       initContainers:
  27.         - image:  10.211 .55 .2: 8080/springcloud-action/skywalking-agent-sidecar:latest
  28.           name: sw-agent-sidecar
  29.           imagePullPolicy: IfNotPresent
  30.           command: [ "sh"]
  31.           args:
  32.             [
  33.                "-c",
  34.                "mkdir -p /skywalking/agent && cp -r /usr/skywalking/agent/* /skywalking/agent",
  35.             ]
  36.           volumeMounts:
  37.             - mountPath: /skywalking/agent
  38.               name: sw-agent
  39.       containers:
  40.         - name: chapter10-devops-demo
  41.           image:  10.211 .55 .2: 8080/springcloud-action/chapter10-monitor-demo:latest
  42.           env:
  43.             #这里通过JAVA_TOOL_OPTIONS,而不是JAVA_OPTS可以实现不通过将agent命令加入到java应用jvm参数而实现agent的集成
  44.             - name: JAVA_TOOL_OPTIONS
  45.               value: -javaagent:/usr/skywalking/agent/skywalking-agent.jar
  46.             - name: SW_AGENT_NAME
  47.               value: chapter10-devops-demo
  48.             - name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
  49.               # FQDN: servicename.namespacename.svc.cluster.local
  50.               value: oap.skywalking: 11800
  51.             - name: SERVER_PORT
  52.               value:  "8080"
  53.             - name: SPRING_PROFILES_ACTIVE
  54.               value: test
  55.           volumeMounts:
  56.             - mountPath: /usr/skywalking/agent
  57.               name: sw-agent
  58.       volumes:
  59.         - name: sw-agent
  60.           emptyDir: {}
  61. ---
  62. apiVersion: v1
  63. kind: Service
  64. metadata:
  65.   name: chapter10-monitor-demo
  66.   labels:
  67.     svc: chapter10-monitor-demo
  68. spec:
  69.   selector:
  70.     app: chapter10-monitor-demo
  71.   ports:
  72.     - name: http
  73.       port:  8080
  74.       nodePort:  30001
  75.    type: NodePort

以上是挂载sidecar的k8s发布文件,以微服务“chapter10-devops-demo”为例,主要是通过共享volume的方式挂载agent。其中initContainers通过skywalking-agent卷挂载了skywalking-agent-sidecar镜像中的/skywalking/agent,并将上面构建好的镜像中的agent目录cp到了/skywalking/agent目录,完成之后微服务容器启动时也挂载了skywalking-agent卷,并将其挂载到容器的/usr/skywalking/agent目录,这样就完成了共享过程。

这里有一个有意思的点,Java服务通过Agent接入SkyWalking一般情况下还需要在启动命令中加入JVM参数,例如:“-javaagent:/usr/skywalking/agent/skywalking-agent.jar”。这就需要我们在定义Java程序镜像打包的Dockerfile文件中通过“ENTRYPOINT”加入相关参数,例如:

ENTRYPOINT [ "sh""-c""java ${JAVA_OPTS} -javaagent:/app/agent/skywalking-agent.jar -Dskywalking.collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES} -Dskywalking.agent.service_name=${SW_AGENT_NAME} -Dskywalking.agent.instance_name=${HOSTNAME} -Djava.security.egd=file:/dev/./urandom -jar /app/app.jar $PROFILE"

但这种方式需要在Dockerfile文件中额外设置SkyWalking Agent相关的JVM参数,所以你可能没注意到,在上述k8s部署文件中我所使用的是“JAVA_TOOL_OPTIONS”这个参数,而不是最常见的“JAVA_OPTS”。这个点很多人都不知道,如果你耐心看到这里,恭喜你Get了一个新技能!至于二者的区别,感兴趣的朋友可以搜索下!

4)、部署启动微服务,并验证其是否已经正常接入SkyWalking监控

接下来我们进入部署文件所在目录,执行发布命令如下:


   
  1. $ kubectl apply -f deploy-skywalking.yml
  2. deployment.apps/chapter10-monitor-demo created
  3. service/chapter10-monitor-demo created

之后查看相关Pod是否运行成功:


   
  1. $ kubectl get pods
  2. NAME                                     READY   STATUS    RESTARTS   AGE
  3. chapter10-monitor-demo -5767d54f5-vfqqf    1/ 1     Running    0           96m

运行成功了!此时可以访问下服务的测试接口,多刷几次,之后通过SkyWalking UI查看是否有监控数据,如下图所示:

如上图所示,在访问微服务测试接口后可以看到SpringCloud微服务已经通过Agent像SkyWalking上报了APM监控数据!

后记

本文实验步骤比较多,也许你很难一次性看完,但是真正的技术都是要练的,所以有空的时候搭建环境后玩一玩是理解文章内容的关键!如果你能读到这里的文字,希望老铁们可以帮我点个赞!如果觉得有价值也请分享给其他热爱技术的朋友!

—————END—————

参考文档:

https://skywalking.apache.org/zh/2019-08-30-how-to-use-skywalking-agent/


转载:https://blog.csdn.net/weixin_44296862/article/details/114313404
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场