设为首页 收藏本站
查看: 1068|回复: 0

[经验分享] 滚动 docker 中的 nginx 日志

[复制链接]

尚未签到

发表于 2018-11-15 11:01:20 | 显示全部楼层 |阅读模式
  Nginx 自己没有处理日志的滚动问题,它把这个球踢给了使用者。一般情况下,你可以使用 logrotate 工具来完成这个任务,或者如果你愿意,你可以写各式各样的脚本完成同样的任务。本文笔者介绍如何滚动运行在 docker 中的 nginx 日志文件。

思路
  Nginx 官方其实给出了如何滚动日志的说明:

  Rotating Log-files
  In order to rotate log files, they need to be renamed first. After that USR1 signal should be sent to the master process. The master process will then re-open all currently open log files and assign them an unprivileged user under which the worker processes are running, as an owner. After successful re-opening, the master process closes all open files and sends the message to worker process to ask them to re-open files. Worker processes also open new files and close old files right away. As a result, old files are almost immediately available for post processing, such as compression.

  这段说明的大意是:


  • 先把旧的日志文件重命名
  • 然后给 nginx master 进程发送 USR1 信号
  • nginx master 进程收到信号后会做一些处理,然后要求工作者进程重新打开日志文件
  • 工作者进程打开新的日志文件并关闭旧的日志文件
  其实真正需要我们做的工作只有前面两点!

创建测试环境
  假设你的系统中已经安装好了 docker,这里我们直接运行一个 nginx 容器:
  

$ docker run -d \  -p 80:80 \
  -v $(pwd)/logs/nginx:/var/log/nginx \
  --restart=always \
  --name=mynginx \
  nginx:1.11.3
  

  注意,我们把 nginx 的日志绑定挂载到了当前目录下的 logs 目录下。
  把下面的内容保存到 test.sh 文件中:
  

#!/bin/bash  

  
for ((i=1;i /dev/null
  sleep 1
  
done
  

  然后运行这个脚本,就可以模拟产生连续的日志记录。

创建滚动日志的脚本
  创建 rotatelog.sh 文件,其内容如下:
  

#!/bin/bash  

  
getdatestring()
  
{
  TZ='Asia/Chongqing' date "+%Y%m%d%H%M"
  
}
  
datestring=$(getdatestring)
  

  
mv /var/log/nginx/access.log /var/log/nginx/access.${datestring}.log
  
mv /var/log/nginx/error.log /var/log/nginx/error.${datestring}.log
  
kill -USR1 `cat /var/run/nginx.pid`
  

  

  getdatestring 函数取当前的时间并格式化为字符串,比如 "201807241310",笔者比较喜欢用日期和时间来命名文件。注意这里通过 TZ='Asia/Chongqing' 指定了时区,因为默认情况下格式化的是 UTC 时间,用起来怪怪的(要实时脑补 +8 小时)。下面的两条 mv 命令用来重命名日志文件。最后通过 kill 命令向 nginx master 进程发送 USR1 信号。
  通过下面的命令为 rotatelog.sh 文件添加可执行权限并复制到 $(pwd)/logs/nginx 目录下:
  

$ chmod +x rotatelog.sh  
$ sudo cp rotatelog.sh $(pwd)/logs/nginx
  

定时执行滚动操作
  我们的 nginx 运行在容器中,所以需要在容器中给 nginx master 进程发送 USR1 信号。因此我们需要通过 docker exec 命令在 mynginx 容器中执行 rotatelog.sh 脚本:
  

$ docker exec mynginx bash /var/log/nginx/rotatelog.sh  

  执行一次上面的命令,会如期产生一批新的日志文件:
DSC0000.jpg

  下面我们把这个命令配置在定时任务中,让它每天早上 1 点钟执行一次。执行 crontab -e 命令,并在文件的末尾添加下面这行:
  

* 1 * * * docker exec mynginx bash /var/log/nginx/rotatelog.sh  

DSC0001.jpg

  保存并退出就可以了。下图是笔者测试过程中每 5 分钟滚动一次的效果:
DSC0002.jpg


为什么不在宿主机中直接 mv 日志文件?
  理论上这么做是可以的,因为通过绑定挂载的数据卷中的内容从宿主机上看和从容器中看都是一样的。但是真正这么做的时候你很可能碰到权限问题。在宿主机中,你一般使用的是普通用户,而在容器中产生的日志文件的所有者是会是特殊的用户,并且一般不会给其它用户写和执行的权限:
DSC0003.jpg

  当然,如果你在宿主机中使用的是 root 用户就不会有问题。
  能从宿主机中发送的信号吗?
  其实这个问题的全称应该是:能从宿主机中给 docker 容器中的 nginx master 进程发送信号吗?
  答案是,可以的。
  笔者这《在 docker 容器中捕获信号》一文中介绍了容器中信号的捕获问题,感兴趣的朋友可以去看看。在那篇文章中我们介绍了 docker 向容器中进程发送信号的 kill 命令。我们可以通过命令:
  

$ docker container kill mynginx -s USR1  

  向容器中的 1 号进程(nginx master)发送 USR1 信号(这种方式只能向 1 号进程发送信号):
DSC0004.jpg

  结合上面的两个问题,我们可以写出另外的一种方式来滚动 docker 中的 nginx 日志。这种方式不需要通过 docker exec 命令在容器中执行命令,而完全在宿主机中完成所有的操作:


  • 先重命名容器数据卷中的日志文件
  • 给容器中的 1 号进程发送 USR1 信号
总结
  相比之下我还是更喜欢第一种方式,它逻辑上清晰,操作上几乎与宿主机完全隔离,也不容易出错。但是通过第二种方式的尝试,我们不但可以找到新的实现方式,还会加深对容器操作的理解。学而不思则罔啊!
  参考:


  • How To Configure Logging and Log Rotation in Nginx on an Ubuntu VPS
  • How To Manage Logfiles with Logrotate on Ubuntu 16.04
  作者:sparkdev
  出处:http://www.cnblogs.com/sparkdev/
  技术交流群:238757010
  更多详情关注51Reboot教育



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-635360-1-1.html 上篇帖子: nginx迁移 下篇帖子: nginx日志模块详解
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表