Docker容器日志占用空間過大的解決方式
1. 問題描述
當(dāng)我們嘗試查看特定 Docker 容器的日志時,通常會使用 docker logs <容器名稱>
命令。然而,有時候會發(fā)現(xiàn)控制臺持續(xù)輸出日志信息,持續(xù)時間可能相當(dāng)長,直到最終打印完成。這種現(xiàn)象往往源自對 Docker 容器日志長時間未進行處理,導(dǎo)致日志積累過多,占用了系統(tǒng)磁盤空間。因此,為了釋放磁盤空間并優(yōu)化系統(tǒng)性能,我們可以采取一些簡單而有效的方法來處理這些龐大的日志文件。
2. docker日志處理機制
需要處理問題,那我們肯定要先了解docker的日志處理機制,了解了基本的機制,能夠幫助我們更好的理解問題并解決問題。
2.1 日志查看
docker logs <容器名稱>
可以查看docker容器的輸出日志,但是這里的日志主要包含標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯誤輸出,一些容器可能會把日志輸出到某個日志文件中,比如tomcat,這樣使用docker logs <容器名稱>
命令是無法查看的。
注意docker logs
命令查看的是容器的全部日志,當(dāng)日志量很大時會對容器的運行造成影響,可以通過docker logs --tail N container name
查看最新N行的數(shù)據(jù),N是一個整數(shù)。
2.2 處理機制
當(dāng)我們啟動一個docker容器時,實際上時作為docker daemon的一個子進程運行的,docker daemon可以拿到容器里進程的標(biāo)準(zhǔn)輸出與標(biāo)準(zhǔn)錯誤輸出,并通過docker的log driver模塊來處理,大致圖示如下:
上面圖中所列舉的就是所支持的Log Driver:
- none:容器沒有日志,
docker logs
不輸出任何內(nèi)容 - local:日志以自定義格式存儲
- json-file:日志以json格式存儲,默認(rèn)的Log Driver
- syslog:將日志寫入syslog。syslog守護程序必須在主機上運行
- journald:將日志寫入journald。journald守護程序必須在主機上運行
- gelf:將日志寫入Graylog Extended Log Format端點,如Graylog或Logstash
- fluentd:將日志寫入fluentd。fluentd守護程序必須在主機上運行
- awslogs:將日志寫入Amazon CloudWatch Logs
- splunk:通過HTTP Event Collector將日志寫入splunk
- etwlogs:將日志作為ETW(Event Tracing for Windows)事件寫入。只在Windows平臺可用
- gcplogs:將日志寫入Google Cloud Platform Logging
- logentries:將日志寫入Rapid7 Logentries
可以使用命令docker info | grep "Logging Driver"
2.3 默認(rèn)的json-file
json-file Log Driver是Docker默認(rèn)啟用的Driver,將容器的STDOUT/STDERR輸出以json的格式寫到宿主機的磁盤,日志文件路徑為 /var/lib/docker/containers/{container_id}/{container_id}-json.log
格式是這樣的:
json-file將每一行日志封裝到一個json字符串中。
json-file支持如下配置:
- max-size:單個日志文件的最大大小,單位可以為k、m、g,默認(rèn)是-1,表示日志文件可以無限大。
- max-file:最多可以存多少個日志文件,默認(rèn)數(shù)量是1,當(dāng)默認(rèn)數(shù)量大于1時,每個日志文件達(dá)到最大存儲大小,且數(shù)量達(dá)到設(shè)置數(shù)量,產(chǎn)生新日志時會刪除掉最舊的一個日志文件。
- labels:指定日志所使用到的標(biāo)簽,使用逗號分割。比如traceId,message兩個標(biāo)簽。
- env:指定與日志相關(guān)的環(huán)境變量,使用逗號分割
- env-rejex:一個正則表達(dá)式來匹配與日志相關(guān)的環(huán)境變量
- compress:是否壓縮日志文件
3. 如何解決?
3.1 查看日志大小
我們可以通過如下腳本獲取當(dāng)前所有容器的日志大小,這里時使用docker默認(rèn)的json-file的形式:
#!/bin/sh echo "======== docker containers logs file size ========" logs=$(find /var/lib/docker/containers/ -name *-json.log) for log in $logs do ls -lh $log done
執(zhí)行腳本:
json-file的命令開頭的一小串字符時容器的id。
例如我有一個docker容器id是2de6f164ee11,我們可以適當(dāng)修改shell腳本,查看某一個容器的日志大小。
logs=$(find /var/lib/docker/containers/ -name *-json.log | grep "2de6f164ee11")
3.2 刪除日志
如果docker容器正在運行,使用rm -rf的方式刪除日志后,磁盤空間并沒有釋放。原因是在Linux或者Unix系統(tǒng)中,通過rm -rf或者文件管理器刪除文件,將會從文件系統(tǒng)的目錄結(jié)構(gòu)上解除鏈接(unlink)。如果文件是被打開的(有一個進程正在使用),那么進程將仍然可以讀取該文件,磁盤空間也一直被占用。
正確的方式是直接使用命令改寫日志文件。
cat /dev/null > *-json.log
cat
: 是一個命令,用于連接文件并打印它們的內(nèi)容到標(biāo)準(zhǔn)輸出(通常是終端)。/dev/null
: 是一個特殊的設(shè)備文件,向它寫入的內(nèi)容會被丟棄,讀取它將會立即返回結(jié)束符。>
: 是重定向操作符,將命令的輸出重定向到文件。*-json.log
: 是通配符,用于匹配當(dāng)前目錄中所有以-json.log
結(jié)尾的文件。
可以使用如下腳本,直接處理所有的日志文件:
#!/bin/sh echo "======== start clean docker containers logs ========" logs=$(find /var/lib/docker/containers/ -name *-json.log) for log in $logs do echo "clean logs : $log" cat /dev/null > $log done echo "======== end clean docker containers logs ========"
注意,雖然使用這種方式可以刪除日志,釋放磁盤,但是過一段時間后,日志又會漲回來,所以要從根本上解決問題,只需要添加兩個參數(shù)。沒錯!就是上面所講到的max-size和max-file。
3.3 治本操作
在運行docker容器時,添加上max-size和max-file可以解決日志一直增長的問題。
docker run -it --log-opt max-size=10m --log-opt max-file=3 alpine ash
這段啟動命令表示總共有三個日志文件,每個文件的最大大小時10m,這樣就能將該容器的日志大小控制在最大30m。
4. 總結(jié)
在運行容器時,我們就應(yīng)該優(yōu)先考慮如何處理日志的問題,后面不必為容器運行后所產(chǎn)生的巨大日志而手足無措。
當(dāng)然需要刪除無用日志可以通過3.1,3.2的操作完成,建議在運行容器的時候加上max-size和max-file參數(shù)或者至少加上max-size參數(shù)。
以上就是Docker容器日志占用空間過大的解決方式的詳細(xì)內(nèi)容,更多關(guān)于Docker日志占用空間過大的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
docker搭建lnmp環(huán)境的實現(xiàn)步驟
DNMP(Docker + Nginx + MySQL + PHP7/5 + Redis)是一款全功能的LNMP一鍵安裝程序,本文就來介紹一下docker搭建lnmp環(huán)境的實現(xiàn)步驟,具有一定的參考價值,感興趣的可以了解一下2024-07-07寫給前端的nginx配置指南基于docker所有配置秒級運行(最新講解)
這篇文章主要介紹了寫給前端的nginx配置指南基于docker所有配置秒級運行,通過?docker?高效學(xué)習(xí)?nginx?配置,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06docker安裝Jenkins配置Gitee SSH密鑰踩坑解決
這篇文章主要為大家介紹了docker安裝Jenkins配置Gitee SSH密鑰踩坑解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08Docker復(fù)制現(xiàn)有容器的實現(xiàn)方法
在使用Docker進行應(yīng)用開發(fā)和部署時,我們經(jīng)常需要基于現(xiàn)有的容器創(chuàng)建相似的環(huán)境,本文主要介紹了Docker復(fù)制現(xiàn)有容器的實現(xiàn)方法,具有一定的參考價值,感興趣的可以了解一下2024-03-03centos搭建部署docker環(huán)境的詳細(xì)步驟
Docker 將程序與程序的運行環(huán)境打包在一起,從而避免了復(fù)雜的環(huán)境配置,下面這篇文章主要給大家介紹了關(guān)于centos搭建部署docker環(huán)境的詳細(xì)步驟,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07Docker將鏡像文件發(fā)布到阿里云的詳細(xì)過程
這篇文章主要介紹了Docker將鏡像文件發(fā)布到阿里云的操作,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05