Kubernetes/Docker/install.sh
offends 7a2f41e7d6
All checks were successful
continuous-integration/drone Build is passing
synchronization
2024-08-07 18:54:39 +08:00

520 lines
18 KiB
Bash
Executable File

#!/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 $@