Dockerfile配置APM監控實現Java容器的效能監控
通過Dockerfile可以用來構建容器映象,我們一般也是通過這種方式來構建一個Tomcat應用服務容器,如果要實現對容器中的Tomcat服務(或是其他Java應用)進行APM(應用效能管理)監控,就需要我們在容器中放置javaagent並做相關配置,而在已生成的容器中修改配置不符合容器管理的規範,所以我們建議在釋出映象時就將javaagent植入,這樣在生成容器時就可以通過環境變數引數來決定是否開啟監控。
(請持續關注smooth的部落格:https://blog.csdn.net/smooth00,另外有關容器的文章還可以關注:《搭建Jmeter容器叢集平臺》、《以容器部署Ganglia並監控Hadoop叢集
以下是以Zoho Applications Manager當中的應用效能管理產品為例(像聽雲、OneAPM等應用效能管理也屬於同類產品,原理一樣,以下配置的關鍵是將監控代理javaagent的jar包和相關配置檔案通過Dockerfile寫入到映象中,並通過環境變數更改配置項):
1、修改catalina.sh
一般APM監控,都是在catalina.sh中追加JAVA_OPTS配置,如下:
export JAVA_OPTS="$JAVA_OPTS -javaagent:$CATALINA_HOME/apminsight/apminsight-javaagent.jar"
我們這次也是這麼幹的,但是會加一個開關來if控制:
if [ "$APM_IS_OPEN" = "true" ] ; then
export JAVA_OPTS="$JAVA_OPTS -javaagent:$CATALINA_HOME/apminsight/apminsight-javaagent.jar"
fi
2、修改apminsight.conf
這是監控代理的配置檔案,其他產品也有類似的配置檔案,主要是對以下幾個引數進行標準化設定
application.name=@[email protected] #這是應用名,這個名稱是用來替換的
apm.host=@[email protected] #這是APM監控平臺的IP,也是用來替換的
apm.port=@[email protected] #這是APM監控平臺的埠,也是用來替換的
3、準備好要部署tomcat的檔案或要替換的配置檔案
比如:jdk-8u171-linux-x64.tar.gz、apache-tomcat-8.5.32.tar.gz、tomcat-users.xml、server.xml,這些檔案都是要確保可以在真實機器上安裝部署和使用的。
然後準備要釋出到tomcat上的應用war包或者檔案,我的環境是rfzf.war
4、配置Dockerfile
# First docker file from zhengguanghua
# VERSION 1.0.1
# Author: zhengguanghua
FROM ubuntu:14.04.3
#作者
# MAINTAINER zhengguanghua <[email protected]>
# add java and tomcat 支援包到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.32.tar.gz /usr/local/
RUN mv /usr/local/apache-tomcat-8.5.32 /usr/local/tomcat
# 配置 java and tomcat 環境變數
ENV JAVA_HOME /usr/local/jdk1.8.0_171
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/tomcat
ENV CATALINA_BASE /usr/local/tomcat
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#定義工作目錄
ENV WORK_PATH /usr/local/tomcat
#定義要釋出的war包檔名
ENV WEB_APP rfzf.war
#刪除原檔案tomcat-users.xml,可不刪除直接COPY覆蓋
#RUN rm $CONF_PATH/$USER_CONF_FILE_NAME
#複製檔案tomcat-users.xml
COPY ./tomcat-users.xml $WORK_PATH/conf/
#複製檔案server.xml
COPY ./server.xml $WORK_PATH/conf/
#複製APM監控代理目錄apminsight
COPY apminsight $WORK_PATH/apminsight
#複製檔案catalina.sh
COPY ./catalina.sh $WORK_PATH/bin/
#複製tomcat啟動檔案(檔案裡也包含apminsight監控代理的配置替換命令)
COPY startTomcat.sh /usr/local/
#給可執行檔案賦許可權,並配置東八區時區
RUN chmod +777 /usr/local/startTomcat.sh && chmod +777 $WORK_PATH/bin/catalina.sh \
&& /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo 'Asia/Shanghai' >/etc/timezone
#複製war包到wepapps目錄下
COPY ./$WEB_APP $WORK_PATH/webapps/
# container listener port
# EXPOSE 8080
# startup web application services by self
# CMD /usr/local/tomcat/bin/catalina.sh run
#讓容器當前目錄定位到工作目錄下
WORKDIR $WORK_PATH
#啟動容器
CMD ["sh", "/usr/local/startTomcat.sh"]
5、編寫startTomcat.sh
由於容器的CMD一般只能執行一個程序命令(多個CMD命令也是最後一個覆蓋前面的),所以把APM監控代理的配置檔案修改命令和tomcat啟動命令全放到startTomcat.sh中,通過一個CMD命令呼叫。
#!/bin/bash
#用sed將環境變數替換成apminsight.conf中的引數
sed -i "s/@[email protected]/${APM_NAME}/g" /usr/local/tomcat/apminsight/apminsight.conf
sed -i "s/@[email protected]/${APM_HOST}/g" /usr/local/tomcat/apminsight/apminsight.conf
sed -i "s/@[email protected]/${APM_PORT}/g" /usr/local/tomcat/apminsight/apminsight.conf
#啟動tomcat,容器不能用後臺執行程序,所以用run在控制檯顯示
/usr/local/tomcat/bin/catalina.sh run
以上啟動tomcat命令用run(必須用run,用catalina.sh start或是startup.sh都不好使),可以防止容器一啟動就關閉(這是容器的一個特性,也是最大的一個坑,應用程序必須在前臺執行,才能成為容器的守護程序,即程序一旦退出或從前臺中止執行容器也會跟著停止)。
以下總結一下容器start.sh的命令原則:
(1)原則上一個容器就執行一個程序,這就是為什麼容器服務要儘量簡單,多程序應用需要拆分成多個容器
(2)容器中要是執行多個守護程序時,前面的程序要用後臺方式執行(或新增 &),否則後面的服務無法啟動
(3)容器中最後一個守護程序一定要用前臺方式執行,否則start.sh退出,容器退出,所有的服務就白啟動了
注:為什麼CMD命令預設一定是覆蓋而不是繼承或追加,很多初次接觸這塊的人都會不理解這麼設計的用意(覺得不能同時多次呼叫CMD不方便),其實這麼實現是很有必要的,比如你在Dockerfile用FROM繼承了一個基礎映象,每個基礎映象肯定都有自己的一套程序邏輯和CMD啟動命令,如果不設計成覆蓋的模式,那麼我們對原有容器映象的任何配置和修改,以及追加新程序,都要顧及太多原有程序的影響,這不利於映象的繼承或巢狀。
6、構建映象
將以上所有檔案都傳到一個目錄下,比如/home/rfzf-tomcat,然後我們進入這個目錄,執行以下命令build成映象:
docker build -t docker-tomcat:1.0 .
7、呼叫映象生成容器
建議將tomcat的logs通過卷的方式持續化日誌檔案,在宿主機上建立目錄/opt/tomcat-logs,並賦予讀寫許可權。以下是生成容器的命令:
docker run --name docker-tomcat -d --restart=unless-stopped -p 8080:8080 -e APM_NAME=Docker_Tomcat -e APM_HOST=172.16.1.251 -e APM_PORT=9099 -e APM_IS_OPEN=true -v /opt/tomcat-logs:/usr/local/tomcat/logs docker-tomcat:1.0
這樣就可以生成容器,而且通過環境變數(-e)將APM的HOST、埠等替換(在啟動tomcat前被替換)了,而且通過APM_IS_OPEN=true,在catalina.sh中也會呼叫apminsight-javaagent.jar監控代理檔案。
以下是執行的容器監檢視:
通過Tomcat的業務窗體訪問,在APM監控平臺就能看到應用服務的監控資料:
總結:對於效能監控來說,容器和虛擬機器下操作其實沒有太大差別,唯一的差別是容器是一種封裝的應用,既然是封裝,我們的監控服務也應該一起封裝進去,而不是等容器部署完了,才開始考慮監控的配置和開啟,一是不方便操作,二是不符合容器的管理要求(容器是即用即生成,不用即消亡,不適合在容器裡做過多配置化操作)。