docker中實現服務日誌輪轉

2022-06-26 00:57:13 字數 4962 閱讀 1835

通常我們乙個完整的應用映象有兩部分組成,乙個是執行時環境,乙個是應用程式。我們以php應用為例,乙個完整的php應用需要包含openresty + php兩個服務來配置執行時環境,然後再加上php**,來完成一整個php應用的發布。php**產生的日誌由程式自行控制,一般都會按天滾動,在日誌量較大的情況下,也可能按小時滾動,或者按照單個日誌檔案的大小來實現滾動。而nginx和php服務的日誌預設情況下並不支援這種滾動,所以預設情況下,乙個openresty+php容器在其生命週期內,就只會寫乙個日誌檔案,如果該容器長時間執行,openresty與php服務的訪問日誌就會變的非常巨大,給我們日誌清理造成了不便。

雖然預設情況下,openresty和php等服務的訪問日誌並不會自動滾動,但我們卻可以使用一些第三方工具來實現。在傳統的應用部署中,我們使用logrotate + crontab來實現openresty 與php等服務的日誌滾動。而事實上,這一方案在容器環境下仍然適用。我們的解決方案是,在每個服務的基礎映象中配置好logrotate和crontab,這樣在容器執行起來後,就會自動根據配置好的輪轉策略實現日誌滾動。

我們仍然以openresty+php為例,給出乙個openresty+php的基礎映象的dockerfile示例如下:

maintainer yanwei "[email protected]"

env nginx_home /usr/local/ngx_openresty

env php_home /usr/local/php7

run groupadd -g 571 www && \

useradd -u 571 -g 571 www && \

yum install -y iproute cronie logrotate

add lib64.tar.gz /

add openresty.tar.gz /

add phpfpm7.tar.gz /

add php.ini $php_home/etc/php.ini

add phpfpm.conf $php_home/etc/phpfpm.conf

add nginx.conf $nginx_home/nginx/conf/nginx.conf

add libnsssysinit.so /usr/lib64/libnsssysinit.so

add build.sh /

add run.sh /

add crontab /etc/crontab

add logrotate /etc/cron.daily/logrotate

add logrotate.conf /etc/logrotate.conf

run chown www -r /home/www $nginx_home $php_home && \

chmod +x /build.sh /run.sh /etc/cron.daily/logrotate /usr/lib64/libnsssysinit.so

expose 80

entrypoint ["/build.sh"]

cmd ["/run.sh"]

在上面的dockerfile中,我們通提取.so檔案並打入到映象中的方式來完成了openresty和php的安裝。其中lib64.tar.gz即openresty和php7所依賴的全部.so檔案,opernsty.tar.gz和phpfpm7.tar.gz為編譯安裝後的openresty和php7的**檔案。我們需要注意的大概有如下幾個檔案:

build.sh

run.sh

crontab

logrotate

logrotate.conf

#!/bin/bash

php_home=/usr/local/php7

/usr/sbin/crond

$php_home/sbin/php-fpm -c $php_home/etc/php.ini -y $php_home/etc/phpfpm.conf

/usr/local/ngx_openresty/nginx/sbin/nginx -c /usr/local/ngx_openresty/nginx/conf/nginx.conf -g "daemon off;"

這個檔案中,啟動了三個服務,分別為crond,php-fpm以及openresty。這很好理解,我們需要openresty和php環境以提供基本的php應用的web功能,需要crontab來實現服務的日誌輪轉。

logrotate.conf提供logrotate的輪轉配置檔案,存放到映象的/etc目錄下,內容如下:

在該配置檔案中,定義了對如下三個日誌檔案做輪**

可以看到,這三個日誌檔案在這裡並非真正意義上的日誌檔案路徑,而是使用了三個佔位符,由於在我們的映象中,日誌檔案的路徑並不固定,只有在容器啟動的那一刻才能確定具體的日誌路徑。所以我這裡採用了docker-entrypoint的方式,在啟動的時候,執行build.sh指令碼來實現日誌路徑的替換。build.sh中關於日誌部分的定義如下:

##############################

# log configration #

##############################

php_home=/usr/local/php7

phpconfigfile=$php_home/etc/php.ini

phpfpmconfigfile=$php_home/etc/phpfpm.conf

nginxconfigfile=/usr/local/ngx_openresty/nginx/conf/nginx.conf

logrotatefile=/etc/logrotate.conf

logdir=/home/www/logs

srvlogdir=$/srvlogs

if [ ! -z $ ];then

host_name=$

else

host_name=$(hostname)

fielse

exit 1

finginxlogdir=$/nginx

phplogdir=$/php

if [ $x == "did_format"x ];then

sed -i "s//did_format/g" $nginxconfigfile

else

sed -i "s//real_ip/g" $nginxconfigfile

finginxaccesslog=$/nginx.access.log

nginxerrorlog=$/nginx.error.log

phpfpmerrorlog=$/phpfpm.error.log

phpfpmaccesslog=$/phpfpm.access.log

phpfpmslowlog=$/phpfpm.slow.log

phperrorlog=$/php.error.log

sed -i "s@@$@g" $nginxconfigfile

sed -i "s@@$@g" $nginxconfigfile

sed -i "s@@$@g" $phpfpmconfigfile

sed -i "s@@$@g" $phpfpmconfigfile

sed -i "s@@$@g" $phpfpmconfigfile

sed -i "s@@$@g" $phpconfigfile

sed -i "s@@$@g" $logrotatefile

sed -i "s@@$@g" $logrotatefile

sed -i "s@@$@g" $logrotatefile

exec "$@"

#!/bin/sh

/usr/sbin/logrotate -s /var/lib/logrotate/logrotate.status -f /etc/logrotate.conf

exitvalue=$?

if [ $exitvalue != 0 ]; then

/usr/bin/logger -t logrotate "alert exited abnormally with [$exitvalue]"

fiexit 0

這個指令碼比較簡單,就是通過logrotate執行輪轉。其中-f表示強制輪轉,-s用於記錄每一次輪轉的狀態。

最後定義具體crontab的執行時間,檔案為/etc/crontab,內容如下:

shell=/bin/bash

path=/sbin:/bin:/usr/sbin:/usr/bin

mailto=root

# for details see man 4 crontabs

# example of job definition:

# .---------------- minute (0 - 59)

# | .------------- hour (0 - 23)

# | | .---------- day of month (1 - 31)

# | | | .------- month (1 - 12) or jan,feb,mar,apr ...

# | | | | .---- day of week (0 - 6) (sunday=0 or 7) or sun,mon,tue,wed,thu,fri,sat

# | | | | |

# * * * * * user-name command to be executed

0 0 * * * root /usr/bin/run-parts /etc/cron.daily

至此,實現了容器內服務日誌的自動輪轉。

java實現日誌服務

我們在伺服器程式中經常用到日誌,日誌對於我們排查問題有很大的幫助。下面是日誌服務的思路以及實現 思路 多個生產者單個消費者的設計方式,每個呼叫log的操作都相當於乙個生產者,而後台的日誌執行緒則相當於消費者。public class loggerservice public void start p...

docker 中執行 redis 服務

先使用 dockerfile 建立乙個 redis 容器 from ubuntu latest run apt get update run apt get y install redis server expose 6379 entrypoint usr bin redis server 使用do...

Docker中開啟sshd服務

ssh服務安裝 開機自起 在 root目錄下建立run.sh指令碼,新增如下內容 bin bash service sshd restart while do sleep 10 done其實開機自起可以用cmd的,但是暫時不會。就統一用指令碼執行的方式防止退出,感覺可調控行蠻好的。儲存修改 開啟服務...