本文目录导读:

在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
这个配置提供了完整的容器监控方案,可以根据实际需求调整指标和告警阈值。