1. 程式人生 > >Dockerfile配置APM監控實現Java容器的效能監控

Dockerfile配置APM監控實現Java容器的效能監控

通過Dockerfile可以用來構建容器映象,我們一般也是通過這種方式來構建一個Tomcat應用服務容器,如果要實現對容器中的Tomcat服務(或是其他Java應用)進行APM(應用效能管理)監控,就需要我們在容器中放置javaagent並做相關配置,而在已生成的容器中修改配置不符合容器管理的規範,所以我們建議在釋出映象時就將javaagent植入,這樣在生成容器時就可以通過環境變數引數來決定是否開啟監控。

(請持續關注smooth的部落格:https://blog.csdn.net/smooth00,另外有關容器的文章還可以關注:《搭建Jmeter容器叢集平臺》、《以容器部署Ganglia並監控Hadoop叢集

》、《Rancher及Docker快速上手指南(一)》、《Rancher及Docker快速上手指南(二)》、《Rancher及Docker快速上手指南(三)》、《Jenkins自動化部署容器》)

以下是以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監控平臺就能看到應用服務的監控資料:

       總結:對於效能監控來說,容器和虛擬機器下操作其實沒有太大差別,唯一的差別是容器是一種封裝的應用,既然是封裝,我們的監控服務也應該一起封裝進去,而不是等容器部署完了,才開始考慮監控的配置和開啟,一是不方便操作,二是不符合容器的管理要求(容器是即用即生成,不用即消亡,不適合在容器裡做過多配置化操作)。