随着现网生产环境容器化改造逐步完成,核心的业务都由K8S集群中的pod对外提供服务。各个微服务应用间的内部资源调用次数、调用链耗时、调用阈值告警、超时错误等信息指标对保障业务健康运行来说显得非常重要。由于现网使用的是云容器引擎服务,公有云提供了一整套的解决方案。下面是华为云和阿里云相关的产品介绍,总体来说,借助这类的工具,可以快速的查看微服务的各项指标和调用情况,定位相关的问题。
https://support.huaweicloud.com/apm/index.html
https://help.aliyun.com/document_detail/63796.html?spm那么刚需来了,程序猿希望内网开发和测试环境能对照现网生产环境也来这么一套差不多的监控工具,一些隐藏的问题不需要等到上了生产环境才能发现。
问:运维同学要怎么满足这个需求呢?
答:开发和测试环境也迁移上公有云。
PS:心里想想就算了!
本文介绍使用pinpoint满足程序猿这个合理需求。
pinpoint是开源在github上的一款APM监控工具,它是用Java编写的,用于大规模分布式系统监控。关于pinpoint服务端的部署可参考下列的文档。
https://www.cnblogs.com/yyhh/p/6106472.html1、开始前我们要先准备好pinpoint服务端环境。
2、其次需要在pod上进行pinpoint客户端埋点(埋点也就是探针,公有云就是根据这个探针个数进行收费的)
答1:直接把agent做到容器镜像里面。
我们容器化的主要目标是开发、测试和生产环境用同一份镜像和代码,代码上实现一次编译,到处运行,解耦通过集中配置服务,configmap等实现,所以这种做法明显不符合目标。
答2:把pinpoint 相关的agent放到PVC上,然后通过ENV注入CATALINA_OPTS环境变量到Pod。
首先然后通过ENV注入CATALINA_OPTS环境变量到Pod这个是肯定要的,但是如果把pinpoint 相关的agent放到PVC上,虽然能解决问题,但是存在耦合问题,万一PVC、PV出现问题,会导致微服务启动失败。比较好的办法,是通过init-containers来解决这个问题,关于什么是init-containers可参考官方手册: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
.# cd pinpoint/ # cat dockerfile FROM busybox MAINTAINER yangliangwei "ylw@fjhb.cn" ADD pp_agent.tgz /var/lib/pp_agent/ # docker build -t harbor.59iedu.com/fjhb/pp_agent:latest . # docker push harbor.59iedu.com/fjhb/pp_agent
pp_agent.tgz包含了客户端埋点所需要的jar包和配置文件
volumes: - name: hb-lan-server-xml configMap: name: hb-lan-server-xml items: - key: server.xml path: server.xml - name: vol-localtime hostPath: path: /etc/localtime type: '' - name: mfsdata persistentVolumeClaim: claimName: mfsdata - name: pp-agent emptyDir: {} initContainers: - name: init-pinpoint image: 'harbor.59iedu.com/fjhb/pp_agent:latest' command: - sh - '-c' - cp -rp /var/lib/pp_agent/* /var/init/pinpoint resources: {} volumeMounts: - name: pp-agent mountPath: /var/init/pinpoint terminationMessagePath: /dev/termination-log terminationMessagePolicy: File imagePullPolicy: Always
首先定义一个emptyDir类型的卷pp-agent,initcontainers容器启动的时候,将这个pp-agent卷挂载到/var/init/pinpoint目录,并把容器镜像层中的/var/lib/pp_agent/目录下的文件拷贝到pp-agent卷下面,然后initContainers的使命完成,正常退出。
containers: - name: tomcat-zffw image: 'harbor.59iedu.com/dev/fjhb6-ability-order-pay:1.22.0-SNAPSHOT-20190227044640' imagePullPolicy: Always lifecycle: preStop: exec: command: ["/bin/bash", "-c", "PID=`pidof java` && kill -SIGTERM $PID && while ps -p $PID > /dev/null; do sleep 1; done;"] env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: CATALINA_OPTS value: >- -javaagent:/var/init/pinpoint/pinpoint-bootstrap.jar -Dpinpoint.agentId=${POD_IP} -Dpinpoint.applicationName=dev-tomcat-zffw - name: JAVA_OPTS value: >- -server -Xms1024M -Xmx1024M -XX:MaxMetaspaceSize=320m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/tomcat/jvmdump/ -agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n -Duser.timezone=Asia/Shanghai -Drocketmq.client.logRoot=/home/tomcat/logs/rocketmqlog resources: limits: cpu: 2000m memory: 2Gi requests: cpu: '500m' memory: 1Gi volumeMounts: - name: hb-lan-server-xml mountPath: /home/tomcat/conf/server.xml subPath: server.xml - name: vol-localtime readOnly: true mountPath: /etc/localtime - name: mfsdata mountPath: /mnt/mfs - name: pp-agent mountPath: /var/init/pinpoint
业务容器上将pod的ip做成变量POD_IP, 用于-Dpinpoint.agentId使用,通过CATALINA_OPTS变量配置pinpoint客户端相关的参数。第一行是pinpoint agent的jar包位置,为了方便后续升级,这里把具体的版本号去掉。第二行是agent的ID,这个ID是唯一的,使用POD_IP变量动态生成。第三行是采集项目的名称。
业务容器需要挂载pp-agent这个卷,这样通过使用init-containers技术就实现了客户端埋点的效果。
1、客户端启动验证
2、服务端UI查看调用链