1. Shell 与 Docker 自动化管理概述
在现代应用部署环境中,容器化技术已经成为标配。作为一名长期从事运维工作的技术人员,我深刻体会到手动管理容器的痛苦——每次部署新版本都要重复执行几十条命令,半夜被叫起来处理容器崩溃更是家常便饭。直到我开始将 Shell 脚本与 Docker 结合使用,工作效率才得到质的提升。
Shell 脚本能够将繁琐的 Docker 操作封装成可重复执行的自动化流程。比如我们团队现在使用的自动化部署系统,只需要执行一个脚本就能完成从代码拉取、镜像构建到服务上线的全过程,部署时间从原来的2小时缩短到15分钟。更重要的是,这种方案不需要引入复杂的编排系统,特别适合中小规模的生产环境。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 基础环境准备
2.1 系统与 Docker 安装
我推荐使用 Ubuntu 22.04 LTS 作为基础系统,它的长期支持特性和稳定的软件源能减少很多不必要的麻烦。以下是经过生产验证的安装步骤:
bash复制# 卸载旧版本
sudo apt-get remove docker docker-engine docker.io containerd runc
# 安装依赖
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 添加 Docker 官方 GPG 密钥
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
# 安装 Docker 引擎
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
# 验证安装
sudo docker run hello-world
注意:生产环境中建议固定 Docker 版本而非使用最新版,避免因版本更新引入兼容性问题。可以通过
apt-get install docker-ce=<VERSION>指定版本。
2.2 用户权限配置
默认情况下,Docker 需要 root 权限才能运行,这在生产环境中存在安全隐患。我建议将操作用户加入 docker 组:
bash复制sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker # 刷新组权限
验证配置是否生效:
bash复制docker ps # 应该能正常执行而不需要 sudo
3. 容器生命周期自动化管理
3.1 容器启停控制脚本
下面这个脚本封装了容器启动、停止、重启和状态检查的完整流程:
bash复制#!/bin/bash
CONTAINER_NAME="my_app"
IMAGE_NAME="my_app:latest"
PORT_MAPPING="8080:80"
VOLUME_MAPPING="/data:/app/data"
case "$1" in
start)
docker run -d \
--name $CONTAINER_NAME \
-p $PORT_MAPPING \
-v $VOLUME_MAPPING \
$IMAGE_NAME
;;
stop)
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
;;
restart)
$0 stop
$0 start
;;
status)
docker ps -a | grep $CONTAINER_NAME
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
esac
使用方式:
bash复制./container_ctl.sh start # 启动容器
./container_ctl.sh status # 检查状态
经验分享:在实际使用中发现,直接使用
docker restart命令有时会导致容器网络配置异常。更可靠的做法是先 stop 再 start,虽然耗时稍长但稳定性更好。
3.2 容器健康检查与自动恢复
生产环境中容器可能因各种原因崩溃,我们需要实现自动恢复机制:
bash复制#!/bin/bash
CONTAINER_NAME="my_app"
MAX_RETRIES=3
RETRY_INTERVAL=60
is_container_healthy() {
local status=$(docker inspect --format='{{.State.Status}}' $CONTAINER_NAME 2>/dev/null)
[ "$status" = "running" ] && return 0 || return 1
}
for ((i=1; i<=$MAX_RETRIES; i++)); do
if ! is_container_healthy; then
echo "$(date) - 容器异常,尝试重启 ($i/$MAX_RETRIES)"
docker restart $CONTAINER_NAME
sleep $RETRY_INTERVAL
else
echo "$(date) - 容器运行正常"
exit 0
fi
done
echo "$(date) - 达到最大重试次数,发送告警"
# 这里可以添加邮件或短信告警逻辑
exit 1
建议将上述脚本加入 crontab 定期执行:
bash复制crontab -e
# 添加以下内容,每5分钟检查一次
*/5 * * * * /path/to/health_check.sh >> /var/log/container_monitor.log 2>&1
4. 镜像构建自动化
4.1 基础镜像构建优化
一个高效的 Dockerfile 应该遵循以下原则:
- 合理利用构建缓存:将变化频率低的指令放在前面
- 减少镜像层数:合并 RUN 指令
- 使用轻量级基础镜像:如 alpine 版本
dockerfile复制# 使用多阶段构建减少最终镜像体积
FROM golang:1.18 as builder
WORKDIR /app
COPY . .
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/main
# 最终阶段
FROM alpine:3.14
WORKDIR /app
COPY --from=builder /app/main /app/main
COPY --from=builder /app/config /app/config
# 设置非root用户
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 8080
ENTRYPOINT ["/app/main"]
构建脚本示例:
bash复制#!/bin/bash
VERSION="1.0.$(date +%Y%m%d)"
IMAGE_NAME="my_app"
docker build -t $IMAGE_NAME:$VERSION .
docker tag $IMAGE_NAME:$VERSION $IMAGE_NAME:latest
4.2 镜像版本管理策略
在实际项目中,我采用以下版本管理方案:
- 每次构建生成带日期戳的版本号(如 1.0.20230615)
- 最新稳定版本标记为 latest
- 重大版本使用语义化版本号(如 2.1.0)
回滚到特定版本的脚本:
bash复制#!/bin/bash
TARGET_VERSION=$1
CONTAINER_NAME="my_app"
docker stop $CONTAINER_NAME
docker rm $CONTAINER_NAME
docker run -d \
--name $CONTAINER_NAME \
-p 8080:80 \
my_app:$TARGET_VERSION
5. 批量部署与管理
5.1 多容器批量操作
当需要管理多个相同类型的容器时(如微服务实例),可以使用如下脚本:
bash复制#!/bin/bash
CONTAINER_PREFIX="app_node"
INSTANCE_COUNT=3
IMAGE_NAME="my_app:latest"
case "$1" in
start)
for i in $(seq 1 $INSTANCE_COUNT); do
docker
