旧的centos7 之前安装的是docker.io 由于一些原因,像docker compose 等版本变化,以及docker.io源受限等,我们要更新到docker-ce 并使用国内阿里云的源怎么处理?下面直接上脚本,upgrade-docker.sh
#!/bin/bash
set -e
# 创建临时目录
TEMP_DIR="./tmp"
mkdir -p "$TEMP_DIR"
# 函数:错误处理和回滚
rollback() {
echo "发生错误。正在回滚更改..."
if [ -f "$TEMP_DIR/docker_images.tar" ]; then
docker load -i "$TEMP_DIR/docker_images.tar"
fi
if [ -d "$TEMP_DIR/docker_containers_backup" ]; then
for container in "$TEMP_DIR/docker_containers_backup"/*; do
docker import "$container" $(basename "$container")
done
fi
if [ -f "$TEMP_DIR/docker-compose" ]; then
sudo mv "$TEMP_DIR/docker-compose" /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
fi
if [ -f "$TEMP_DIR/docker_config.txt" ]; then
while IFS= read -r line; do
eval "$line"
done < "$TEMP_DIR/docker_config.txt"
fi
sudo yum downgrade -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
echo "回滚完成。系统已恢复到之前的状态。"
exit 1
}
# 捕获错误并调用回滚函数
trap rollback ERR
# 保存当前的Docker数据和配置
echo "正在保存当前的Docker数据和配置..."
mkdir -p "$TEMP_DIR/docker_containers_backup"
docker save $(docker images -q) -o "$TEMP_DIR/docker_images.tar"
# 保存每个容器的配置
docker ps -a --format '{{.Names}}' | while read container_name; do
docker inspect "$container_name" > "$TEMP_DIR/docker_containers_backup/${container_name}_inspect.json"
docker export "$container_name" > "$TEMP_DIR/docker_containers_backup/${container_name}.tar"
done
# 保存Docker守护进程配置
docker info --format '{{json .}}' > "$TEMP_DIR/docker_config.txt"
# 停止Docker服务
echo "正在停止Docker服务..."
sudo systemctl stop docker
# 备份 docker-compose
if [ -f /usr/local/bin/docker-compose ]; then
echo "正在备份docker-compose..."
sudo cp /usr/local/bin/docker-compose "$TEMP_DIR/docker-compose"
fi
# 卸载旧版本的Docker和docker-compose
echo "正在卸载旧版本的Docker和docker-compose..."
sudo yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-ce \
docker-ce-cli
sudo rm -f /usr/local/bin/docker-compose
# 安装必要的依赖
echo "正在安装必要的依赖..."
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加阿里云Docker CE的yum源
echo "正在添加阿里云Docker CE的yum源..."
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装Docker CE
echo "正在安装Docker CE..."
sudo yum install -y docker-ce docker-ce-cli containerd.io
# 恢复Docker守护进程配置
if [ -f "$TEMP_DIR/docker_config.txt" ]; then
echo "正在恢复Docker守护进程配置..."
sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak || true
sudo jq -s '.[0] * .[1]' /etc/docker/daemon.json "$TEMP_DIR/docker_config.txt" | sudo tee /etc/docker/daemon.json > /dev/null
fi
# 启动Docker服务
echo "正在启动Docker服务..."
sudo systemctl start docker
# 设置Docker开机自启
echo "正在设置Docker开机自启..."
sudo systemctl enable docker
# 恢复之前保存的Docker数据
echo "正在恢复Docker数据..."
docker load -i "$TEMP_DIR/docker_images.tar"
# 恢复容器
for container in "$TEMP_DIR/docker_containers_backup"/*_inspect.json; do
container_name=$(basename "$container" _inspect.json)
echo "正在恢复容器: $container_name"
# 从备份中导入容器镜像
cat "$TEMP_DIR/docker_containers_backup/${container_name}.tar" | docker import - "$container_name:backup"
# 从inspect文件中提取必要的配置
config=$(jq '.[] | {Image: .Config.Image, Cmd: .Config.Cmd, Entrypoint: .Config.Entrypoint, Env: .Config.Env, ExposedPorts: .Config.ExposedPorts, Volumes: .Config.Volumes, WorkingDir: .Config.WorkingDir, HostConfig: .HostConfig}' "$container")
# 使用提取的配置创建新容器
docker create $(echo "$config" | jq -r '.HostConfig | to_entries | map("\(.key)=\(.value|tostring)") | join(" ")') \
$(echo "$config" | jq -r 'to_entries | map("\(.key)=\(.value|tostring)") | join(" ")') \
--name "$container_name" \
"$container_name:backup"
# 如果容器之前是运行状态,则启动它
if [ "$(jq -r '.[0].State.Running' "$container")" = "true" ]; then
docker start "$container_name"
fi
done
# 清理临时文件
echo "正在清理临时文件..."
rm -rf "$TEMP_DIR"
# 验证 docker compose 命令
if docker compose version; then
echo "Docker Compose (V2) 已成功安装。"
else
echo "Docker Compose (V2) 不可用。请检查您的Docker安装。"
rollback
fi
echo "Docker CE 安装、数据迁移和 docker-compose 移除已成功完成。"
echo "所有容器已恢复,保留了原始名称、参数和配置。"