本文目录导读:

在Shell脚本中配置容器日志轮转主要有以下几种方法:
Docker内置日志轮转配置
创建日志轮转配置文件
#!/bin/bash
# 创建Docker daemon配置文件
cat > /etc/docker/daemon.json <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
# 重启Docker服务使配置生效
systemctl restart docker
针对单个容器的日志配置
#!/bin/bash # 运行容器时指定日志轮转参数 docker run -d \ --name myapp \ --log-opt max-size=10m \ --log-opt max-file=3 \ nginx:latest
使用logrotate工具
安装logrotate
#!/bin/bash
# 检查并安装logrotate
if ! command -v logrotate &> /dev/null; then
apt-get update && apt-get install -y logrotate
# 或 yum install -y logrotate
fi
配置logrotate规则
#!/bin/bash
# 创建Docker容器日志轮转配置
cat > /etc/logrotate.d/docker-containers <<EOF
# Docker容器日志轮转配置
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
missingok
delaycompress
copytruncate
notifempty
maxsize 100M
dateext
dateformat -%Y%m%d
postrotate
# 触发Docker重新打开日志文件
docker container ls -q | xargs -I {} docker inspect {} --format '{{.LogPath}}' | while read logfile; do
if [ -f "$logfile" ]; then
kill -USR1 $(docker inspect $(docker ps -q) --format '{{.State.Pid}}' 2>/dev/null) 2>/dev/null
fi
done
endscript
}
EOF
# 立即测试轮转配置
logrotate -vf /etc/logrotate.d/docker-containers
自定义日志轮转脚本
基础日志轮转脚本
#!/bin/bash
# 日志轮转函数
rotate_container_logs() {
local CONTAINER_NAME=$1
local MAX_SIZE=${2:-100M}
local MAX_FILES=${3:-5}
echo "开始轮转容器日志: $CONTAINER_NAME"
# 获取容器日志路径
LOG_PATH=$(docker inspect --format='{{.LogPath}}' "$CONTAINER_NAME" 2>/dev/null)
if [ -z "$LOG_PATH" ]; then
echo "错误: 找不到容器 $CONTAINER_NAME 的日志路径"
return 1
fi
# 检查日志文件大小
CURRENT_SIZE=$(stat -c%s "$LOG_PATH" 2>/dev/null || echo 0)
MAX_BYTES=$(numfmt --from=iec "$MAX_SIZE" 2>/dev/null || echo 104857600)
if [ "$CURRENT_SIZE" -gt "$MAX_BYTES" ]; then
echo "当前日志大小: $(numfmt --to=iec $CURRENT_SIZE)"
# 轮转旧日志
for i in $(seq $((MAX_FILES-1)) -1 1); do
if [ -f "${LOG_PATH}.${i}" ]; then
mv "${LOG_PATH}.${i}" "${LOG_PATH}.$((i+1))"
fi
done
# 重命名当前日志
if [ -f "$LOG_PATH" ]; then
cp "$LOG_PATH" "${LOG_PATH}.1"
: > "$LOG_PATH"
fi
# 通知Docker重新打开日志文件
docker kill --signal=USR1 "$CONTAINER_NAME" 2>/dev/null
echo "日志轮转完成"
else
echo "日志大小未超过限制,跳过轮转"
fi
}
# 使用示例
rotate_container_logs "myapp" "50M" 3
高级日志管理脚本
#!/bin/bash
# 容器日志管理器
CONTAINER_LOG_MANAGER() {
local ACTION=$1
case "$ACTION" in
setup)
# 设置定时任务
(crontab -l 2>/dev/null; echo "*/30 * * * * /usr/local/bin/container-log-rotate.sh rotate") | crontab -
echo "定时任务已设置"
;;
rotate)
# 遍历所有运行容器
docker ps --format '{{.Names}}' | while read container; do
if [ -n "$container" ]; then
echo "处理容器: $container"
rotate_container_logs "$container" "100M" 5
fi
done
;;
cleanup)
# 清理超过7天的压缩日志
find /var/lib/docker/containers/ -name "*.log.*.gz" -mtime +7 -delete
echo "清理完成"
;;
status)
# 显示日志状态
echo "=== 容器日志状态 ==="
docker ps --format 'table {{.Names}}\t{{.Status}}' | while read line; do
container=$(echo "$line" | awk '{print $1}')
if [ "$container" != "NAMES" ]; then
log_path=$(docker inspect --format='{{.LogPath}}' "$container" 2>/dev/null)
if [ -f "$log_path" ]; then
size=$(stat -c%s "$log_path" 2>/dev/null || echo 0)
echo "$container: $(numfmt --to=iec $size)"
fi
fi
done
;;
*)
echo "用法: $0 {setup|rotate|cleanup|status}"
exit 1
;;
esac
}
# 主程序入口
if [ "${BASH_SOURCE[0]}" -ef "$0" ]; then
CONTAINER_LOG_MANAGER "$@"
fi
配置环境变量方式
#!/bin/bash
# 通过Docker环境变量配置(适用于使用特定日志驱动的容器)
docker run -d \
--name myapp \
-e "LOG_MAX_SIZE=10m" \
-e "LOG_MAX_FILE=3" \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx:latest
# 在docker-compose.yml中配置
cat > docker-compose.yml <<EOF
version: '3.8'
services:
web:
image: nginx:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
EOF
# 启动服务
docker-compose up -d
Docker Compose批量配置
#!/bin/bash
# 批量配置所有容器的日志轮转
configure_all_containers_logging() {
local MAX_SIZE=${1:-50m}
local MAX_FILE=${2:-3}
# 更新所有容器的日志配置
docker ps -q | while read container_id; do
echo "更新容器日志配置: $container_id"
docker update \
--log-opt max-size=$MAX_SIZE \
--log-opt max-file=$MAX_FILE \
$container_id
done
}
# 使用示例
configure_all_containers_logging "10m" 3
监控和告警脚本
#!/bin/bash
# 日志大小监控脚本
check_container_logs() {
local WARN_SIZE=${1:-500M}
local CRIT_SIZE=${2:-1G}
local WARN_BYTES=$(numfmt --from=iec "$WARN_SIZE")
local CRIT_BYTES=$(numfmt --from=iec "$CRIT_SIZE")
echo "开始检查容器日志大小..."
docker ps --format '{{.Names}}' | while read container; do
log_path=$(docker inspect --format='{{.LogPath}}' "$container" 2>/dev/null)
if [ -f "$log_path" ]; then
current_size=$(stat -c%s "$log_path")
if [ "$current_size" -gt "$CRIT_BYTES" ]; then
echo "严重警告: 容器 $container 日志大小 $(numfmt --to=iec $current_size) 超过临界值 $CRIT_SIZE"
# 可以在这里添加发送告警的代码
elif [ "$current_size" -gt "$WARN_BYTES" ]; then
echo "警告: 容器 $container 日志大小 $(numfmt --to=iec $current_size) 超过预警值 $WARN_SIZE"
fi
fi
done
}
# 使用示例
check_container_logs "200M" "500M"
推荐的最佳实践
- 优先使用Docker内置配置:效率最高,资源消耗最小
- 结合logrotate:当需要更复杂的轮转策略时
- 设置合理的限制:建议
max-size=10m到100m,max-file=3到7 - 定期检查:添加监控告警,防止日志爆满
- 使用copytruncate:避免需要重启容器
选择哪种方式取决于你的具体需求,推荐优先使用Docker内置的日志轮转功能。