隨着現網生產環境容器化改造逐步完成,核心的業務都由K8S集羣中的pod對外提供服務。各個微服務應用間的內部資源調用次數、調用鏈耗時、調用閾值告警、超時錯誤等信息指標對保障業務健康運行來說顯得非常重要。由於現網使用的是雲容器引擎服務,公有云提供了一整套的解決方案。下面是華爲雲和阿里雲相關的產品介紹,總體來說,藉助這類的工具,可以快速的查看微服務的各項指標和調用情況,定位相關的問題。
https://support.huaweicloud.com/apm/index.html
https://help.aliyun.com/document_detail/63796.html?spm
那麼剛需來了,程序猿希望內網開發和測試環境能對照現網生產環境也來這麼一套差不多的監控工具,一些隱藏的問題不需要等到上了生產環境才能發現。
問:運維同學要怎麼滿足這個需求呢?
答:開發和測試環境也遷移上公有云。
PS:心裏想想就算了!
本文介紹使用pinpoint滿足程序猿這個合理需求。
一、Pinpoint是什麼?
pinpoint是開源在github上的一款APM監控工具,它是用Java編寫的,用於大規模分佈式系統監控。關於pinpoint服務端的部署可參考下列的文檔。
https://www.cnblogs.com/yyhh/p/6106472.html
二、需求分析
1、開始前我們要先準備好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/
三、準備init-containers鏡像
.# cd pinpoint/
# cat dockerfile
FROM busybox
MAINTAINER yangliangwei "[email protected]"
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包和配置文件
四、更新微服務yaml文件
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查看調用鏈