Shell脚本如何配置容器监控指标

wen 实用脚本 1

本文目录导读:

Shell脚本如何配置容器监控指标

  1. 基础命令监控
  2. 使用cgroups直接获取指标
  3. 完整的监控脚本示例
  4. 配置为系统服务
  5. 与Prometheus集成
  6. 配置注意事项

在Shell脚本中配置容器监控指标,通常涉及以下步骤和工具:

基础命令监控

Docker容器监控

#!/bin/bash
# 容器CPU使用率
get_container_cpu() {
    local container_id=$1
    docker stats --no-stream --format "{{.CPUPerc}}" $container_id
}
# 容器内存使用
get_container_memory() {
    local container_id=$1
    docker stats --no-stream --format "{{.MemUsage}}" $container_id
}
# 容器网络I/O
get_container_network() {
    local container_id=$1
    docker stats --no-stream --format "{{.NetIO}}" $container_id
}
# 容器磁盘I/O
get_container_disk() {
    local container_id=$1
    docker stats --no-stream --format "{{.BlockIO}}" $container_id
}

使用cgroups直接获取指标

#!/bin/bash
# 获取容器CPU使用(纳秒)
get_container_cpu_usage() {
    local container_id=$1
    cat /sys/fs/cgroup/cpu/docker/$container_id/cpuacct.usage
}
# 获取容器内存使用
get_container_memory_usage() {
    local container_id=$1
    cat /sys/fs/cgroup/memory/docker/$container_id/memory.usage_in_bytes
}
# 获取容器内存限制
get_container_memory_limit() {
    local container_id=$1
    cat /sys/fs/cgroup/memory/docker/$container_id/memory.limit_in_bytes
}

完整的监控脚本示例

#!/bin/bash
# 配置参数
INTERVAL=5  # 采集间隔(秒)
LOG_DIR="/var/log/container-monitor"
METRICS_FILE="$LOG_DIR/container_metrics_$(date +%Y%m%d).log"
# 创建日志目录
mkdir -p $LOG_DIR
# 错误处理函数
handle_error() {
    echo "[ERROR] $(date): $1" >&2
}
# 采集单个容器指标
collect_container_metrics() {
    local container_id=$1
    # 获取容器名称
    local container_name=$(docker inspect --format '{{.Name}}' $container_id 2>/dev/null | sed 's/\///')
    if [ -z "$container_name" ]; then
        handle_error "Container $container_id not found"
        return 1
    fi
    # 采集各项指标
    local cpu_percent=$(docker stats --no-stream --format "{{.CPUPerc}}" $container_id 2>/dev/null)
    local mem_usage=$(docker stats --no-stream --format "{{.MemUsage}}" $container_id 2>/dev/null)
    local net_io=$(docker stats --no-stream --format "{{.NetIO}}" $container_id 2>/dev/null)
    local block_io=$(docker stats --no-stream --format "{{.BlockIO}}" $container_id 2>/dev/null)
    local pids=$(docker stats --no-stream --format "{{.PIDs}}" $container_id 2>/dev/null)
    # 格式化为JSON
    cat <<EOF
{
    "timestamp": "$(date +%s)",
    "container_id": "$container_id",
    "container_name": "$container_name",
    "metrics": {
        "cpu_percent": "$cpu_percent",
        "memory_usage": "$mem_usage",
        "network_io": "$net_io",
        "block_io": "$block_io",
        "pids": "$pids"
    }
}
EOF
}
# 监控所有运行中的容器
monitor_all_containers() {
    local containers=$(docker ps -q)
    echo "[" > $METRICS_FILE
    local first=true
    for container in $containers; do
        if [ "$first" = true ]; then
            first=false
        else
            echo "," >> $METRICS_FILE
        fi
        collect_container_metrics $container >> $METRICS_FILE
    done
    echo "]" >> $METRICS_FILE
}
# 发送指标到监控系统
send_metrics_to_prometheus() {
    local pushgateway_url="http://prometheus-pushgateway:9091"
    # 获取所有容器指标
    for container in $(docker ps -q); do
        local cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" $container | sed 's/%//')
        local mem=$(docker stats --no-stream --format "{{.MemUsage}}" $container | awk '{print $1}')
        # 推送指标
        cat <<EOF | curl -s -X POST --data-binary @- $pushgateway_url/metrics/job/container_monitoring/instance/$container
# HELP container_cpu_percent CPU usage percentage
# TYPE container_cpu_percent gauge
container_cpu_percent{container="$container"} $cpu
# HELP container_memory_usage_bytes Memory usage in bytes
# TYPE container_memory_usage_bytes gauge
container_memory_usage_bytes{container="$container"} $mem
EOF
    done
}
# 告警检查函数
check_alerts() {
    local threshold_cpu=80
    local threshold_mem=90
    for container in $(docker ps -q); do
        local cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" $container | sed 's/%//')
        local mem=$(docker stats --no-stream --format "{{.MemPerc}}" $container | sed 's/%//')
        if (( $(echo "$cpu > $threshold_cpu" | bc -l) )); then
            handle_error "ALERT: Container $container CPU usage > $threshold_cpu%"
        fi
        if (( $(echo "$mem > $threshold_mem" | bc -l) )); then
            handle_error "ALERT: Container $container Memory usage > $threshold_mem%"
        fi
    done
}
# 主循环
main() {
    echo "[INFO] Starting container monitoring..."
    while true; do
        # 采集并保存指标
        monitor_all_containers
        # 检查告警
        check_alerts
        # 发送到外部监控系统
        if [ "$SEND_TO_PROMETHEUS" = "true" ]; then
            send_metrics_to_prometheus
        fi
        sleep $INTERVAL
    done
}
# 运行主函数
main

配置为系统服务

# 创建systemd服务文件
cat > /etc/systemd/system/container-monitor.service <<EOF
[Unit]
Description=Container Monitor Service
After=docker.service
Requires=docker.service
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/container-monitor.sh
Restart=always
RestartSec=10
Environment="SEND_TO_PROMETHEUS=false"
[Install]
WantedBy=multi-user.target
EOF
# 启用并启动服务
systemctl daemon-reload
systemctl enable container-monitor
systemctl start container-monitor

与Prometheus集成

#!/bin/bash
# 创建metrics导出端点
start_metrics_exporter() {
    while true; do
        # 监听端口并提供metrics
        { echo -ne "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n"
          for container in $(docker ps -q); do
              local name=$(docker inspect --format '{{.Name}}' $container | sed 's/\///')
              local cpu=$(docker stats --no-stream --format "{{.CPUPerc}}" $container | sed 's/%//')
              local mem=$(docker stats --no-stream --format "{{.MemPerc}}" $container | sed 's/%//')
              echo "# HELP container_cpu_percent CPU usage percentage"
              echo "# TYPE container_cpu_percent gauge"
              echo "container_cpu_percent{container=\"$name\"} $cpu"
              echo "# HELP container_mem_percent Memory usage percentage"
              echo "# TYPE container_mem_percent gauge"
              echo "container_mem_percent{container=\"$name\"} $mem"
          done
        } | nc -l -p 9100 -q 1
    done
}

配置注意事项

性能优化

  • 避免频繁调用docker stats,适当增加采集间隔
  • 使用--no-stream参数只获取单次数据
  • 批量处理容器,避免逐个查询

安全配置

# 限制脚本权限
chmod 700 /usr/local/bin/container-monitor.sh
chown root:root /usr/local/bin/container-monitor.sh
# 使用非root用户运行
usermod -aG docker monitor-user

日志管理

# 添加日志轮转
cat > /etc/logrotate.d/container-monitor <<EOF
/var/log/container-monitor/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
}
EOF

这个配置提供了完整的容器监控方案,可以根据实际需求调整指标和告警阈值。

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