当前位置: 首页 > news >正文

install_arm_docker.sh

#!/bin/bash
# Docker 二进制包安装脚本(最终修复版)
# 作者:Doubao
# 日期:2025-07-19

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # 无颜色

# 定义变量
DOCKER_VERSION="28.3.2"
PACKAGE_DIR="/opt/docker-packages"         # 安装包目录
PACKAGE_PATH="$PACKAGE_DIR/docker-$DOCKER_VERSION.tgz"  # 安装包路径
EXTRACT_DIR="/tmp/docker-install"          # 解压目录
LOG_FILE="/var/log/docker_install.log"

# 日志函数
log() {
local message="$1"
local level="$2"

if [ -z "$level" ]; then
level="INFO"
fi

echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" | tee -a "$LOG_FILE"
}

# 错误处理函数
error() {
log "$1" "ERROR"
echo -e "${RED}错误: $1${NC}" >&2
exit 1
}

# 检查是否为 root 用户
check_root() {
if [ "$(id -u)" -ne 0 ]; then
error "请使用 root 用户执行此脚本"
fi
}

# 检查系统架构
check_arch() {
local arch=$(uname -m)
if [ "$arch" != "aarch64" ]; then
error "此脚本仅适用于 aarch64 架构,当前架构为 $arch"
fi
log "系统架构检查通过: $arch"
}

# 检查安装包
check_package() {
if [ ! -d "$PACKAGE_DIR" ]; then
error "安装包目录 $PACKAGE_DIR 不存在"
fi

if [ ! -f "$PACKAGE_PATH" ]; then
# 尝试查找匹配的包
local found_pkg=$(ls "$PACKAGE_DIR"/docker-*.tgz 2>/dev/null | head -1)
if [ -n "$found_pkg" ]; then
log "未找到 $PACKAGE_PATH,但发现匹配的包: $found_pkg"
PACKAGE_PATH="$found_pkg"
DOCKER_VERSION=$(basename "$found_pkg" | sed 's/docker-//' | sed 's/.tgz//')
log "自动检测到 Docker 版本: $DOCKER_VERSION"
else
error "安装包 $PACKAGE_PATH 不存在,且未找到匹配的 docker-*.tgz 文件"
fi
fi

# 验证文件类型
local file_type=$(file -b "$PACKAGE_PATH")
if ! echo "$file_type" | grep -q "gzip compressed data"; then
error "安装包 $PACKAGE_PATH 不是有效的 gzip 压缩文件"
fi

log "安装包检查通过"
}

# 卸载旧版本
uninstall_old() {
log "卸载旧版本 Docker..."

# 停止运行中的 Docker 服务
systemctl stop docker.service docker.socket || true

# 卸载旧版本
yum remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine \
docker-ce || true

# 移除残留文件和符号链接
log "移除旧版 Docker 二进制文件和符号链接..."
rm -f /usr/bin/docker* /usr/bin/containerd* /usr/bin/runc /usr/bin/ctr || true

log "旧版本 Docker 卸载完成"
}

# 解压安装包
extract_package() {
log "解压安装包..."

# 创建解压目录
mkdir -p "$EXTRACT_DIR"
rm -rf "$EXTRACT_DIR"/*

# 解压
tar -xzf "$PACKAGE_PATH" -C "$EXTRACT_DIR" || error "解压安装包失败"

# 检查解压结果
if [ ! -d "$EXTRACT_DIR/docker" ]; then
error "解压后未找到 docker 目录"
fi

log "安装包解压完成"
}

# 安装 Docker
install_docker() {
log "开始安装 Docker $DOCKER_VERSION..."

# 移除目标目录中可能存在的符号链接
log "移除 /usr/bin 目录下的 Docker 相关符号链接..."
rm -f /usr/bin/docker /usr/bin/docker-init /usr/bin/docker-proxy /usr/bin/dockerd \
/usr/bin/containerd /usr/bin/containerd-shim /usr/bin/containerd-shim-runc-v2 \
/usr/bin/ctr /usr/bin/runc || true

# 复制二进制文件到 /usr/bin
log "复制 Docker 二进制文件..."
cp -f "$EXTRACT_DIR/docker"/* /usr/bin/ || error "复制 Docker 二进制文件失败"

# 验证安装
log "验证 Docker 安装..."
if ! docker --version >/dev/null 2>&1; then
error "Docker 安装失败,无法获取版本信息"
fi

log "Docker 版本: $(docker --version)"

# 创建必要的目录
mkdir -p /etc/docker /var/lib/docker

log "Docker 安装完成"
}

# 配置 Docker 服务
configure_docker_service() {
log "配置 Docker 服务..."

# 创建 systemd 服务文件
cat > /etc/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target
Requires=containerd.service

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP \$MAINPID
TimeoutSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3

# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
# this option work for either version of systemd.
StartLimitInterval=60s

# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity

# Comment TasksMax if your systemd version does not support it.
# Only systemd 226 and above support this option.
TasksMax=infinity

# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes

# kill only the docker process, not all processes in the cgroup
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target
EOF

# 重载 systemd
systemctl daemon-reload

# 启动 Docker 并设置开机自启
log "启动 Docker 服务..."
systemctl enable --now docker

# 验证 Docker 服务状态
if ! systemctl is-active docker >/dev/null 2>&1; then
error "Docker 服务未启动"
fi

log "Docker 服务状态: $(systemctl is-active docker)"

# 测试 Docker 运行
log "测试 Docker 基本功能..."
if ! docker run --rm hello-world >/dev/null 2>&1; then
error "Docker 测试运行失败"
fi

log "Docker 测试运行成功"
}

# 配置 Docker
configure_docker() {
log "配置 Docker..."

# 设置镜像加速器(可选)
cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://registry.docker-cn.com"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF

# 重启 Docker 服务使配置生效
log "重启 Docker 服务以应用配置..."
systemctl restart docker

log "Docker 配置完成"
}

# 添加用户到 docker 组(可选)
add_user_to_docker_group() {
local user="${1:-$(whoami)}"

log "将用户 $user 添加到 docker 组..."

if ! getent group docker >/dev/null; then
groupadd docker
fi

usermod -aG docker "$user"

log "用户 $user 已添加到 docker 组"
log "注意: 需要重新登录才能生效"
}

# 清理临时文件
cleanup() {
log "清理临时文件..."
rm -rf "$EXTRACT_DIR"
log "临时文件清理完成"
}

# 显示安装信息
show_install_info() {
echo -e "${GREEN}=====================================================================${NC}"
echo -e "${GREEN}Docker 已成功安装!${NC}"
echo -e "${GREEN}版本: $(docker --version)${NC}"
echo -e "${GREEN}状态: $(systemctl is-active docker)${NC}"
echo -e "${GREEN}=====================================================================${NC}"
echo -e "${YELLOW}使用提示:${NC}"
echo -e "  1. 普通用户需要重新登录才能使用 docker 命令"
echo -e "  2. 查看 Docker 信息: docker info"
echo -e "  3. 运行第一个容器: docker run -it ubuntu bash"
echo -e "${YELLOW}日志文件位置: $LOG_FILE${NC}"
}

# 主函数
main() {
echo -e "${GREEN}开始执行 Docker 二进制包安装脚本...${NC}"
log "========================================================="
log "开始执行 Docker 二进制包安装脚本"
log "系统信息: $(uname -a)"

check_root
check_arch
check_package
uninstall_old
extract_package
install_docker
configure_docker_service
configure_docker
add_user_to_docker_group
cleanup

show_install_info
log "Docker 二进制包安装脚本执行完成"
log "========================================================="
}

# 执行主函数
main

安装docker

http://www.lryc.cn/news/593215.html

相关文章:

  • Django接口自动化平台实现(三)
  • Django母婴商城项目实践(八)- 数据渲染与显示之首页
  • LLM 的Top-P参数 是在LLM中的每一层发挥作用,还是最后一层?
  • 【设计模式C#】外观模式(用于解决客户端对系统的许多类进行频繁沟通)
  • Django母婴商城项目实践(七)- 首页数据业务视图
  • 洛谷 P2947:[USACO09MAR] Look Up S ← 数组模拟+单调栈
  • 使用 Gunicorn 部署 Django 项目
  • 5 基于STM32单片机的绝缘检测系统设计(STM32代码编写+手机APP设计+PCB设计+Proteus仿真)
  • 6 STM32单片机的智能家居安防系统设计(STM32代码+手机APP设计+PCB设计+Proteus仿真)
  • 对话访谈 | 盘古信息×锐明科技:中国企业高质量出海“走进去”和“走上去”
  • 家庭KTV v1.1.9 | 曲库丰富,无限制免费K歌
  • 驾驭 Spring Boot 事件机制:8 个内置事件 + 自定义扩展实战
  • 《一行注解解决重复提交:Spring Boot 接口幂等实战》
  • 深入理解设计模式:策略模式的艺术与实践
  • 在非Spring Boot的Spring项目中使用Lock4j
  • 用graphviz画一个关系图
  • 云服务器磁盘IO性能优化的测试与配置方法
  • 2025年7月19日,二维矩阵
  • 智能制造——解读39页汽车行业数字化工厂解决方案【附全文阅读】
  • 异世界历险之数据结构世界(二叉树-leetcode)
  • 国产电科金仓数据库:融合进化,智领未来
  • 【Unity3D实例-功能-移动】角色移动-通过WSAD(Rigidbody方式)
  • 架构探索笔记【1】
  • JavaScript空值安全深度指南
  • windows内核研究(驱动开发之内核编程)
  • Java无服务架构新范式:Spring Native与AWS Lambda冷启动深度优化
  • 【小沐学GIS】基于Rust绘制三维数字地球Earth(Rust、OpenGL、GIS)
  • C++STL系列之概述
  • OpenCV 官翻5 - 机器学习
  • 【web安全】万能密码