Linux系统中Docker配置最佳实践:第3篇
·
本文为 Docker配置最佳实践系列第 3 篇,聚焦:
监控告警体系、生产环境检查清单、故障排查手册、备份与恢复。
监控告警体系
Prometheus + Grafana监控
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
ports:
- "9090:9090"
grafana:
image: grafana/grafana:latest
volumes:
- grafana-data:/var/lib/grafana
ports:
- "3000:3000"
cadvisor:
image: gcr.io/cadvisor/cadvisor:latest
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
ports:
- "8080:8080"
node-exporter:
image: prom/node-exporter:latest
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
ports:
- "9100:9100"
volumes:
prometheus-data:
grafana-data:
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'docker'
static_configs:
- targets: ['host.docker.internal:9323']
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
- job_name: 'node'
static_configs:
- targets: ['node-exporter:9100']
告警规则配置
groups:
- name: docker_alerts
interval: 30s
rules:
- alert: ContainerHighCPU
expr: rate(container_cpu_usage_seconds_total[5m]) > 0.8
for: 5m
- alert: ContainerHighMemory
expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.9
for: 5m
- alert: ContainerRestarting
expr: rate(container_restart_count[15m]) > 0
for: 5m
- alert: DiskSpaceHigh
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
for: 5m
- alert: DockerDaemonDown
expr: up{job="docker"} == 0
for: 1m
健康检查配置
FROM nginx:latest
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost/ || exit 1
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 3s
retries: 3
docker ps --format "table {{.Names}}\t{{.Status}}"
docker inspect --format='{{json .State.Health}}' container_name | jq
自定义监控脚本
#!/bin/bash
# /usr/local/bin/docker-monitor.sh
check_containers() {
local unhealthy=$(docker ps --filter "health=unhealthy" --format "{{.Names}}")
if [ -n "$unhealthy" ]; then
echo "警告:以下容器不健康:"
echo "$unhealthy"
fi
}
check_resources() {
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemPerc}}" | \
awk 'NR>1 {
cpu=$2; mem=$3;
gsub(/%/, "", cpu); gsub(/%/, "", mem);
if (cpu > 80 || mem > 90) print "警告: "$1" CPU:"cpu"% 内存:"mem"%"
}'
}
check_disk() {
local usage=$(df /var/lib/docker | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $usage -gt 80 ]; then
echo "警告:Docker磁盘使用率 ${usage}%"
docker system prune -f
fi
}
while true; do
check_containers
check_resources
check_disk
sleep 60
done
生产环境检查清单
部署前检查
x内核版本满足要求
x开启IP转发:net.ipv4.ip_forward=1
x配置合适ulimit
x磁盘空间至少50GB
xNTP时间同步
xdaemon.json配置完整
x镜像加速与日志轮转已配置
x存储驱动overlay2、live-restore开启
x自定义网络与防火墙规则完善
x容器非root运行、漏洞扫描完成
运行时检查
#!/bin/bash
# /usr/local/bin/docker-daily-check.sh
echo "========== Docker每日健康检查 =========="
echo "检查时间: $(date)"
systemctl is-active docker && echo "✓ Docker服务运行正常" || echo "✗ Docker服务异常"
total=$(docker ps -a | wc -l)
running=$(docker ps | wc -l)
echo "总容器数: $((total-1))"
echo "运行中: $((running-1))"
docker system df
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemPerc}}" | head -6
journalctl -u docker --since "24 hours ago" | grep -i error | tail -5
echo "========== 检查完成 =========="
0 9 * * * /usr/local/bin/docker-daily-check.sh | mail -s "Docker每日检查报告" admin@example.com
故障排查手册
常见问题快速诊断
# 容器无法启动
docker logs container_name
docker inspect container_name
netstat -tlnp | grep <端口>
docker stats container_name
docker run -it --entrypoint /bin/sh image_name
# 容器频繁重启
docker inspect --format='{{.RestartCount}}' container_name
docker inspect --format='{{.State.ExitCode}}' container_name
dmesg | grep -i "out of memory"
docker inspect --format='{{json .State.Health}}' container_name | jq
# 网络不通
docker inspect --format='{{.NetworkSettings.IPAddress}}' container_name
docker network inspect bridge
docker exec container1 ping container2
docker exec container_name cat /etc/resolv.conf
iptables -t nat -L -n | grep DOCKER
systemctl status firewalld
# 磁盘空间不足
docker system df -v
docker container prune -f
docker image prune -a -f
docker volume prune -f
docker builder prune -a -f
docker system prune -a --volumes -f
性能问题排查
# CPU
docker stats --no-stream | sort -k3 -h -r | head -5
docker exec -it container_name top
docker exec container_name ps aux --forest
# 内存
watch -n 1 'docker stats --no-stream container_name'
docker exec container_name cat /proc/meminfo
docker exec container_name jmap -heap <PID>
docker exec container_name jmap -dump:format=b,file=/tmp/heap.bin <PID>
# IO
docker stats --no-stream --format "table {{.Container}}\t{{.BlockIO}}"
docker exec container_name iostat -x 1
备份与恢复
容器备份策略
# 导出容器为镜像
docker commit container_name backup_image:v1
docker save -o backup_image_v1.tar backup_image:v1
gzip backup_image_v1.tar
docker load -i backup_image_v1.tar.gz
# 备份卷
docker run --rm \
-v volume_name:/source \
-v $(pwd):/backup \
alpine tar czf /backup/volume_backup.tar.gz -C /source .
# 恢复卷
docker run --rm \
-v volume_name:/target \
-v $(pwd):/backup \
alpine tar xzf /backup/volume_backup.tar.gz -C /target
#!/bin/bash
# /usr/local/bin/docker-backup.sh
BACKUP_DIR="/backup/docker"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR/$DATE
docker images --format "{{.Repository}}:{{.Tag}}" > $BACKUP_DIR/$DATE/images.txt
docker ps -a --format "{{.Names}}" | while read container; do
docker inspect $container > $BACKUP_DIR/$DATE/${container}_config.json
done
docker volume ls --format "{{.Name}}" | while read volume; do
docker run --rm -v $volume:/source -v $BACKUP_DIR/$DATE:/backup alpine \
tar czf /backup/${volume}.tar.gz -C /source .
done
cp /etc/docker/daemon.json $BACKUP_DIR/$DATE/
cd $BACKUP_DIR
tar czf docker_backup_$DATE.tar.gz $DATE
rm -rf $DATE
find $BACKUP_DIR -name "docker_backup_*.tar.gz" -mtime +7 -delete
echo "备份完成: $BACKUP_DIR/docker_backup_$DATE.tar.gz"
灾难恢复演练
#!/bin/bash
BACKUP_FILE=$1
if [ -z "$BACKUP_FILE" ]; then
echo "用法: $0 <备份文件>"
exit 1
fi
tar xzf $BACKUP_FILE
BACKUP_DIR=$(basename $BACKUP_FILE .tar.gz | sed 's/docker_backup_//')
cp $BACKUP_DIR/daemon.json /etc/docker/
systemctl restart docker
cat $BACKUP_DIR/images.txt | while read image; do
docker pull $image
done
for volume_backup in $BACKUP_DIR/*.tar.gz; do
volume_name=$(basename $volume_backup .tar.gz)
docker volume create $volume_name
docker run --rm -v $volume_name:/target -v $(pwd)/$BACKUP_DIR:/backup alpine \
tar xzf /backup/$(basename $volume_backup) -C /target
done
echo "请根据配置文件手动重新创建容器"
ls $BACKUP_DIR/*_config.json
总结
核心原则:
- 安全第一
- 性能优化
- 可观测性
- 高可用性
- 自动化
更详细内容
个人博客:https://itinstall.dev
公众号:IT安装手册
更多推荐


所有评论(0)