create 与 copytruncate
一句话总结
create虽然不会丢失日志,但需要过程的配合,copytruncate虽然不需要**配合,但会失去一点日志。**两者都不是一劳永逸的。
为什么需要这个?
日志文件越大,磁盘就会冻结。但是进程在打开文件的情况下使用,所以不能直接删除。在Linux上rm只删除目录项,打开的文件的块在最后一个手柄关闭之前不会返回。所以df说被挤得紧紧的du据说没有文件。
轮换以两种方式解决了这个问题。
create— 改名字重新制作
app.log → app.log.1 로 rename
새 app.log 생성
프로세스에 SIGHUP 을 보내 다시 열게 한다
rename 会保持inode的原样,所以进程会仍然用在旧文件上。所以必须重新打开。如果不这样做,新的app.log永远是0字节,实际日志是app.log.1继续流下去。虽然没有丢失日志,但没有人能找到。
copytruncate— 复制后剪下来
app.log → app.log.1 로 복사
app.log 를 0바이트로 truncate
因为文件是原样,所以进程什么都不用知道。相反,**复制和剪切之间使用的日志会消失。**如果每秒积累数千行日志,那么这个缝隙就很大。
怎么行动
/var/log/app/*.log {
daily
rotate 14 # 14개까지 보관
size 100M # 또는 100MB 넘으면
compress
delaycompress # 직전 것은 압축하지 않는다(아직 쓰고 있을 수 있다)
missingok
notifempty
create 0640 app app
postrotate
kill -HUP $(cat /run/app.pid) 2>/dev/null || true
endscript
}
delaycompress去很重要。create虽然从方法上讲,过程可能还在旧文件中使用,但如果直接压缩的话,就会导致使用失败。
常见的误解
在容器中运行logrotate。容器通常将日志输出到stdout。然后容器运行时(containerd)将日志写入文件,并**运行时旋转。**kubelet的containerLogMaxSize(基本10Mi),containerLogMaxFiles(基本5)就是那个设置。没有理由在容器内运行logrotate。
**轮换会破坏收集器。**像Fluent Bit这样的收集器以inode为基准跟踪文件。create如果rename的话,收集器可能会一直读取旧的inode,然后错过新文件。Rotate_Wait设置填补了那个缝隙。
在集装箱上不直接进行轮换。
到目前为止的故事是关于在文件中使用的过程。在容器中标准输出 使用后,轮换交由运行时处理。
// /etc/docker/daemon.json 또는 containerd 설정
{"log-driver": "json-file",
"log-opts": {"max-size": "10m", "max-file": "3"}}
如果没有这个设置,日志文件会无限增长**填满节点的磁盘。**然后
那个节点的所有派对都会死亡。在容器管理中,节点DiskPressure罗帕德
是驱逐事故的常见原因。
kubelet方面也有同样的设置(containerLogMaxSize,containerLogMaxFiles).
容器运行时设置和kubelet设置中哪一个适用,取决于运行时。
因为不同,所以确定在节点上确认实际文件大小是确定的。
du -sh /var/log/pods/* | sort -h | tail -5
日志消失的三位数字
与轮换分开,日志在多个地方安静地消失。
**缓冲。**进程死亡时,缓冲中的内容会消失。Python是
PYTHONUNBUFFERED=1,Shell脚本是stdbuf -oL换算成罗单位。
收集器队列超出。 Fluent Bit·Vector 当内存缓冲区满了时会丢弃新日志 (基本政策)。换成磁盘缓冲区会减少丢失,但会写入节点磁盘。
# Fluent Bit — 넘칠 때 디스크로
[SERVICE]
storage.path /var/log/flb-storage/
storage.max_chunks_up 128
[INPUT]
storage.type filesystem
删除容器。如果帕德被删除的话/var/log/pods下面也会消失。所以
要看死去的帕德的日志,以后必须收集器在之前拿走。收集器
每30秒扫描一次,如果中间有pad被抹掉的话,就没有最后的日志了。terminationGrace 稍微增加PeriodSeconds的话,那个窗口就会变小。
要留下什么日志呢?
无论如何设置轮换,如果**量太大的话,就会变成费用。**遵守三个条件的话 大大减少。
- **正常路径仅总结。**每次请求一行即可。在运营中将调试日志 保持打开是日志量爆炸的第一大原因。
- **重复的内容用统计来处理。**如果每秒出现1000次同样的错误,则用“这个错误”代替1000行。 1,000次”一行更好。
- **结构化。**用JSON写的话,以后可以过滤到字段中,保存政策 可以细分为多个部分。
在实际工作中真正重要的东西
保管期限规定为需要调查法规,而不是磁盘。不是“磁盘剩余后90天”,而是“调查障碍一般需要2周,审计要求为1年”,则分为热存储2周+冷存储1年。
而且**压缩几乎总是有利的。**文本日志以gzip压缩,减少了10~20倍。稍微使用CPU,大大节省了磁盘空间。