Shell脚本如何配置容器日志采集

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器日志采集

  1. 使用Filebeat采集容器日志
  2. 使用Fluentd采集容器日志
  3. 使用Logstash采集容器日志
  4. Docker日志驱动配置脚本
  5. 批量采集容器日志脚本
  6. 实时日志采集并转发到远程服务器
  7. 配置日志轮转
  8. 完整的容器日志采集方案
  9. 使用说明

配置容器日志采集的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

使用说明

  1. 选择适合的方案:根据你的日志系统选择对应的脚本
  2. 修改配置:根据实际环境修改服务器地址、端口等参数
  3. 执行脚本:以root权限执行脚本
  4. 验证采集:检查日志是否正常发送到目标系统

这些脚本涵盖了常见的容器日志采集场景,你可以根据实际需求调整配置。

抱歉,评论功能暂时关闭!