共计 2485 个字符,预计需要花费 7 分钟才能阅读完成。
过程
给 syslog docker 增加了日志分析脚本. 脚本会使用最短编辑距离算法, 归集错误日志, 发送到测试环境报警群. 该脚本依赖 logrotate. 第二天一早没有看到预期的错误归集报警. 发现 logrotate 不工作了.
xxxxxxxx@xxxxxxxx:/srv/log/p10057_syslog/rsyslog$ cat analyze_error_log.log
('log_path_not_exist', '/srv/log/rsyslog/ejoy_errors/error.log.xxxxxxx')
增加日志分析脚本做了 2 个事情:
- 用 crontab 调用分析脚本.
- build 了一个新的 syslog docker image, 增加了脚本依赖的几个 python 库.
猜测:
logrotate 依赖 crontab, crontab 的配置覆盖了 logrotate 的定期执行
回滚 docker image 版本, 之前并没有 crontab 任务.
事实上开发时已经检查过这一项, 之所以怀疑 crontab, 是因为确实没有可疑改动了.
ubuntu# crontab -l
no crontab for root
最后发现是 logrotate.conf 文件权限问题:
root@xxxxxxx:/etc# /usr/sbin/logrotate -d -v /etc/logrotate.conf
Ignoring /etc/logrotate.conf because of bad file mode.
Handling 0 logs
root@xxxxxxxx:/etc# ls -l /etc/logrotate.conf
-rw-rw-r-- 1 root root 351 Sep 29 03:47 /etc/logrotate.conf
root@xxxxxx:/etc# chmod 644 /etc/logrotate.conf
root@xxxxxx:/etc# /usr/sbin/logrotate -d -v /etc/logrotate.conf
reading config file /etc/logrotate.conf
Handling 1 logs
rotating pattern: /srv/log/rsyslog/*/*.log 4096 bytes (14 rotations)
empty log files are rotated, old logs are removed
considering log /srv/log/rsyslog/admin/access.log
log does not need rotating
considering log /srv/log/rsyslog/admin/admin.log
....
那就很诡异了, 为什么 logrotate.conf 的权限会发生变化呢? 在此之前, 我不知道有 logrotate.conf 文件, 更不用说修改了.
syslog/Dockerfile 里有这样一行, 镜像内 logrotate.conf 文件的权限由 build docker image 机器上 syslog/logrotate.conf 的权限决定:
COPY logrotate.conf /etc/logrotate.conf
发布机器上 logrotate.conf 的 filemode 是 644, 而我是 664. 是我不小心修改了 logrotate.conf 的 filemode 吗? 而 filemode 为 false 导致我忽略了 filemode 的修改?
git config core.filemode false
将 core.filemode 设为 true 也看不到 diff, 经过一番尝试, 发现 git 的一个冷知识:
git 只记录文件的 executable bit
https://medium.com/@tahteche/…
即, 对 git 来说, filemode 只有 755 (user executable) 和 644 (user not executable).
好吧, 是我无意间修改了 logrotate.conf 的 filemode 吗? 我的 logrotate.conf 确实是 664, 打包机上确实是 644. 铁证如山.
重新 checkout battleship, 新 checkout 的 logrotate.conf 是 664. 又引出一个新的问题.
umask 和 USERGROUPS_ENAB
https://superuser.com/questio…
尝试后发现.
不同在于, 我的 umask 是 002, 而打包机是 0022.
我的 user_name 等于 group_name, 而打包机 user_name 和 group_name 不一样.
~ » touch aa
~ » ls -l aa
-rw-rw-r-- 1 enjolras enjolras 0 Sep 29 19:09 aa
~ » umask
002
platformdeploy@DEPLOY-192-168-0-116:~$ touch a
platformdeploy@DEPLOY-192-168-0-116:~$ ls -l a
-rw-r--r-- 1 platformdeploy platform 0 Sep 29 19:56 a
platformdeploy@DEPLOY-192-168-0-116:~$ umask
0022
less /etc/login.defs
Enable setting of the umask group bits to be the same as owner bits
(examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
the same as gid, and username is the same as the primary group name.
If set to yes, userdel will remove the user´s group if it contains no
more members, and useradd will create by default a group with the name
of the user.
USERGROUPS_ENAB yes
结论
不同的环境下, checkout 出来的文件权限不一样. DockerFile 里最好显示指定文件的权限.