kubernets 的容器中日志大kubectl 如何清理容器日志
; L7 ^% L: G- E3 T
7 ?0 `9 t; i' k2 @" G, R% n
' w0 x w! J/ N# ~- q; g创建一个定时任务(CronJob)来定期清理Pod的日志文件。可以使用kubectl create cronjob命令来创建一个定时任务。 在CronJob中使用kubectl delete pod <pod-name>命令来删除指定Pod的日志文件。可以通过标签选择器来选择需要清理的Pod。 可以在CronJob中使用kubectl logs <pod-name> --tail=0命令来清空Pod的日志文件,然后再删除Pod。 设置合适的定时任务调度规则,比如每天凌晨执行清理操作。
2 {. C5 W6 a% R$ a3 R& }
请注意,在清理Pod的日志文件之前,请确保备份重要的日志数据以防丢失。另外,建议在清理操作之前先测试一下命令是否能够正确执行。
8 ? S4 k \5 e5 L H
, c) c( @# ^; {9 w2 Q5 F
- Y3 P3 M, e! E
8 N2 ?$ j$ f$ m& A& [: A; c + x8 ?+ W1 h- r, W5 |6 N* ^# ~
磁盘写满引发的后果
$ i9 @% R) c5 [; b6 t) ?5 \容器数据磁盘写满造成的后果:7 I! h8 H! }4 ]& F) `6 `# `
& T/ U5 N/ R, a4 [ L- G5 ]Pod 不能删除 (一直 Terminating)
1 i) Q% w, d6 ?$ b$ e) T! ], lPod 不能被创建 (一直 ContainerCreating)
% g+ [! |5 V, \7 b( T磁盘写满分两种情况:
+ Y2 I6 y! l% _( U3 A% _
: Q% ?' x P7 x' D4 i磁盘空间全部使用完" \* }4 [0 c/ X7 {- P2 P7 Q
, Z8 ]$ p( M" I& v$ s: Z% s# 系统盘被占满$ df -Th文件系统 类型 容量 已用 可用 已用% 挂载点/dev/vda1 ext4 50G 50G 0G 100% //dev/vdb1 ext4 100G 10G 90G 10% /data
# G+ \- E) _9 u& z磁盘 Inode 全部使用完
! g& ]1 a! ~+ R% q( _* _# D- |* p
6 W. U) i+ C7 s. _- J+ |# 数据盘 Inode 被占满$ df -i文件系统 Inode 已用(I) 可用(I) 已用(I)% 挂载点/dev/vda1 3276800 3276800 0 100% /# J/ P% Y4 U% ~& U' Z
判断磁盘写满方法4 T/ i' Y/ c9 [: a% c2 H6 m
下面命令能快速的排查磁盘占满原因:
# t$ Y6 ]1 e% E4 q1 U5 K
/ k0 ^9 [7 M2 h5 @8 q3 D# Pdocker info | grep 'Docker Root Dir' # 检查 Docker 存储目录
6 g9 i! E4 T6 C K( }& N* K. Q8 _/ Ndocker system df # 查看容器磁盘使用情况
% W. F6 M( b5 e# P) S$ W$ kdf -hT # 检查宿主机 磁盘空间 使用情况
+ B- k& T3 T1 C0 D z. O& A- ]df -i # 检查宿主机 Inode 使用情况
) S ?" k! x& {: p7 ]解决方法* o3 {" B+ ~4 ^) T" f% f
PS:保证业务能正常使用为第一原则解决问题
" O' L6 n8 s0 t1 G1 G
3 G- r, s1 j! x标记 Node 为不可调度4 b0 b# ~7 J/ o1 m
" Z8 N2 Q5 }. A( A3 F$ kubectl drain ${node-name}" S0 W. k; M5 x# M0 e% s! V3 Y
查找那个容器输出日志占用最大9 ` ]6 f6 S8 _/ O2 O* M/ j! W V
+ q4 J( T! E3 z7 X% u- F6 T4 R$ for name in $(docker ps -a | awk '{print $1}' | grep -v CONTAINER); do docker inspect $name | grep LogPath | awk '{print $NF}' | tr -d '",' |xargs du -sh;done5G /var/lib/docker/containers/d0e330944a074268a1f0998fd66ee73f584642352a2fe77304c1fa49b819893a/d0e330944a074268a1f0998fd66ee73f584642352a2fe77304c1fa49b819893a-json.log
, m; S. b- n& b, |, S& `清空容器日志文件
f. S1 z# d* J- |, j6 R0 U4 _ n5 P. |+ T
注意:如果需要重启 docker服务,首先腾出一点磁盘空间,不然重启 docker 会失败。不能直接使用 rm 删除日志文件,这样磁盘空间是不会释放的。不小心这样操作,那只能通过 systemctl restart docker 重启 Docker 服务释放磁盘空间,如果磁盘还是没有释放,可以通过 lsof | grep -i delete 查找已删除的文件进程,找到后直接 kill掉。- ]( \: m6 V& o" O+ @5 X
/ N0 o5 v' L. f* E: W' X
# 通过 echo 命令 清空日志文件$ echo > /var/lib/docker/containers/d0e330944a074268a1f0998fd66ee73f584642352a2fe77304c1fa49b819893a/d0e330944a074268a1f0998fd66ee73f584642352a2fe77304c1fa49b819893a-json.log9 e- ^2 ~* o+ P# C: B3 i
清理节点不用的 images,释放磁盘空间
+ F' h6 O3 D9 y- G. _( p
5 O1 L9 x" ~+ ?# 查看 docker 镜像$ docker images# 删除不用的镜像$ docker rmi ${images_id}4 l5 a( }4 s7 `9 }! R9 h
上面步骤操作完后(上面清理日志方法,可能对于收集日志程序会丢失一些日志,但一般情况能接受),可以选择驱赶节点上所有pod(kubectl drain ${node-name} )再优化Docker配置。也可以不驱赶节点上pod,在现基础上优化容器日志方法,优化配置后重启 Docker,这会导致节点上pod中断一会,如果前端反向代理具备重试机制一般不会影响业务正常访问。
/ e0 F( j. L a4 r) U5 {* N0 x* u0 i# W( H% w
优化完 Docker配置后,把节点加入到k8s集群中,正常服务。
. \5 H8 r8 r, h
, [# ~. g0 \# p* e M. P# 取消不可调度的标记$ kubectl uncordon ${node-name}
' ^* Q- D/ ?( S. i" P. U3 ]定位问题根本原因及解决思路
- f2 x1 x$ d! v$ v, S日志输出量大,导致磁盘写满5 O3 q6 k, K2 T# E; ?. s/ g. t
9 [8 f1 X4 i) ?, y减少日志输出,调整应用日志输出级别& p2 \ A$ d! k
增大磁盘空间
/ q9 T1 D$ i% N$ c1 \: J日志输出到统一日志收集中心+ |* z9 B2 c* f' v3 T* j' r
容器镜像占满磁盘! w. Q- z# n2 \
6 K4 U& j; _4 ]; {7 [) ^
配置k8s垃圾回收策略
& P4 i" @* @) R9 _节点运行 images 定时清理脚本
B% L5 f+ N% {+ g' V可写层量大导致磁盘写满: 优化程序逻辑,不写文件到容器内或控制写入文件的大小与数量
" G+ J0 N O7 U
4 s& _9 d9 i* Q! P3 R; z具体优化方法/ }% L3 V* O9 w- o1 V3 K+ E2 B% Q
配置 Docker日志轮转,数据目录不要存放在系统盘
1 J% ?3 d+ W5 i3 I7 ^8 r6 u2 U7 T& m9 _. {& ?5 |6 M/ a# }' m
$ vim /etc/docker/daemon.json{"registry-mirrors": ["https://4xr1qpsp.mirror.aliyuncs.com"], "graph": "/data/docker", "log-opts": {"max-size":"500m", "max-file":"3"}}" @* e9 D q# B; ?( j( W' t& O
配置解释:
3 P! M/ Z) k" M+ A2 {0 Q) P2 k I
配置完,重启 docker才能生效,日志轮转只对以后新创建的容器有效。% l: o$ [: A9 Y L k7 V) \
; P2 L6 t% w- n: [2 W2 pregistry-mirrors 镜像加速配置
; I2 B) F0 @; i! G2 ygraph 定义数据存储目录. Z" i7 U& B8 K" d/ G
max-size=500m 意味着一个容器日志大小上限是500M- [) V# B8 H2 \
max-file=3,意味着一个容器有三个日志,分别是id+.json、id+1.json、id+2.json
9 x9 ?# o5 H3 u1 x6 U/ t) F) J! o清理 docker images
* Q* m' s, u! x- B+ |
' S* d. Q5 A6 ?6 ^ n6 s" M7 t定时清理脚本
, M/ ?3 O e; L" ?3 S" z2 V
- l" a' d) A3 z4 _. g$ vim docker_delete_image.sh#!/usr/bin/env bashfor images_id in `docker images | grep 'harbor.example.com' | awk '{print $3}'`do docker rmi $images_iddone# 清理 imagesfor images_id_1 in `docker images | awk '$2 ~ ""{print $3}'`do docker rmi $images_id_1done$ X( i! k$ k# E0 {+ K
kubernetes 垃圾回收配置,这里不在细讲,具体参考官方配置文档 https://kubernetes.io/docs/conce ... garbage-collection/' j2 e0 H. h( j. h" B1 C. P3 u
|