#!/bin/bash ############################################################################################# # 用途: 多功能部署 Docker 脚本 # 作者: 丁辉 # 编写时间: 2023-12-07 # 更新时间: 2024-06-06 ############################################################################################# # 加载检测脚本 source <(curl -sS https://gitee.com/offends/Linux/raw/main/File/Shell/Check_command.sh) # 开启检测 # set -e -o pipefail set -e # 变量定义 # 脚本版本 SCRIPT_VERSION="1.0.7" # Docker 二进制部署使用官方下载地址 INSTALL_DOCKER_PACKAGE="https://download.docker.com/linux/static/stable" # Rke支持Docker大版本 RKE_SUPPORT_VERSION="20.10.24" # 控制在线或离线安装变量(默认为在线安装)[使用offline_packager.sh打包离线包后会自动变为离线安装] NETWORK_STATE="online" # 控制二进制安装还是网络源安装(默认为二进制安装) INSTALL_TYPE=${INSTALL_TYPE:-binary} # 官方脚本安装 # INSTALL_TYPE=${INSTALL_TYPE:-official} # 调试模式为: privilege,请谨慎使用 # INSTALL_TYPE=${INSTALL_TYPE:-privilege} # --help 帮助信息 function HELP_BINARY(){ echo "Usage: script_name [OPTIONS] [ARGUMENTS]" echo "" echo "Description:" echo " Offends" echo "" echo "Options:" echo " -h, --help 显示此帮助信息" echo " -v, --version 显示当前脚本版本号" echo " rke 二进制安装 Rke1 官方支持 Docker 最新版本" echo " latest 二进制安装 Docker 官方最新版本" echo " all_curl 二进制安装 Docker 官方最新版本,省心网络安装,所有文件都会从网络 curl 下载" echo "" echo " export INSTALL_TYPE=official 切换使用官方脚本安装 Docker" echo " export INSTALL_TYPE=privilege 切换使用特权模式,详细功能请查看: https://gitee.com/offends/Kubernetes/blob/main/Docker/README.md" echo "" echo "Examples:" echo " 示例 1: ./install.sh rke" echo " 示例 2: ./install.sh latest" exit 0 } function HELP_OFFICIAL(){ echo "Usage: script_name [OPTIONS] [ARGUMENTS]" echo "" echo "Description:" echo " Offends" echo "" echo "Options:" echo " -h, --help 显示此帮助信息" echo " -v, --version 显示当前脚本版本号" echo " default 官方默认安装脚本" echo " aliyun 官方默认安装脚本-阿里源" echo "" echo " export INSTALL_TYPE=binary 切换使用二进制脚本安装 Docker" echo " export INSTALL_TYPE=privilege 切换使用特权模式,详细功能请查看: https://gitee.com/offends/Kubernetes/blob/main/Docker/README.md" echo "" echo "Examples:" echo " 示例 1: ./install.sh default" echo " 示例 2: ./install.sh aliyun" exit 0 } function HELP_PRIVILEGE(){ echo "Usage: script_name [OPTIONS] [ARGUMENTS]" echo "" echo "Description:" echo " Offends" echo "" echo "Options:" echo " -h, --help 显示此帮助信息" echo " -v, --version 显示当前脚本版本号" echo " stop 强制停止 Docker,并清理残留进程" echo " uninstall 强制卸载 Docker [正常情况下会保留存储文件]" echo " clean 清理 Docker 持久化残留文件,请谨慎使用" echo " update 更新 Docker 版本 [只支持二进制部署环境更新]" echo "" echo " export INSTALL_TYPE=binary 切换使用二进制脚本安装 Docker" echo " export INSTALL_TYPE=official 切换使用官方脚本安装 Docker" echo "" echo "Examples:" echo " 示例 1: ./install.sh stop" echo " 示例 2: ./install.sh uninstall" echo " 示例 3: ./install.sh clean" echo " 示例 4: ./install.sh update" exit 0 } # 判断在线安装还是离线安装 function CHECK_NETWORK_STATE() { if [ ${NETWORK_STATE} = "online" ]; then INSTALL_ONLINE $@ elif [ ${NETWORK_STATE} = "offline" ]; then INSTALL_OFFLINE fi } # 在线安装 function INSTALL_ONLINE(){ if [ ${INSTALL_TYPE} = "binary" ]; then if [ $# -eq 1 ]; then while true; do case $1 in rke) SEND_INFO "您选择的安装方式为: RKE最高支持版本安装" INSTALL_BINARY_RKE break ;; latest) SEND_INFO "您选择的安装方式为: Docker最新版本安装" INSTALL_BINARY_LATEST break ;; all_curl) SEND_INFO "您选择的安装方式为: 省心网络安装" INSTALL_BINARY_ALL_CURL break ;; --help|-h) HELP_BINARY ;; --version|-v) SEND_INFO "当前脚本版本号为: $SCRIPT_VERSION" break ;; *) SEND_ERROR "参数错误" HELP_BINARY ;; esac done else SEND_ERROR "参数错误" HELP_BINARY fi elif [ ${INSTALL_TYPE} = "official" ]; then if [ $# -eq 1 ]; then while true; do case $1 in default) SEND_INFO "您选择的安装方式为: 官方默认安装脚本" INSTALL_OFFICIAL_DEFAULT break ;; aliyun) SEND_INFO "您选择的安装方式为: 官方默认安装脚本-阿里源" INSTALL_OFFICIAL_ALIYUN break ;; --help|-h) HELP_OFFICIAL ;; --version|-v) SEND_INFO "当前脚本版本号为: $SCRIPT_VERSION" break ;; *) SEND_ERROR "参数错误" HELP_OFFICIAL ;; esac done else SEND_ERROR "参数错误" HELP_OFFICIAL fi fi } # 特权模式 function PRIVILEGE(){ if [ $# -eq 1 ]; then while true; do case $1 in stop) SEND_INFO "您选择的模式为: 强制停止 Docker,并清理残留进程" STOP_DOCKER break ;; uninstall) SEND_INFO "您选择的模式为: 强制卸载 Docker" UNINSTALL_DOCKER break ;; clean) SEND_INFO "您选择的模式为: 清理 Docker 持久化残留文件,请谨慎使用" CLEAN_DOCKER break ;; update) SEND_INFO "您选择的模式为: 更新 Docker 版本" UPDATE_DOCKER break ;; --help|-h) HELP_PRIVILEGE ;; --version|-v) SEND_INFO "当前脚本版本号为: $SCRIPT_VERSION" break ;; *) SEND_ERROR "参数错误" HELP_PRIVILEGE ;; esac done else SEND_ERROR "参数错误" HELP_PRIVILEGE fi } # 停止 Docker,并清理残留进程 function STOP_DOCKER(){ # 停止 docker SEND_WARN "正在停止 Docker 服务..." NULL_TRUE systemctl stop docker NULL_TRUE systemctl stop docker.socket # 判断是否存在 docker 进程,存在则清理 if ps -ef | grep docker | grep -v grep >/dev/null 2>&1; then SEND_INFO "正在清理 Docker 进程..." ps -ef | grep docker | grep -v grep | grep -v Install-docker.sh | awk '{print $2}' | xargs kill -9 > /dev/null 2>&1 || true fi SEND_INFO "Docker 服务已停止,进程已清理完毕" } # 更新 Docker 版本 function UPDATE_DOCKER(){ if ! command -v docker >/dev/null 2>&1; then SEND_ERROR "Docker 服务未安装,请先安装 Docker 服务" exit 1 fi while true; do read -p "在线更新[1默认]/本地文件更新[2](仅支持二进制环境): " userInput case $userInput in "1"|"") SEND_INFO "您选择的更新方式为: 在线更新" STOP_DOCKER CHECK_CPU read -p "输入所需更新的版本[示例: 24.0.7]: " version SEND_INFO "正在获取 Docker 版本: $version" URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/docker-$version.tgz" if ! wget $URL > /dev/null 2>&1; then SEND_ERROR "获取版本失败,请检查 Docker 版本: $version 是否真实存在或检查本地网络情况" exit 1 fi UPDATE_DOCKER_FILE break ;; "2") SEND_INFO "您选择的更新方式为: 本地文件更新" STOP_DOCKER read -p "输入 Docker 本地安装文件绝对路径[示例: /root/docker-24.0.7.tgz]: " pwd CHECK_FILE $pwd NULL_TRUE cp $pwd . SEND_INFO "更新完成" UPDATE_DOCKER_FILE break ;; *) SEND_ERROR "输入错误,请重新输入" ;; esac done } # 更新替换 Docker 二进制文件 function UPDATE_DOCKER_FILE(){ CHECK_COMMAND_NULL tar -zxvf docker-*.tgz CHECK_COMMAND_NULL \\cp ./docker/* /usr/local/bin/ NULL_TRUE rm -rf docker docker-*.tgz NULL_TRUE systemctl start docker DOCKER_VERSION_ENV } # 强制卸载 Docker function UNINSTALL_DOCKER(){ STOP_DOCKER SEND_INFO "正在清理 Docker 用户,请稍等" NULL_TRUE userdel -r docker NULL_TRUE groupdel docker SEND_INFO "正在清理 Docker 环境,请稍等" # 清理网络源安装文件 if command -v yum >/dev/null 2>&1; then # yum 卸载方法 yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras -y > /dev/null 2>&1 || true elif command -v apt >/dev/null 2>&1; then # apt 卸载方法 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras -y > /dev/null 2>&1 || true else SEND_ERROR "无法识别的系统软件包管理工具" exit 1 fi # 清理二进制安装文件 dfile=( containerd containerd-shim containerd-shim-runc-v2 ctr docker dockerd docker-init docker-proxy runc ) # 指定文件列表,使用 command -v 查找并删除 for i in "${dfile[@]}"; do rm -rf $(command -v $i) > /dev/null 2>&1 || true done SEND_INFO "Docker 环境清理完毕" } # 清理 Docker 持久化残留文件,请谨慎使用 function CLEAN_DOCKER(){ # 给用户一个输入框,判断用户输入的是否为大写 YES 或 NO validInput=false read -p "这是一个危险操作,你真的需要这么做吗? YES/NO: " userInput while [ "$validInput" = false ]; do case $userInput in YES) if ! command -v docker >/dev/null 2>&1; then SEND_INFO "正在彻底清理环境..." NULL_TRUE rm -rf /var/lib/docker NULL_TRUE rm -rf /var/lib/containerd NULL_TRUE rm -rf /etc/docker # 查找 docker.service 文件位置并删除 # find / -name "docker.service" | xargs rm -rf > /dev/null 2>&1 || true rm -rf $(systemctl cat docker | head -n 1 | sed 's/^#//') || true NULL_TRUE rm -rf /etc/sysctl.d/offends.conf SEND_INFO "环境清理完毕" else SEND_INFO "请先卸载 Docker 服务,再执行此操作" fi validInput=true ;; NO) SEND_WARN "退出脚本。" validInput=true ;; *) read -p "输入不是大写的 YES 或 NO,请重新输入: " userInput ;; esac done } # 官方默认安装脚本 function INSTALL_OFFICIAL_DEFAULT(){ FUNC_PRINT_SYSTEM_INFO SEND_INFO "开始安装 Docker 服务" curl -fsSL https://get.docker.com | bash INIT_DOCKER_FILE_ME } # 官方默认安装脚本-阿里源 function INSTALL_OFFICIAL_ALIYUN(){ FUNC_PRINT_SYSTEM_INFO SEND_INFO "开始安装 Docker 服务" curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun INIT_DOCKER_FILE_ME } # 二进制安装 Rke1 官方支持 Docker 最新版本 function INSTALL_BINARY_RKE(){ CHECK_CPU FUNC_PRINT_SYSTEM_INFO #下载rke支持范围内的版本包 SEND_INFO "正在获取当前Rke支持最新Docker版本文件" URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/docker-$RKE_SUPPORT_VERSION.tgz" INSTALL_BINARY_ALL } function INSTALL_BINARY_ALL_CURL(){ CHECK_CPU FUNC_PRINT_SYSTEM_INFO #下载最新版本包 DOCKER_URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/" SEND_INFO "正在获取最新Docker版本文件" version=$(curl -fsS $DOCKER_URL | awk -F 'href="' '{print $2}' | awk -F '"' '{print $1}' \ | grep -v rootless-extras | grep -oP 'docker-\K[0-9]+\.[0-9]+\.[0-9]+' \ | sort -t. -k1,1n -k2,2n -k3,3n | tail -n 1) URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/docker-${version}.tgz" curl -O $URL #解压问价并安装后清理文件残余 CHECK_COMMAND_NULL tar -zxvf docker-*.tgz SEND_INFO "正在配置 Docker 环境[获取网络资源中,请稍等...]" CHECK_COMMAND_NULL \\cp ./docker/* /usr/local/bin/ curl -so /usr/lib/systemd/system/docker.service https://gitee.com/offends/Kubernetes/raw/main/Docker/Files/docker.service NULL_TRUE rm -rf docker docker-*.tgz CHECK_DIR /etc/docker/ curl -so /etc/docker/daemon.json https://gitee.com/offends/Kubernetes/raw/main/Docker/Files/daemon.json curl -so /etc/sysctl.d/offends.conf https://gitee.com/offends/Kubernetes/raw/main/Docker/Files/offends.conf NULL_TRUE_ECHO sysctl -p /etc/sysctl.d/offends.conf SEND_INFO "正在安装 Docker" INIT_DOCKER } # 二进制安装 Docker 官方最新版本 function INSTALL_BINARY_LATEST(){ CHECK_CPU FUNC_PRINT_SYSTEM_INFO #下载最新版本包 DOCKER_URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/" SEND_INFO "正在获取最新Docker版本文件" version=$(curl -fsS $DOCKER_URL | awk -F 'href="' '{print $2}' | awk -F '"' '{print $1}' \ | grep -v rootless-extras | grep -oP 'docker-\K[0-9]+\.[0-9]+\.[0-9]+' \ | sort -t. -k1,1n -k2,2n -k3,3n | tail -n 1) URL="$INSTALL_DOCKER_PACKAGE/$ARCH_TYPE_1/docker-${version}.tgz" INSTALL_BINARY_ALL } # 开始安装安装 function INSTALL_BINARY_ALL(){ curl -O $URL #解压问价并安装后清理文件残余 INIT_DOCKER_FILE } # 离线安装 function INSTALL_OFFLINE() { FUNC_PRINT_SYSTEM_INFO SEND_INFO "离线安装" CHECK_FILE docker-*.tgz SEND_INFO "正在解压离线包" INIT_DOCKER_FILE } # 初始化 Docker 文件 function INIT_DOCKER_FILE() { CHECK_COMMAND_NULL tar -zxvf docker-*.tgz SEND_INFO "正在配置 Docker 环境" CHECK_COMMAND_NULL \\cp ./docker/* /usr/local/bin/ CHECK_COMMAND_NULL \\cp ./Files/docker.service /usr/lib/systemd/system/docker.service NULL_TRUE rm -rf docker docker-*.tgz INIT_DOCKER_FILE_ME } function INIT_DOCKER_FILE_ME(){ CHECK_DIR /etc/docker/ CHECK_COMMAND_NULL \\cp ./Files/daemon.json /etc/docker/daemon.json CHECK_COMMAND_NULL \\cp ./Files/offends.conf /etc/sysctl.d/offends.conf NULL_TRUE_ECHO sysctl -p /etc/sysctl.d/offends.conf SEND_INFO "正在安装 Docker" INIT_DOCKER } function DOCKER_VERSION_ENV(){ #启动 docker DOCKER_VERSION=$(docker --version | grep -oP 'Docker version \K[0-9.]+') SEND_INFO "正在启动,当前 Docker 版本为: $DOCKER_VERSION" } # 初始化 Docker 环境 function INIT_DOCKER() { #永久关闭防火墙 SEND_INFO "正在检查防火墙配置" NULL_TRUE systemctl stop firewalld NULL_TRUE systemctl disable firewalld NULL_TRUE iptables -F #创建 Dokcer 用户,加入Docker组 SEND_INFO "正在检测 Docker 用户" ADD_USER_GROUP docker docker DOCKER_VERSION_ENV NULL_TRUE systemctl daemon-reload NULL_TRUE systemctl enable --now docker } # 检测某个systemd服务是否存在 function CHECK_SYSTEMD(){ if ! command -v docker >/dev/null 2>&1; then CHECK_NETWORK_STATE $@ else SEND_INFO "Docker 服务已安装,版本为: $(docker --version | grep -oP 'Docker version \K[0-9.]+')" if ! systemctl status docker >/dev/null 2>&1; then SEND_WARN "Docker 服务未启动,正在启动 Docker 服务" if ! systemctl start docker >/dev/null 2>&1; then SEND_ERROR "Docker 服务启动失败,请检查日志排查错误" exit 1 else SEND_INFO "Docker 服务启动成功" fi fi fi } # 执行全部函数 function EXECUTE_ALL_FUNCTION() { if [ ${INSTALL_TYPE} = "privilege" ]; then PRIVILEGE $@ else CHECK_SYSTEMD $@ fi } EXECUTE_ALL_FUNCTION $@