1. Shell与Docker自动化概述
在DevOps和云原生技术栈中,Shell脚本与Docker的组合堪称黄金搭档。我曾在多个分布式系统部署项目中,通过Shell脚本将Docker的容器管理、镜像构建等操作自动化,将原本需要数小时的人工操作压缩到几分钟内完成。这种自动化方案特别适合需要频繁部署的环境,比如持续集成流水线、多节点集群管理等场景。
Shell作为Linux系统的原生脚本语言,具有直接调用系统命令、处理文本流、条件判断等核心能力。而Docker通过容器化技术实现了应用运行环境的标准化封装。当二者结合时,Shell脚本就成为了操控Docker引擎的"神经中枢",能够以编程方式完成:
- 容器的生命周期管理(创建/启动/停止/删除)
- 镜像的构建、推送和版本控制
- 多容器应用的编排部署
- 批量节点的配置管理
这种组合的优势在于:
- 无额外依赖:只需基础Linux环境即可运行
- 灵活可控:可以精细控制每个操作步骤
- 可复用性强:脚本一次编写,多处执行
2. 基础环境准备
2.1 Docker安装与配置
虽然不同Linux发行版的安装命令略有差异,但通过Shell脚本可以自动完成环境检测和适配。以下是一个兼容CentOS/Ubuntu的安装脚本片段:
bash复制#!/bin/bash
# 检测系统类型
if [ -f /etc/redhat-release ]; then
# CentOS/RHEL
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
elif [ -f /etc/lsb-release ]; then
# Ubuntu
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
fi
# 启动Docker服务
systemctl enable --now docker
# 验证安装
docker run hello-world
注意:生产环境中建议固定Docker版本而非使用latest,避免版本升级带来的兼容性问题。
2.2 Shell脚本基础框架
一个健壮的Docker管理脚本应该包含以下基本结构:
bash复制#!/bin/bash
# 配置区 - 定义全局变量
DOCKER_REGISTRY="registry.example.com"
IMAGE_NAME="myapp"
TAG="v1.0"
CONTAINER_NAME="myapp_container"
PORT_MAPPING="8080:80"
# 函数区 - 定义可复用的操作
check_docker_install() {
if ! command -v docker &> /dev/null; then
echo "Docker未安装,正在自动安装..."
# 调用安装函数
install_docker
fi
}
# 主逻辑 - 脚本入口
main() {
check_docker_install
# 其他操作...
}
# 执行主函数
main "$@"
这种结构化的编写方式使得脚本更易维护和扩展。
3. 容器生命周期管理
3.1 容器启停控制
通过Shell封装Docker命令可以实现更智能的容器管理。下面是一个带状态检查的容器控制脚本:
bash复制#!/bin/bash
CONTAINER_NAME="myapp_prod"
case "$1" in
start)
if [ "$(docker inspect -f '{{.State.Running}}' $CONTAINER_NAME 2>/dev/null)" == "true" ]; then
echo "容器已在运行中"
else
docker run -d --name $CONTAINER_NAME \
-p 8080:80 \
-v /data/app:/app \
myapp:latest
echo "容器已启动"
fi
;;
stop)
if [ "$(docker inspect -f '{{.State.Running}}' $CONTAINER_NAME 2>/dev/null)" == "true" ]; then
docker stop $CONTAINER_NAME
echo "容器已停止"
else
echo "容器未运行"
fi
;;
restart)
$0 stop
sleep 2
$0 start
;;
status)
docker inspect -f '{{.State.Status}}' $CONTAINER_NAME 2>/dev/null || echo "容器不存在"
;;
*)
echo "用法: $0 {start|stop|restart|status}"
exit 1
esac
这个脚本的特点:
- 使用case语句实现子命令分发
- 每次操作前检查容器当前状态
- 支持start/stop/restart/status四种操作
3.2 容器批量操作
当需要管理多个容器时,可以使用数组结合循环的方式:
bash复制#!/bin/bash
CONTAINERS=("web1" "web2" "web3" "db")
batch_operation() {
operation=$1
for container in "${CONTAINERS[@]}"; do
echo "正在处理容器 $container"
case $operation in
start)
docker start $container || docker run -d --name $container ${container}_image
;;
stop)
docker stop $container
;;
# 其他操作...
esac
done
}
batch_operation $1
4. 镜像构建自动化
4.1 基础镜像构建
镜像构建的自动化可以通过Shell脚本与Dockerfile配合实现。以下是一个典型的构建流程:
bash复制#!/bin/bash
VERSION="1.2.0"
IMAGE_NAME="myapp"
DOCKERFILE="Dockerfile.prod"
# 构建前清理旧镜像
docker rmi $IMAGE_NAME:$VERSION 2>/dev/null
# 执行构建
docker build -t $IMAGE_NAME:$VERSION -f $DOCKERFILE .
# 打标签
docker tag $IMAGE_NAME:$VERSION $IMAGE_NAME:latest
# 推送到仓库
docker push $IMAGE_NAME:$VERSION
docker push $IMAGE_NAME:latest
对应的Dockerfile.prod示例:
dockerfile复制FROM alpine:3.14
# 安装依赖
RUN apk add --no-cache python3 py3-pip nginx
# 复制应用代码
COPY . /app
WORKDIR /app
# 安装Python依赖
RUN pip install -r requirements.txt
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
4.2 多架构镜像构建
在跨平台场景下,可以使用buildx构建多架构镜像:
bash复制#!/bin/bash
# 创建构建器实例
docker buildx create --use --name multiarch-builder
# 启动构建器
docker buildx inspect --bootstrap
# 构建并推送多架构镜像
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t username/myapp:latest \
-t username/myapp:v1.0 \
--push .
5. 批量部署方案
5.1 单机多容器部署
对于需要在单台主机上部署多个关联容器的场景,可以使用如下脚本:
bash复制#!/bin/bash
# 定义网络
NETWORK_NAME="myapp_net"
docker network create -d bridge $NETWORK_NAME 2>/dev/null
# 启动数据库容器
docker run -d --name mysql \
--network $NETWORK_NAME \
-e MYSQL_ROOT_PASSWORD=secret \
-v /data/mysql:/var/lib/mysql \
mysql:5.7
# 启动应用容器
docker run -d --name myapp \
--network $NETWORK_NAME \
-p 8080:80 \
-e DB_HOST=mysql \
myapp:latest
# 启动监控容器
docker run -d --name prometheus \
--network $NETWORK_NAME \
-p 9090:9090 \
-v ./prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
5.2 多节点集群部署
对于跨多台主机的部署,可以结合SSH和Docker Context实现:
bash复制#!/bin/bash
# 节点列表
NODES=("node1.example.com" "node2.example.com" "node3.example.com")
# 镜像准备
docker build -t myapp:latest .
docker save myapp:latest > myapp.tar
# 批量部署
for node in "${NODES[@]}"; do
echo "正在部署到 $node"
# 传输镜像
scp myapp.tar $node:/tmp/
# 远程执行命令
ssh $node << EOF
docker load -i /tmp/myapp.tar
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp -p 8080:80 myapp:latest
rm /tmp/myapp.tar
EOF
done
# 清理本地临时文件
rm myapp.tar
6. 高级技巧与最佳实践
6.1 健康检查与自动恢复
在生产环境中,应该为容器添加健康检查并实现故障自动恢复:
bash复制#!/bin/bash
CONTAINER_NAME="myapp_prod"
# 定义健康检查
docker run -d --name $CONTAINER_NAME \
--health-cmd="curl -f http://localhost/health || exit 1" \
--health-interval=30s \
--health-retries=3 \
myapp:latest
# 监控脚本
while true; do
status=$(docker inspect -f '{{.State.Health.Status}}' $CONTAINER_NAME)
if [ "$status" != "healthy" ]; then
echo "$(date) - 容器状态异常,正在恢复..."
docker restart $CONTAINER_NAME
fi
sleep 60
done
6.2 日志收集与轮转
合理的日志管理方案可以避免磁盘空间被占满:
bash复制#!/bin/bash
# 启动容器时配置日志选项
docker run -d --name myapp \
--log-driver=json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
myapp:latest
# 日志收集脚本
LOGS_DIR="/var/log/containers"
mkdir -p $LOGS_DIR
docker logs -f myapp > "$LOGS_DIR/myapp_$(date +%Y%m%d).log" 2>&1 &
6.3 资源限制与监控
通过Shell脚本可以批量配置容器的资源限制:
bash复制#!/bin/bash
# 为所有运行中的容器设置CPU和内存限制
for container in $(docker ps -q); do
docker update \
--cpus 1 \
--memory 512m \
--memory-swap 1g \
$container
done
# 监控资源使用情况
watch -n 5 "docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'"
7. 安全加固措施
7.1 非root用户运行
在Dockerfile和启动脚本中强制使用非root用户:
bash复制#!/bin/bash
# Dockerfile中应包含:
# RUN groupadd -r appuser && useradd -r -g appuser appuser
# USER appuser
docker run -d --name myapp \
--user 1000:1000 \
-v /data/app:/app:ro \
myapp:latest
7.2 敏感信息管理
使用Docker secret或环境变量文件管理敏感信息:
bash复制#!/bin/bash
# 创建环境变量文件
cat > .env << EOF
DB_PASSWORD=secret123
API_KEY=abcd1234
EOF
# 安全启动容器
docker run -d --name myapp \
--env-file .env \
myapp:latest
# 使用后立即清理
shred -u .env
8. 实际案例:Web应用全流程部署
下面通过一个真实案例展示从代码提交到生产部署的完整自动化流程:
bash复制#!/bin/bash
# 1. 代码检出
git clone https://github.com/example/myapp.git
cd myapp
# 2. 运行测试
docker-compose -f docker-compose.test.yml up --build --abort-on-container-exit
TEST_RESULT=$?
docker-compose -f docker-compose.test.yml down
if [ $TEST_RESULT -ne 0 ]; then
echo "测试失败,部署中止"
exit 1
fi
# 3. 构建生产镜像
VERSION=$(git rev-parse --short HEAD)
docker build -t myapp:$VERSION -f Dockerfile.prod .
docker tag myapp:$VERSION myapp:latest
# 4. 推送到镜像仓库
docker login -u $DOCKER_USER -p $DOCKER_PASS registry.example.com
docker tag myapp:$VERSION registry.example.com/myapp:$VERSION
docker push registry.example.com/myapp:$VERSION
# 5. 生产环境部署
ssh prod-server << EOF
docker pull registry.example.com/myapp:$VERSION
docker stop myapp || true
docker rm myapp || true
docker run -d --name myapp \
-p 443:8443 \
-v /etc/ssl:/etc/ssl:ro \
registry.example.com/myapp:$VERSION
EOF
# 6. 清理旧镜像
ssh prod-server "docker image prune -f --filter 'until=24h'"
这个脚本实现了:
- 自动代码检出
- 在隔离环境中运行测试
- 基于Git提交哈希构建版本化镜像
- 安全推送镜像到私有仓库
- 零停机部署到生产环境
- 自动清理旧镜像
9. 错误处理与调试技巧
9.1 完善的错误处理
健壮的脚本应该包含完善的错误处理机制:
bash复制#!/bin/bash
set -euo pipefail # 开启严格模式
# 定义错误处理函数
handle_error() {
echo "错误发生在第 $1 行,退出状态码 $2"
# 发送警报
send_alert "脚本执行失败: $BASH_COMMAND"
exit $2
}
trap 'handle_error $LINENO $?' ERR
# 主脚本内容
main() {
echo "开始执行部署"
# 关键操作示例
docker pull myapp:latest || {
echo "镜像拉取失败,尝试重新构建"
build_image
}
# 更多操作...
}
# 调用主函数
main "$@"
9.2 调试技巧
当脚本出现问题时,可以使用以下方法调试:
- 使用
-x参数运行脚本,显示每条执行的命令:
bash复制bash -x deploy.sh
- 在脚本中插入调试输出:
bash复制echo "DEBUG: 当前容器状态=$(docker ps -a)"
- 检查Docker守护进程日志:
bash复制journalctl -u docker.service -n 50 --no-pager
- 使用
docker events监控实时事件:
bash复制docker events --filter 'event=die' --filter 'event=start'
10. 性能优化实践
10.1 构建缓存优化
通过合理利用构建缓存可以显著加快镜像构建速度:
bash复制#!/bin/bash
# 使用BuildKit后端
export DOCKER_BUILDKIT=1
# 多阶段构建优化
docker build \
--cache-from=myapp:latest \
--tag myapp:latest \
--build-arg BUILDKIT_INLINE_CACHE=1 \
.
对应的Dockerfile优化示例:
dockerfile复制# 第一阶段:构建环境
FROM node:16 as builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 第二阶段:运行环境
FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
CMD ["node", "dist/main.js"]
10.2 并行化操作
对于批量操作,可以使用GNU parallel实现并行处理:
bash复制#!/bin/bash
# 安装parallel
if ! command -v parallel &> /dev/null; then
apt-get install -y parallel || yum install -y parallel
fi
# 并行拉取镜像
cat images.list | parallel -j 4 "docker pull {}"
# 并行启动容器
seq 1 10 | parallel -j 4 "docker run -d --name worker{} myapp:latest"
11. 版本控制与回滚
11.1 版本化部署
通过Git标签和Docker标签实现版本控制:
bash复制#!/bin/bash
# 获取当前Git版本
VERSION=$(git describe --tags --always)
# 构建版本化镜像
docker build -t myapp:$VERSION .
# 记录部署日志
echo "$(date) - 部署版本 $VERSION" >> deploy.log
# 保留最近5个版本的镜像
docker images myapp | awk -v keep=5 'NR>keep+1 {print $3}' | xargs docker rmi
11.2 快速回滚机制
实现一键回滚到上一个版本:
bash复制#!/bin/bash
# 获取当前运行的版本
CURRENT_VERSION=$(docker inspect myapp --format '{{.Config.Image}}' | cut -d: -f2)
# 获取上一个版本
PREVIOUS_VERSION=$(grep -B1 $CURRENT_VERSION deploy.log | head -n1 | awk '{print $NF}')
# 执行回滚
docker stop myapp
docker rm myapp
docker run -d --name myapp myapp:$PREVIOUS_VERSION
# 记录回滚日志
echo "$(date) - 从 $CURRENT_VERSION 回滚到 $PREVIOUS_VERSION" >> rollback.log
12. 监控与告警集成
12.1 容器状态监控
通过Shell脚本收集容器指标并生成报告:
bash复制#!/bin/bash
# 生成监控报告
generate_report() {
echo "容器状态报告 - $(date)"
echo "========================="
echo "运行中容器: $(docker ps -q | wc -l)"
echo "全部容器: $(docker ps -aq | wc -l)"
echo "CPU使用率TOP5:"
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}" | sort -k2 -hr | head -5
echo "内存使用TOP5:"
docker stats --no-stream --format "table {{.Name}}\t{{.MemPerc}}" | sort -k2 -hr | head -5
}
# 发送报告到Slack
send_to_slack() {
curl -X POST -H 'Content-type: application/json' \
--data "{\"text\":\"$(generate_report | sed 's/"/\\"/g')\"}" \
$SLACK_WEBHOOK_URL
}
# 每小时执行一次
while true; do
send_to_slack
sleep 3600
done
12.2 日志分析告警
实时分析容器日志并触发告警:
bash复制#!/bin/bash
# 监控错误日志
docker logs -f myapp 2>&1 | while read line; do
if echo "$line" | grep -q "ERROR"; then
# 发送告警
curl -X POST $ALERT_ENDPOINT \
-d "message=应用错误: $line" \
-d "severity=high"
fi
done
13. 跨平台兼容性处理
13.1 平台检测与适配
使脚本能够识别不同平台并执行相应操作:
bash复制#!/bin/bash
# 检测平台
if [[ "$(uname -m)" == "arm64" ]]; then
PLATFORM="linux/arm64"
BASE_IMAGE="arm64v8/alpine"
elif [[ "$(uname -m)" == "x86_64" ]]; then
PLATFORM="linux/amd64"
BASE_IMAGE="alpine"
else
echo "不支持的平台"
exit 1
fi
# 使用平台特定的基础镜像
docker build \
--platform $PLATFORM \
--build-arg BASE_IMAGE=$BASE_IMAGE \
-t myapp .
13.2 Windows兼容模式
对于需要在Windows(WSL)环境下运行的脚本:
bash复制#!/bin/bash
# 检测是否在WSL中运行
if grep -qEi "(microsoft|wsl)" /proc/version &>/dev/null; then
echo "运行在WSL环境中"
# 调整路径格式
VOLUME_PATH=$(wslpath -w $(pwd))
else
VOLUME_PATH=$(pwd)
fi
docker run -v "$VOLUME_PATH:/app" myapp
14. CI/CD流水线集成
14.1 Jenkins集成示例
在Jenkins中调用Docker管理脚本的流水线配置:
groovy复制pipeline {
agent any
stages {
stage('Build') {
steps {
sh '''
#!/bin/bash
./scripts/build.sh
'''
}
}
stage('Test') {
steps {
sh '''
#!/bin/bash
./scripts/run_tests.sh
'''
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh '''
#!/bin/bash
./scripts/deploy_prod.sh
'''
}
}
}
post {
always {
sh '''
#!/bin/bash
./scripts/cleanup.sh
'''
}
}
}
14.2 GitHub Actions集成
GitHub Actions工作流示例:
yaml复制name: Docker Build and Deploy
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Login to Docker Hub
run: |
echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Build and push
run: |
./scripts/build.sh
./scripts/push.sh
- name: Deploy to production
run: |
ssh ${{ secrets.PROD_SERVER }} 'bash -s' < ./scripts/deploy_remote.sh
15. 脚本维护与文档化
15.1 脚本自文档化
通过Here Document实现脚本使用说明的内置:
bash复制#!/bin/bash
# 显示帮助信息
show_help() {
cat << EOF
Usage: $0 [OPTIONS] COMMAND
A Docker management script for myapp.
Commands:
start Start the application
stop Stop the application
restart Restart the application
status Show current status
logs Show application logs
Options:
-h, --help Show this help message
-e ENV Set environment (prod/stage/dev)
Examples:
$0 start -e prod
$0 status
EOF
}
# 参数解析
while getopts "he:" opt; do
case $opt in
h) show_help; exit 0 ;;
e) ENVIRONMENT=$OPTARG ;;
*) show_help; exit 1 ;;
esac
done
shift $((OPTIND-1))
COMMAND=$1
# 主逻辑...
15.2 单元测试框架
为Shell脚本添加基本的测试验证:
bash复制#!/bin/bash
# 测试启动功能
test_start() {
./manage.sh start
sleep 5
if [ "$(docker inspect -f '{{.State.Running}}' myapp)" == "true" ]; then
echo "PASS: 启动测试成功"
return 0
else
echo "FAIL: 启动测试失败"
return 1
fi
}
# 运行所有测试
run_tests() {
local passed=0 failed=0
for test_func in $(declare -F | awk '{print $3}' | grep ^test_); do
if $test_func; then
((passed++))
else
((failed++))
fi
done
echo "测试结果: $passed 通过, $failed 失败"
return $failed
}
run_tests
16. 安全审计与合规检查
16.1 容器安全扫描
集成安全扫描工具到自动化流程中:
bash复制#!/bin/bash
# 使用Trivy扫描镜像漏洞
scan_image() {
local image=$1
if ! docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image --severity HIGH,CRITICAL $image; then
echo "发现严重漏洞,停止部署"
exit 1
fi
}
# 在构建后调用
scan_image "myapp:latest"
16.2 合规性检查
检查容器配置是否符合安全基线:
bash复制#!/bin/bash
# 检查容器是否以非root运行
check_non_root() {
local container=$1
local user=$(docker inspect -f '{{.Config.User}}' $container)
if [ -z "$user" ]; then
echo "警告: 容器 $container 以root用户运行"
return 1
fi
return 0
}
# 检查所有运行中的容器
for container in $(docker ps -q); do
check_non_root $container
done
17. 备份与恢复策略
17.1 容器数据备份
自动化备份容器中的关键数据:
bash复制#!/bin/bash
# 备份数据库容器
backup_database() {
local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_dir="/backups/db/$timestamp"
mkdir -p $backup_dir
# 导出数据库
docker exec mysql mysqldump -u root -p"$DB_PASSWORD" --all-databases > "$backup_dir/full.sql"
# 备份数据卷
docker run --rm --volumes-from mysql -v $backup_dir:/backup alpine \
tar czf /backup/data.tar.gz /var/lib/mysql
# 上传到云存储
aws s3 cp "$backup_dir/full.sql" "s3://myapp-backups/db/$timestamp.sql"
aws s3 cp "$backup_dir/data.tar.gz" "s3://myapp-backups/db/$timestamp.tar.gz"
# 清理本地备份(保留最近7天)
find /backups/db -type d -mtime +7 -exec rm -rf {} \;
}
# 每天凌晨执行备份
backup_database
17.2 容器配置备份
备份重要的容器配置:
bash复制#!/bin/bash
# 备份容器配置
backup_configs() {
local containers=("nginx" "myapp" "mysql")
local backup_dir="/backups/configs/$(date +%Y%m%d)"
mkdir -p $backup_dir
for container in "${containers[@]}"; do
# 导出容器配置
docker inspect $container > "$backup_dir/${container}_inspect.json"
# 导出容器日志
docker logs $container > "$backup_dir/${container}_logs.log" 2>&1
done
}
backup_configs
18. 网络配置自动化
18.1 自定义网络配置
通过脚本创建和管理Docker网络:
bash复制#!/bin/bash
# 创建自定义网络
create_network() {
if ! docker network inspect myapp_net >/dev/null 2>&1; then
docker network create \
--driver=bridge \
--subnet=172.20.0.0/16 \
--ip-range=172.20.5.0/24 \
--gateway=172.20.5.254 \
myapp_net
fi
}
# 将容器连接到网络
connect_container() {
local container=$1
docker network connect myapp_net $container
}
# 使用示例
create_network
connect_container "mysql"
connect_container "myapp"
18.2 网络策略检查
验证容器的网络配置是否符合安全要求:
bash复制#!/bin/bash
# 检查不必要的端口暴露
check_exposed_ports() {
local container=$1
local ports=$(docker inspect -f '{{range $p, $conf := .NetworkSettings.Ports}}{{$p}} {{end}}' $container)
for port in $ports; do
if [[ $port == 0.0.0.0:* ]]; then
echo "警告: 容器 $container 暴露了外部端口 $port"
fi
done
}
# 检查所有容器
for container in $(docker ps -q); do
check_exposed_ports $container
done
19. 资源清理与回收
19.1 自动化清理脚本
定期清理不再使用的Docker资源:
bash复制#!/bin/bash
# 清理停止的容器
docker container prune -f
# 清理未被使用的网络
docker network prune -f
# 清理悬空镜像
docker image prune -f
# 清理构建缓存
docker builder prune -f
# 按时间清理旧镜像
docker image prune -a -f --filter "until=24h"
# 清理卷
docker volume prune -f
19.2 资源使用报告
生成资源使用情况报告:
bash复制#!/bin/bash
generate_resource_report() {
echo "===== 资源使用报告 ====="
echo "生成时间: $(date)"
echo
echo "--- 容器资源使用 ---"
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}"
echo
echo "--- 磁盘使用 ---"
docker system df -v
echo
echo "--- 最大的5个镜像 ---"
docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -h -r | head -5
}
# 保存报告到文件
generate_resource_report > /var/log/docker/resource_report_$(date +%Y%m%d).log
20. 多环境管理策略
20.1 环境差异化配置
通过脚本管理不同环境(开发/测试/生产)的配置:
bash复制#!/bin/bash
ENVIRONMENT=${1:-dev}
case $ENVIRONMENT in
prod)
DOCKER_COMPOSE_FILE="docker-compose.prod.yml"
REGISTRY="registry.prod.example.com"
NETWORK="prod_net"
;;
staging)
DOCKER_COMPOSE_FILE="docker-compose.staging.yml"
REGISTRY="registry.stage.example.com"
NETWORK="stage_net"
;;
dev)
DOCKER_COMPOSE_FILE="docker-compose.dev.yml"
REGISTRY="registry.dev.example.com"
NETWORK="dev_net"
;;
*)
echo "未知环境: $ENVIRONMENT"
exit 1
;;
esac
# 使用适当的环境配置
docker-compose -f $DOCKER_COMPOSE_FILE up -d
# 打标签并推送到对应环境的仓库
docker tag myapp:latest $REGISTRY/myapp:latest
docker push $REGISTRY/myapp:latest
20.2 环境同步脚本
将配置从开发环境同步到其他环境:
bash复制#!/bin/bash
# 从开发环境导出配置
docker-compose -f docker-compose.dev.yml config > docker-compose.export.yml
# 转换为生产环境配置
sed -i 's/dev-db/prod-db/g' docker-compose.export.yml
sed -i 's/build: ./image: registry.prod.example.com\/myapp/g' docker-compose.export.yml
# 应用生产配置
mv docker-compose.export.yml docker-compose.prod.yml