本文目录导读:

- 使用Filebeat采集容器日志
- 使用Fluentd采集容器日志
- 使用Logstash采集容器日志
- Docker日志驱动配置脚本
- 批量采集容器日志脚本
- 实时日志采集并转发到远程服务器
- 配置日志轮转
- 完整的容器日志采集方案
- 使用说明
配置容器日志采集的Shell脚本需要根据你的日志采集方案(如ELK、Loki、Fluentd、Filebeat等)来编写,以下是几种常见的配置方案及对应的Shell脚本示例。
使用Filebeat采集容器日志
#!/bin/bash
# 配置Filebeat采集Docker容器日志
# 变量定义
FILEBEAT_CONFIG="/etc/filebeat/filebeat.yml"
LOG_DIR="/var/log/containers"
DOCKER_LOG_DIR="/var/lib/docker/containers"
# 配置Filebeat
cat > $FILEBEAT_CONFIG << EOF
filebeat.inputs:
- type: container
paths:
- /var/lib/docker/containers/*/*.log
fields:
log_type: container
multiline:
pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
negate: true
match: after
output.elasticsearch:
hosts: ["localhost:9200"]
index: "docker-logs-%{+yyyy.MM.dd}"
setup.kibana:
host: "localhost:5601"
EOF
# 重启Filebeat服务
systemctl restart filebeat
systemctl enable filebeat
echo "Filebeat容器日志采集配置完成"
使用Fluentd采集容器日志
#!/bin/bash # 配置Fluentd采集Docker容器日志 cat > /etc/fluentd/fluent.conf << EOF <source> @type tail path /var/log/containers/*.log pos_file /var/log/fluentd-docker.pos tag kubernetes.* format json read_from_head true </source> <filter kubernetes.**> @type kubernetes_metadata </filter> <match kubernetes.**> @type elasticsearch host localhost port 9200 logstash_format true logstash_prefix fluentd flush_interval 5s </match> EOF # 使用Docker运行Fluentd docker run -d \ --name fluentd \ -v /var/log:/var/log \ -v /var/lib/docker/containers:/var/lib/docker/containers \ -v /etc/fluentd/fluent.conf:/fluentd/etc/fluent.conf \ -p 24224:24224 \ fluent/fluentd:v1.14 echo "Fluentd容器日志采集配置完成"
使用Logstash采集容器日志
#!/bin/bash
# 配置Logstash采集Docker容器日志
cat > /etc/logstash/conf.d/docker-logs.conf << EOF
input {
file {
path => "/var/lib/docker/containers/*/*.log"
type => "docker"
start_position => "beginning"
sincedb_path => "/dev/null"
}
}
filter {
json {
source => "message"
}
mutate {
add_field => {
"container_id" => "%{[?split(path,'/')][3]}"
}
}
date {
match => ["time", "ISO8601"]
target => "@timestamp"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "docker-logs-%{+YYYY.MM.dd}"
}
stdout {
codec => rubydebug
}
}
EOF
# 重启Logstash
systemctl restart logstash
echo "Logstash容器日志采集配置完成"
Docker日志驱动配置脚本
#!/bin/bash
# 配置Docker daemon使用json-file日志驱动
DOCKER_DAEMON_CONFIG="/etc/docker/daemon.json"
if [ ! -f "$DOCKER_DAEMON_CONFIG" ]; then
echo '{}' > $DOCKER_DAEMON_CONFIG
fi
# 配置日志驱动
cat > $DOCKER_DAEMON_CONFIG << EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"labels": "container_name",
"env": "SERVICE_NAME"
}
}
EOF
# 重启Docker服务
systemctl restart docker
echo "Docker日志驱动配置完成"
批量采集容器日志脚本
#!/bin/bash
# 批量采集所有运行中容器的日志
LOG_BASE_DIR="/var/log/container-logs"
DATE=$(date +%Y%m%d)
# 创建日志目录
mkdir -p $LOG_BASE_DIR/$DATE
# 获取所有运行中的容器
containers=$(docker ps --format "{{.Names}}" )
for container in $containers; do
# 获取容器ID
container_id=$(docker ps -q -f name=$container)
# 导出容器日志
docker logs $container_id > $LOG_BASE_DIR/$DATE/${container}_${container_id}.log 2>&1
# 获取日志大小
log_size=$(stat -c%s "$LOG_BASE_DIR/$DATE/${container}_${container_id}.log" 2>/dev/null)
echo "容器名称: $container"
echo "容器ID: $container_id"
echo "日志大小: $log_size bytes"
echo "日志路径: $LOG_BASE_DIR/$DATE/${container}_${container_id}.log"
echo "-----------------------------------"
done
# 压缩旧日志(保留7天)
find $LOG_BASE_DIR -type f -name "*.log" -mtime +7 -exec gzip {} \;
echo "日志采集完成,保存至: $LOG_BASE_DIR/$DATE/"
实时日志采集并转发到远程服务器
#!/bin/bash
# 实时采集容器日志并转发到远程服务器
REMOTE_HOST="192.168.1.100"
REMOTE_PORT="514" # syslog端口
REMOTE_USER="loguser"
# 创建日志转发函数
forward_logs() {
while true; do
# 获取最新的容器日志
docker logs --since 1m $(docker ps -q) 2>&1 | \
while read line; do
# 添加时间戳和容器信息
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
container_name=$(docker inspect $(docker ps -q) --format '{{.Name}}' | cut -d'/' -f2)
# 发送到远程syslog服务器
echo "$timestamp [$container_name] $line" | \
nc -w 1 $REMOTE_HOST $REMOTE_PORT || \
logger -p local0.info -t "container-logs" "$line"
done
sleep 5
done
}
# 检查网络连接
if ping -c 1 $REMOTE_HOST &> /dev/null; then
echo "远程服务器可达,开始转发日志..."
forward_logs &
echo "日志转发进程已启动"
else
echo "远程服务器不可达,日志保存在本地"
forward_logs > /var/log/local-container-logs.log &
fi
配置日志轮转
#!/bin/bash
# 配置容器日志轮转
cat > /etc/logrotate.d/docker-logs << EOF
/var/lib/docker/containers/*/*.log {
rotate 10
daily
compress
delaycompress
missingok
notifempty
copytruncate
size 100M
dateext
dateformat -%Y%m%d-%s
postrotate
docker exec $(docker ps -q) kill -USR1 1 2>/dev/null || true
endscript
}
EOF
# 测试logrotate配置
logrotate -d /etc/logrotate.d/docker-logs
# 手动执行一次日志轮转
logrotate -f /etc/logrotate.d/docker-logs
echo "日志轮转配置完成"
完整的容器日志采集方案
#!/bin/bash
# 完整的容器日志采集配置脚本
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# 日志函数
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# 检查依赖
check_dependencies() {
log_info "检查系统依赖..."
# 检查Docker
if ! command -v docker &> /dev/null; then
log_error "Docker未安装"
exit 1
fi
# 检查所需的工具
for cmd in docker systemctl curl; do
if ! command -v $cmd &> /dev/null; then
log_warn "$cmd 未安装"
fi
done
log_info "依赖检查完成"
}
# 创建日志目录结构
create_log_directories() {
log_info "创建日志目录结构..."
mkdir -p /var/log/containers
mkdir -p /etc/container-logs
mkdir -p /var/run/container-logs
# 设置权限
chmod 755 /var/log/containers
chmod 755 /etc/container-logs
log_info "日志目录创建完成"
}
# 配置Docker日志
configure_docker_logging() {
log_info "配置Docker日志..."
# 配置daemon.json
if [ -f /etc/docker/daemon.json ]; then
cp /etc/docker/daemon.json /etc/docker/daemon.json.bak
fi
cat > /etc/docker/daemon.json << EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"labels": "container_name,service",
"env": "SERVICE_NAME,ENVIRONMENT"
},
"storage-driver": "overlay2",
"experimental": true
}
EOF
# 重启Docker
systemctl restart docker
log_info "Docker日志配置完成"
}
# 配置Filebeat日志采集
configure_filebeat() {
log_info "配置Filebeat日志采集..."
local filebeat_config="/etc/filebeat/filebeat.yml"
cat > $filebeat_config << EOF
filebeat.inputs:
- type: container
paths:
- /var/lib/docker/containers/*/*.log
fields_under_root: true
fields:
environment: production
service: container-logs
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
- add_host_metadata:
netinfo.enabled: true
- decode_json_fields:
fields: ["message"]
target: "json"
overwrite_keys: false
output.elasticsearch:
hosts: ["localhost:9200", "elasticsearch2:9200"]
index: "docker-logs-%{+yyyy.MM.dd}"
pipeline: "docker-logs-pipeline"
timeout: 30
setup.template.settings:
index.number_of_shards: 3
index.number_of_replicas: 1
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/filebeat
name: filebeat.log
keepfiles: 7
EOF
# 启动Filebeat
if systemctl is-active filebeat &> /dev/null; then
systemctl restart filebeat
else
systemctl start filebeat
systemctl enable filebeat
fi
log_info "Filebeat配置完成"
}
# 配置日志监控告警
configure_log_monitoring() {
log_info "配置日志监控..."
cat > /etc/container-logs/monitor.sh << 'EOF'
#!/bin/bash
# 日志监控脚本
LOG_DIR="/var/lib/docker/containers"
ALERT_THRESHOLD=1000000000 # 1GB
check_log_sizes() {
for log_file in $(find $LOG_DIR -name "*.log"); do
size=$(stat -c%s "$log_file" 2>/dev/null || echo 0)
if [ $size -gt $ALERT_THRESHOLD ]; then
# 发送告警
echo "警告: 日志文件 $log_file 大小为 $(numfmt --to=iec $size)"
# 触发告警动作
trigger_alert "$log_file" "$size"
fi
done
}
trigger_alert() {
local log_file=$1
local size=$2
# 发送邮件告警
echo "日志文件 $log_file 大小异常 ($(numfmt --to=iec $size))" | \
mail -s "日志告警" admin@example.com
# 发送webhook
curl -X POST -H "Content-Type: application/json" \
-d "{\"log_file\":\"$log_file\",\"size\":\"$size\"}" \
http://alertmanager:9093/api/v1/alerts
}
# 添加crontab任务
(crontab -l 2>/dev/null; echo "*/10 * * * * /etc/container-logs/monitor.sh") | crontab -
# 执行一次检查
check_log_sizes
EOF
chmod +x /etc/container-logs/monitor.sh
log_info "日志监控配置完成"
}
# 主函数
main() {
echo "======================================"
echo "容器日志采集配置脚本"
echo "======================================"
check_dependencies
create_log_directories
configure_docker_logging
configure_filebeat
configure_log_monitoring
log_info "配置完成!"
log_info "请检查日志采集状态:"
echo " 1. 查看Docker日志: docker logs <container-name>"
echo " 2. 检查Filebeat状态: systemctl status filebeat"
echo " 3. 查看采集的日志: ls -la /var/log/containers/"
}
# 执行主函数
main
使用说明
- 选择适合的方案:根据你的日志系统选择对应的脚本
- 修改配置:根据实际环境修改服务器地址、端口等参数
- 执行脚本:以root权限执行脚本
- 验证采集:检查日志是否正常发送到目标系统
这些脚本涵盖了常见的容器日志采集场景,你可以根据实际需求调整配置。