基於Docker應用容器日誌檔案收集

jaymarco發表於2020-07-02

1 背景介紹

中介軟體應用執行在Docker容器中能夠感受到容器快速建立快速銷燬確實帶來了很大的便利性、靈活性。但由於Docker應用容器銷燬不管人為操作,還是容器掛掉甚至容器應用導致其崩潰,它執行的資料都會隨著它的生命週期結束而結束,這種情況是非常適合部署無狀態服務。卻不適合有狀態的應用部署。但問題來了,假如運維同事需要對容器應用發生的故障進行下一步分析,而在容器中這分部有狀態的應用日誌也會隨著容器銷燬而銷燬。日誌都丟了還談什麼故障分析定位,運維同事面臨盲目被動狀態。然而在大的容器叢集環境下如果直接將容器應用日誌持久化到本地磁碟目錄,那樣日誌會出現目錄結構臨亂和容器日誌檔案也會面臨覆蓋問題。


2 日誌轉存需求

1)將容器中的單個或多個業務應用新增日誌內容按照一定目錄結構存放在遠端日誌伺服器。

2)儲存日誌的目錄結構形式需要以下方式儲存:

/logs/app_id/service_id/container_id/app_name/xxx.log


3 工具介紹

1) Filebeat是一個日誌檔案託運工具,在你的伺服器上安裝客戶端後,filebeat會監控日誌目錄或者指定的日誌檔案,追蹤讀取這些檔案(追蹤檔案的變化,不停的讀),並且轉發這些資訊到logstarsh中存放。

2) Logstash是一款輕量級的日誌蒐集處理框架,可以方便的把分散的、多樣化的日誌蒐集起來,並進行自定義的處理,然後傳輸到指定的位置。

4 Logstash日誌伺服器

部署日誌伺服器logstash配置要求如下。

系統

Centos7.0 X86_64 以上

CPU

4核

記憶體

16G

儲存

外部儲存500G以上

Logstash軟體對JDK也是有要求的,建議在JDK1.8.0以上版本來執行logstash。


4.1 安裝JDK軟體

直接去oracle官方下載JDK版本1.8軟體來安裝

tar xvf jdk1.8.0_131.tar.gz –C /usr

然後配置JDK環境變數vi /etc/profile

JAVA_HOME=/usr/jdk1.8.0_131

CLASSPATH=.:$JAVA_HOME/lib.tools.jar

PATH=$JAVA_HOME/bin:$PATH                                                                                   

export JAVA_HOME CLASSPATH PATH

用命令source /etc/profile生效環境變數


4.2 安裝logstash軟體

軟體下載

軟體安裝

執行命令tar -xvf /opt/ logstash-6.0.0.tar.gz 解壓logstash

啟動logstash

/opt/logstash/bin/logstash -f /opt/logstash/logstash.conf

在日誌伺服器上新建一個/logs目錄用於儲存大量應用容器日誌。

5 Filebeat軟體安裝

直接將filebeat軟體和nginx,php-fpm軟體聯合一起封裝成一個新的基礎映象,事先我們需要知道哪些應用日誌檔案需要提取出來。注意以下是需要提取容器中的應用日誌:

Nginx日誌容器路徑

/var/log/nginx

Php-fpm日誌視窗路徑:

/var/opt/remi/php70/log/php-fpm

下載filebeat軟體

wget

5.1  採用dockerfile指令碼安裝nginx,php-fpm, Filebeat軟體

以下紅色字型部署就是規範nginx與php-fpm應用日誌,並將日誌檔案對映到/logs目錄下。同時安裝filebeat軟體。

FROM centos

MAINTAINER jaymarco@shsnc.com

#Install system library

RUN rpm -ivh     && rpm -ivh   && \

yum install -y php70-php-gd.x86_64 php70-php-mcrypt.x86_64   php70-php-fpm.x86_64 php70-php-pecl-redis.x86_64 python-setuptools  \

php70-php-mbstring.x86_64 php70-php-snmp.x86_64   php70-php-pecl-zip.x86_64 php70-php-xml.x86_64    \

php70-php-mysqlnd.x86_64 php70-php-pecl-mysql.x86_64 gcc  gcc-c++    automake   libtool  make    cmake openssl openssl-devel pcre-devel && \

yum clean all

 

#Make install nginx

RUN rpm -ivh  

COPY nginx.conf /etc/nginx/nginx.conf

 

#set  php config

RUN sed -e 's/127.0.0.1:9000/9000/' \

-e '/allowed_clients/d' \

-e '/catch_workers_output/s/^;//' \

-e '/error_log/d' \

-e 's/;listen.backlog = 511/listen.backlog = 1024/' \

-e 's/pm.max_children = 50/pm.max_children = 300/' \

-e 's/pm.start_servers = 5/pm.start_servers = 30/' \

-e 's/pm.min_spare_servers = 5/pm.min_spare_servers = 30/' \

-e 's/pm.max_spare_servers = 35/pm.max_spare_servers = 60/' \

-e 's/;pm.max_requests = 500/pm.max_requests = 10240/' \

-e 's/;request_slowlog_timeout = 0/request_slowlog_timeout = 2/'   \

-e 's/;request_terminate_timeout = 0/request_terminate_timeout =   20/' \

-e 's/;rlimit_files = 1024/rlimit_files = 65535/' \

-i    /etc/opt/remi/php70/php-fpm.d/ && \

sed -e 's/max_execution_time = 30/max_execution_time = 150/' \

-e 's/max_input_time = 60/max_input_time = 300/' \

-i /etc/opt/remi/php70/php.ini && \

sed -e 's/daemonize = yes/daemonize = no/' \

-e 's/;rlimit_files = 1024/rlimit_files = 65535/' -i   /etc/opt/remi/php70/php-fpm.conf && \

cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\

echo 'Asia/Shanghai' >/etc/timezone

 

RUN easy_install supervisor && \

    mkdir -p /var/log/supervisor   && \

    mkdir -p /var/run/sshd   && \

    mkdir -p   /var/run/supervisord

 

#Add supervisord conf

ADD supervisord.conf /etc/supervisord.conf

 

#copy start script

ADD startserv.sh /startserv.sh

RUN chmod +x /startserv.sh

 

#Set port

EXPOSE 9000

 

# For collecting logs, install filebeat plugin

RUN mkdir /logs

RUN ln -s   /var/log/nginx /logs/

RUN ln -s   /var/opt/remi/php70/log/php-fpm /logs

ADD   filebeat-6.0.0-linux-x86_64.tar.gz /var/log/

RUN chmod +x   /var/log/filebeat/filebeat

 

#Start web server

#ENTRYPOINT ["/var/log/filebeat/init.sh"]

CMD ["/startserv.sh"]

5.2  nginx引數配置最佳化

以下配置是對nginx服務的一些效能指標引數來最佳化,並一起打包到基礎映象中。

user nginx;

worker_processes  2;

worker_cpu_affinity auto;

error_log    /var/log/nginx/error.log error;

worker_rlimit_nofile    10240;

worker_priority -2;

events {

    use epoll;

    accept_mutex on;

    worker_connections  10240;

}

http {

    include       mime.types;

    default_type  application/octet-stream;

    log_format  main    '$remote_addr - $remote_user [$time_local] "$request" '

                        '$status $body_bytes_sent "$http_referer" '

                        '"$http_user_agent" "$http_x_forwarded_for"'

                          'upstream_addr:"$upstream_addr" '

                        'upstream_cache_status:"$upstream_cache_status"   '

                          'upstream_status:"$upstream_status" ';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;

    sendfile_max_chunk   512k;

    aio threads;

    directio 4m;

    keepalive_timeout  65;

    open_log_file_cache   max=1000 inactive=20s valid=1m min_uses=2;

    gzip on;

    gzip_comp_level 4;

    gzip_disable "MSIE   [1-6].";

    gzip_min_length 10k;

    gzip_http_version 1.0;

    gzip_types text/plain   text/css text/xml text/javascript application/xml application/x-javascript   application/xml+rss application/javascript application/json;

    gzip_vary on;

    client_max_body_size   2m;

    include   /etc/nginx/conf.d/*.conf;

}


5.3  supervisord.conf配置引數

容器中只能執行一個程式,如果需要執行多個程式我們使用了supervisord後臺管理程式工具,方便多程式啟動監控。以下紅色字型加入了filebeat啟動命令。

[unix_http_server]

file=/tmp/supervisor.sock ; (the path to the socket file)

[supervisord]

logfile=/tmp/supervisord.log ; (main log file;default   $CWD/supervisord.log)

logfile_maxbytes=50MB ; (max main logfile bytes b4   rotation;default 50MB)

logfile_backups=10 ; (num of main logfile rotation   backups;default 10)

loglevel=info ; (log level;default info; others:   debug,warn,trace)

pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)

nodaemon=true ; (start in foreground if true;default false)

minfds=1024 ; (min. avail startup file descriptors;default 1024)

minprocs=200 ; (min. avail process descriptors;default 200)

user=root       ;

; the below section must remain in the config file for RPC

; (supervisorctl/web interface) to work, additional interfaces   may be

; added by defining them in separate rpcinterface: sections

[rpcinterface:supervisor]

supervisor.rpcinterface_factory =   supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]

serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a   unix socket

[program:php-fpm]

command=/opt/remi/php70/root/usr/sbin/php-fpm -F

[program:nginx]

command=/usr/sbin/nginx -c /etc/nginx/nginx.conf

[program:filebeat]

command=/var/log/filebeat/filebeat   -c /var/log/filebeat/filebeat.yml


5.4  startserv.sh啟動指令碼

以下紅色字型部分的內容主要是為了生成一個filebeat.yml檔案,讓filebeat程式載入對應的app_id,service_id,host_name,logstash等引數值,並將服務接起來。

#!/bin/sh

ip=`ip a|grep -w   inet|grep -v -w lo|awk '{print $2}'|awk -F'/' '{print $1}'`

LOGS="/logs/"

#FILE=`ls -l   $LOGS |awk '/^d/ {print $NF}'`

FILE=`ls $LOGS`

HOME="/var/log/filebeat"

BAK="$HOME/bak"

CONF="$HOME/filebeat.yml"

HOST_NAME=`hostname`

cp $BAK $CONF

for name in   $FILE

do

sed -i   "/paths/a\    -   $LOGS$name/*.log" $CONF

done

sed -i   "s/#APP_ID#/$APP_ID/g" $CONF

sed -i   "s/#ip#/$ip/g" $CONF

sed -i   "s/#SERVICE_ID#/$SERVICE_ID/g" $CONF

sed -i   "s/#HOST_NAME#/$HOST_NAME/g" $CONF

sed -i   "s/#LOGSTASH_HOST#/$LOGSTASH_HOST/g" $CONF

/usr/bin/supervisord -n -c /etc/supervisord.conf

filebeat.yml例子:

filebeat:

 spool_size: 10240

 idle_timeout: "10s"

 prospectors:

  -

   paths:

    - /logs/php-fpm/*.log

    - /logs/nginx/*.log

   fields:

    app_id: "6db116df"

    service_id: "_6db116df_64a00233"

    host_name: "139b3e343614"

   fields_under_root: true

   tail_files: true

   document_type: "172.17.0.2"

processors:

-   drop_fields:

   fields: ["input_type",   "beat", "offset"]

output.logstash:

  hosts: ["XX.XX.XX.XX:5044"]

  worker: 2

打包應用映象

docker build –t  acitivty_front:6.0-201711221420 .


5.5 啟動應用容器

以上操作已經封裝成一個新的應用映象acitivty_front:6.0-201711221420,然後透過docker執行指令來啟動應用映象。

docker run -itd -p 80:80 -e APP_ID=6db116df -e SERVICE_ID=_6db116df_64a00233 -e LOGSTASH_HOST=<日誌伺服器IP> acitivty_front:6.0-201711221420



6 提取日誌結果

應用容器拉起來後同時會啟動動應用和filebeat外掛,容器就會自動對應用日誌統一收集並推送到日誌伺服器。以下是日誌伺服器中看到的提取出來的容器中的應用日誌。


Logstash日誌目錄解析



日誌伺服器logstash接收日誌


有需要的朋友可以關注我的公眾號,文章每日一更



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28833846/viewspace-2702081/,如需轉載,請註明出處,否則將追究法律責任。

相關文章