From a1286cfcbf6c5f1166e137b024eec9c5169583fc Mon Sep 17 00:00:00 2001 From: joy Date: Thu, 30 Oct 2025 13:34:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20scripts/k8s-base-setup.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aaadf --- scripts/k8s-base-setup.sh | 418 +++++++++++++++++++++++++++----------- 1 file changed, 295 insertions(+), 123 deletions(-) diff --git a/scripts/k8s-base-setup.sh b/scripts/k8s-base-setup.sh index 9c264a8..76bf364 100644 --- a/scripts/k8s-base-setup.sh +++ b/scripts/k8s-base-setup.sh @@ -1,8 +1,9 @@ #!/bin/bash set -euo pipefail +# ========================== 全局配置 ========================== # 脚本版本 -SCRIPT_VERSION="1.7" +SCRIPT_VERSION="1.8" # 默认K8s版本 DEFAULT_K8S_VERSION="1.30.5" # 阿里云K8s镜像基础路径(验证有效) @@ -10,62 +11,92 @@ ALIBABA_MIRROR_BASE="https://mirrors.aliyun.com/kubernetes-new/core/stable" # 用户指定的nerdctl内网下载地址 NERDCTL_DOWNLOAD_URL="http://10.102.32.207:5588/k8s/nerdctl-1.5.0-linux-amd64.tar.gz" +# 颜色定义(终端兼容) +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # 无颜色 -# 帮助信息 +# 打印工具函数(统一格式) +info() { echo -e "${YELLOW}[INFO]${NC} $1"; } +success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; } +step() { echo -e "\n${YELLOW}[STEP $1/$2]${NC} $3"; } + + +# ========================== 帮助信息 ========================== usage() { cat << EOF Kubernetes Master组件 + nerdctl 完整安装脚本(适配内网nerdctl下载) +脚本版本:${SCRIPT_VERSION} -功能:安装/卸载K8s组件(kubelet/kubeadm/kubectl)、nerdctl,配置crictl和kubectl补全 -前提:需预先安装containerd(脚本会自动检测);确保能访问内网nerdctl下载地址 +功能: + 1. 安装:K8s组件(kubelet/kubeadm/kubectl)、nerdctl,配置crictl和kubectl补全 + 2. 卸载:K8s组件、nerdctl及相关配置(保留containerd) + +前提: + - 需预先安装containerd(脚本会自动检测) + - 确保能访问内网nerdctl下载地址:${NERDCTL_DOWNLOAD_URL} 用法: $0 [选项] 选项: - --install 安装组件及配置 - --uninstall 卸载组件及配置(保留containerd) - --version 指定K8s版本(如1.30.5,仅与--install配合) - --help 显示帮助信息 - --script-version 显示脚本版本 + --install 执行组件安装及配置 + --uninstall 执行组件卸载及配置清理(保留containerd) + --version 指定K8s版本(格式x.y.z,如1.30.5,仅与--install配合) + --help 显示此帮助信息 + --script-version 显示脚本当前版本 示例: - 安装默认版本: - sudo $0 --install + 1. 安装默认版本(${DEFAULT_K8S_VERSION}): + sudo $0 --install - 安装指定版本: - sudo $0 --install --version 1.30.5 + 2. 安装指定版本(如1.30.5): + sudo $0 --install --version 1.30.5 - 卸载: - sudo $0 --uninstall + 3. 卸载(需二次确认): + sudo $0 --uninstall EOF exit 1 } + +# ========================== 前置检查 ========================== # 检查是否为root用户 check_root() { if [ "$(id -u)" -ne 0 ]; then - echo "错误:请使用root权限运行(sudo $0 ...)" + error "请使用root权限运行脚本,命令格式:sudo $0 ..." exit 1 fi + success "root权限检查通过" } # 检查containerd是否已安装并运行 check_containerd() { + step 1 1 "检查containerd状态" + + # 检查是否安装 if ! command -v containerd &> /dev/null; then - echo "错误:未检测到containerd,请先执行以下命令安装:" - echo "sudo apt-get update && sudo apt-get install -y containerd" + error "未检测到containerd,请先执行以下命令安装:" + echo " sudo apt-get update && sudo apt-get install -y containerd" exit 1 fi + # 检查版本 local containerd_ver=$(containerd --version | head -n1 | awk '{print $3}') - echo "检测到已安装containerd,版本:$containerd_ver" + info "已检测到containerd,版本:${containerd_ver}" + # 检查运行状态 if ! systemctl is-active --quiet containerd; then - echo "警告:containerd未运行,尝试启动..." - systemctl start containerd || { - echo "错误:启动containerd失败,请手动检查状态" + info "containerd未运行,尝试启动..." + if systemctl start containerd; then + success "containerd启动成功" + else + error "containerd启动失败,请手动执行 'systemctl status containerd' 检查原因" exit 1 - } + fi + else + success "containerd已处于运行状态" fi } @@ -73,9 +104,10 @@ check_containerd() { validate_version() { local version=$1 if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - echo "错误:无效的K8s版本格式 '$version',正确格式为 x.y.z(如1.30.5)" + error "无效的K8s版本格式:'${version}',正确格式为 x.y.z(如1.30.5)" exit 1 fi + success "K8s版本格式校验通过:${version}" } # 提取主版本(如1.30.5 -> 1.30) @@ -84,62 +116,93 @@ get_major_version() { echo "$version" | cut -d '.' -f 1,2 } + +# ========================== 安装相关函数 ========================== # 配置kubectl命令补全 configure_kubectl_completion() { - echo -e "\n===== 配置kubectl命令补全 =====" + step 4 4 "配置kubectl命令补全" + # 安装bash-completion依赖 - apt-get install -y -qq bash-completion > /dev/null + info "安装bash-completion依赖..." + if apt-get install -y -qq bash-completion; then + success "bash-completion安装完成" + else + error "bash-completion安装失败" + exit 1 + fi # 写入补全配置到全局profile(所有用户生效) local bash_profile="/etc/profile.d/kubectl-completion.sh" if ! grep -q "source <(kubectl completion bash)" "$bash_profile" 2>/dev/null; then + info "添加kubectl补全配置到 ${bash_profile}..." echo "source <(kubectl completion bash)" | tee -a "$bash_profile" > /dev/null - echo "已添加kubectl补全配置到 $bash_profile(所有用户生效)" + success "kubectl补全配置写入成功(所有用户生效)" else - echo "kubectl补全配置已存在,跳过写入" + info "kubectl补全配置已存在,跳过写入" fi # 立即生效当前会话 + info "使当前会话生效kubectl补全..." source <(kubectl completion bash) - echo "kubectl命令补全已生效(当前会话)" + success "kubectl命令补全配置完成(当前会话已生效)" } # 安装nerdctl(使用用户指定的内网下载地址) install_nerdctl() { - echo -e "\n===== 开始安装nerdctl =====" - + step 3 4 "安装nerdctl并配置crictl" + # 优先通过系统仓库安装(兼容性更好) if apt-cache show nerdctl &> /dev/null; then - echo "通过系统仓库安装nerdctl..." - apt-get install -y -qq nerdctl > /dev/null - else - # 系统仓库无则使用用户指定的内网地址下载 - echo "系统仓库无nerdctl,从内网地址下载:$NERDCTL_DOWNLOAD_URL" - # 下载二进制包到临时目录 - if ! curl -fsSL "$NERDCTL_DOWNLOAD_URL" -o /tmp/nerdctl.tar.gz; then - echo "错误:从内网地址下载nerdctl失败,请检查:" - echo "1. 内网地址是否可访问($NERDCTL_DOWNLOAD_URL)" - echo "2. 网络是否连通(可尝试 curl $NERDCTL_DOWNLOAD_URL 测试)" + info "系统仓库存在nerdctl,通过apt安装..." + if apt-get install -y -qq nerdctl; then + success "nerdctl通过系统仓库安装完成" + else + error "nerdctl系统仓库安装失败" exit 1 fi + else + # 系统仓库无则使用内网地址下载二进制包 + info "系统仓库无nerdctl,从内网地址下载:${NERDCTL_DOWNLOAD_URL}" + + # 下载二进制包到临时目录 + info "开始下载nerdctl压缩包..." + if curl -fsSL "$NERDCTL_DOWNLOAD_URL" -o /tmp/nerdctl.tar.gz; then + success "nerdctl压缩包下载完成(保存到 /tmp/nerdctl.tar.gz)" + else + error "nerdctl下载失败,请检查:" + echo " 1. 内网地址是否可访问:${NERDCTL_DOWNLOAD_URL}" + echo " 2. 网络连通性(可执行 curl ${NERDCTL_DOWNLOAD_URL} 测试)" + exit 1 + fi + # 解压到/usr/local/bin(系统可执行路径) - tar -zxf /tmp/nerdctl.tar.gz -C /usr/local/bin nerdctl > /dev/null + info "解压nerdctl到 /usr/local/bin..." + if tar -zxf /tmp/nerdctl.tar.gz -C /usr/local/bin nerdctl; then + success "nerdctl解压完成" + else + error "nerdctl解压失败" + exit 1 + fi + # 清理临时文件 + info "清理临时压缩包..." rm -f /tmp/nerdctl.tar.gz - echo "nerdctl二进制包已解压到 /usr/local/bin" + success "临时文件清理完成" fi # 配置crictl连接containerd - echo -e "\n===== 配置crictl连接containerd =====" - crictl config runtime-endpoint unix:///run/containerd/containerd.sock || { - echo "错误:配置crictl失败" + info "配置crictl连接containerd运行时..." + if crictl config runtime-endpoint unix:///run/containerd/containerd.sock; then + success "crictl配置完成(已关联containerd)" + else + error "crictl配置失败" exit 1 - } - echo "crictl已配置为连接containerd运行时" + fi - # 验证安装 - echo "===== nerdctl安装完成!版本信息:=====" - nerdctl --version + # 验证nerdctl安装 + info "验证nerdctl版本..." + local nerdctl_ver=$(nerdctl --version | awk '{print $3}') + success "nerdctl安装完成,版本:${nerdctl_ver}" } # 安装Kubernetes组件(核心流程) @@ -151,59 +214,91 @@ install_k8s() { # 前置检查:containerd check_containerd - echo "===== 开始安装Kubernetes组件(版本: $k8s_version) =====" + info "开始执行Kubernetes组件安装,目标版本:${k8s_version}" # 1. 更新系统并安装基础依赖 - echo "[1/6] 更新系统包索引并安装依赖..." - apt-get update -qq > /dev/null - apt-get install -y -qq apt-transport-https ca-certificates curl lsb-release bash-completion > /dev/null - mkdir -p /etc/apt/keyrings # 确保密钥目录存在 + step 1 4 "安装K8s基础依赖" + info "更新系统包索引..." + if apt-get update -qq; then + success "系统包索引更新完成" + else + error "系统包索引更新失败,请检查网络" + exit 1 + fi + + info "安装基础依赖(apt-transport-https/ca-certificates等)..." + if apt-get install -y -qq apt-transport-https ca-certificates curl lsb-release bash-completion; then + success "基础依赖安装完成" + else + error "基础依赖安装失败" + exit 1 + fi + + # 确保密钥目录存在 + info "创建apt密钥目录(/etc/apt/keyrings)..." + mkdir -p /etc/apt/keyrings + success "apt密钥目录准备完成" - # 2. 添加阿里云K8s GPG密钥(强制覆盖,无交互) - echo "[2/6] 添加Kubernetes GPG密钥..." + # 2. 添加阿里云K8s GPG密钥 + step 2 4 "添加K8s GPG密钥与软件源" local key_url="${ALIBABA_MIRROR_BASE}/v${major_version}/deb/Release.key" - if ! curl -fsSL "$key_url" | gpg --dearmor > /etc/apt/keyrings/kubernetes-apt-keyring.gpg 2>/dev/null; then - echo "错误:获取K8s GPG密钥失败(URL: $key_url)" - echo "建议:手动访问URL检查是否有效,或更换网络环境" + info "下载K8s GPG密钥,地址:${key_url}" + if curl -fsSL "$key_url" | gpg --dearmor > /etc/apt/keyrings/kubernetes-apt-keyring.gpg 2>/dev/null; then + success "K8s GPG密钥添加完成(保存到 /etc/apt/keyrings/kubernetes-apt-keyring.gpg)" + else + error "K8s GPG密钥获取失败,URL:${key_url}" + echo " 建议:手动访问URL检查是否有效,或更换网络环境" exit 1 fi # 3. 添加K8s软件源 - echo "[3/6] 配置Kubernetes软件源..." local repo_url="${ALIBABA_MIRROR_BASE}/v${major_version}/deb/" + info "配置K8s软件源,地址:${repo_url}" echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] $repo_url /" | \ tee /etc/apt/sources.list.d/kubernetes.list > /dev/null + success "K8s软件源配置完成(保存到 /etc/apt/sources.list.d/kubernetes.list)" # 4. 刷新软件源 - echo "[4/6] 加载新软件源..." - apt-get update -qq > /dev/null || { - echo "错误:刷新软件源失败,请检查网络" + info "刷新新配置的软件源..." + if apt-get update -qq; then + success "软件源刷新完成" + else + error "软件源刷新失败,请检查网络或源地址" exit 1 - } + fi # 5. 安装指定版本的K8s组件 - echo "[5/6] 安装kubelet、kubeadm、kubectl(版本: $deb_version)..." - if ! apt-get install -y -qq \ + step 3 4 "安装K8s核心组件(kubelet/kubeadm/kubectl)" + info "安装目标版本:${deb_version}..." + if apt-get install -y -qq --allow-downgrades\ kubelet="$deb_version" \ kubeadm="$deb_version" \ - kubectl="$deb_version" > /dev/null 2>&1; then - echo "错误:安装K8s组件失败,可能版本不存在" - echo "建议:执行 'apt-cache madison kubeadm' 查看可用版本" + kubectl="$deb_version"; then + success "K8s组件安装完成(版本:${k8s_version})" + else + error "K8s组件安装失败,可能原因:" + echo " 1. 版本 ${deb_version} 不存在(可执行 'apt-cache madison kubeadm' 查看可用版本)" + echo " 2. 软件源配置错误(检查 /etc/apt/sources.list.d/kubernetes.list)" exit 1 fi # 6. 配置kubelet(锁定版本+自启) - echo "[6/6] 配置kubelet服务..." + info "锁定K8s组件版本(防止意外升级)..." apt-mark hold kubelet kubeadm kubectl > /dev/null - systemctl enable kubelet --now || { - echo "错误:启动kubelet失败" + success "K8s组件版本锁定完成" + + info "设置kubelet开机自启并启动..." + if systemctl enable kubelet --now; then + success "kubelet配置完成(已开机自启并启动)" + else + error "kubelet启动失败,请执行 'systemctl status kubelet' 检查原因" exit 1 - } - echo "kubelet已设置为开机自启并启动成功" + fi # 验证K8s组件安装 - echo -e "\n===== K8s组件安装完成!版本信息:=====" - kubelet --version + info "验证K8s组件版本..." + local kubelet_ver=$(kubelet --version | awk '{print $2}') + success "K8s核心组件安装验证通过,版本:${kubelet_ver}" # 安装nerdctl(使用内网地址) install_nerdctl @@ -211,61 +306,146 @@ install_k8s() { # 配置kubectl补全 configure_kubectl_completion - echo -e "\n===== 所有组件安装及配置完成 =====" - echo "下一步可执行 'kubeadm init' 初始化集群(需根据网络配置参数)" + # 安装完成汇总 + echo -e "\n========================================" + success "所有组件安装及配置全部完成!" + echo -e "${YELLOW}[汇总信息]${NC}" + echo " - K8s版本:${k8s_version}" + echo " - nerdctl版本:$(nerdctl --version | awk '{print $3}')" + echo " - 下一步:执行 'kubeadm init' 初始化集群(需根据网络配置参数)" + echo -e "========================================" } + +# ========================== 卸载相关函数 ========================== # 卸载组件及配置(保留containerd) uninstall_k8s() { - echo "===== 开始卸载组件 =====" + # 二次确认(防止误操作) + echo -e "\n${RED}[WARNING]${NC} 即将执行卸载操作,将移除以下内容:" + echo " 1. K8s组件:kubelet、kubeadm、kubectl" + echo " 2. 工具:nerdctl" + echo " 3. 配置:crictl配置、kubectl补全、K8s软件源及密钥" + echo " 4. 数据目录:/var/lib/kubelet、/etc/kubernetes、/var/lib/etcd等" + echo -e "${RED}注意:此操作不可逆,且会保留containerd!${NC}" + read -p "请确认是否继续卸载?[y/N] " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + info "用户取消卸载操作,脚本退出" + exit 0 + fi + + info "开始执行卸载流程,共6个步骤" # 1. 停止kubelet服务 - echo "[1/5] 停止kubelet服务..." + step 1 6 "停止kubelet服务" if systemctl is-active --quiet kubelet; then - systemctl stop kubelet > /dev/null + info "kubelet当前处于运行状态,正在停止..." + if systemctl stop kubelet; then + success "kubelet停止成功" + else + error "kubelet停止失败,将强制继续卸载" + fi + else + info "kubelet已处于停止状态,跳过停止步骤" fi # 2. 卸载K8s组件 - echo "[2/5] 卸载kubelet、kubeadm、kubectl..." - apt-get purge -y -qq kubelet kubeadm kubectl > /dev/null - apt-get autoremove -y -qq > /dev/null + step 2 6 "卸载K8s核心组件" + if dpkg -l | grep -qE "kubelet|kubeadm|kubectl"; then + info "检测到K8s组件,正在卸载..." + if apt-get purge -y -qq kubelet kubeadm kubectl; then + success "K8s组件卸载完成" + else + error "K8s组件卸载失败,建议手动执行 'apt-get purge -y kubelet kubeadm kubectl'" + exit 1 + fi + else + info "未检测到K8s组件,跳过卸载步骤" + fi # 3. 卸载nerdctl - echo "[3/5] 卸载nerdctl..." + step 3 6 "卸载nerdctl" if command -v nerdctl &> /dev/null; then + info "检测到nerdctl,正在卸载..." # 根据安装方式选择卸载方法(系统仓库或二进制) - if dpkg -l nerdctl &> /dev/null; then - apt-get purge -y -qq nerdctl > /dev/null + if dpkg -l | grep -q nerdctl; then + # 系统仓库安装:apt卸载 + if apt-get purge -y -qq nerdctl; then + success "nerdctl(系统仓库版)卸载完成" + else + error "nerdctl卸载失败" + exit 1 + fi else - rm -f /usr/local/bin/nerdctl # 清理内网下载的二进制文件 + # 二进制安装:删除文件 + if rm -f /usr/local/bin/nerdctl; then + success "nerdctl(二进制版)删除完成" + else + error "nerdctl删除失败,建议手动执行 'rm -f /usr/local/bin/nerdctl'" + exit 1 + fi fi + else + info "未检测到nerdctl,跳过卸载步骤" fi - apt-get autoremove -y -qq > /dev/null - # 4. 解锁版本锁定 - echo "[4/5] 解除版本锁定..." + # 4. 清理依赖残留 + step 4 6 "清理系统依赖残留" + info "执行autoremove清理无用依赖..." + if apt-get autoremove -y -qq; then + success "系统依赖残留清理完成" + else + error "依赖残留清理失败,建议手动执行 'apt-get autoremove -y'" + fi + + # 5. 解锁版本锁定 + step 5 6 "解除版本锁定" + info "解除K8s组件和nerdctl的版本锁定..." apt-mark unhold kubelet kubeadm kubectl nerdctl > /dev/null 2>&1 || true + success "版本锁定解除完成(无锁定则跳过)" - # 5. 清理配置文件和数据目录 - echo "[5/5] 清理配置文件和数据目录..." - rm -f /etc/apt/sources.list.d/kubernetes.list - rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg - rm -rf /var/lib/kubelet /etc/kubernetes /var/lib/etcd /var/lib/cni /etc/crictl.yaml > /dev/null 2>&1 || true - - # 清理kubectl补全配置 - local bash_profile="/etc/profile.d/kubectl-completion.sh" - if grep -q "source <(kubectl completion bash)" "$bash_profile" 2>/dev/null; then - sed -i '/source <(kubectl completion bash)/d' "$bash_profile" - echo "已移除kubectl补全配置" - fi + # 6. 清理配置文件和数据目录 + step 6 6 "清理配置文件与数据目录" + local clean_items=( + "/etc/apt/sources.list.d/kubernetes.list" # K8s软件源 + "/etc/apt/keyrings/kubernetes-apt-keyring.gpg" # K8s GPG密钥 + "/var/lib/kubelet" # kubelet数据目录 + "/etc/kubernetes" # K8s配置目录 + "/var/lib/etcd" # etcd数据目录(若存在) + "/var/lib/cni" # CNI网络配置 + "/etc/crictl.yaml" # crictl配置 + "/etc/profile.d/kubectl-completion.sh" # kubectl补全脚本 + ) - # 刷新软件源 + for item in "${clean_items[@]}"; do + if [ -e "$item" ]; then + info "清理文件/目录:${item}" + if rm -rf "$item"; then + success "清理完成:${item}" + else + error "清理失败:${item}(权限不足?)" + fi + else + info "文件/目录不存在,跳过:${item}" + fi + done + + # 刷新软件源(确保清理生效) + info "刷新系统软件源,确保配置清理生效..." apt-get update -qq > /dev/null + success "软件源刷新完成" - echo "===== 卸载完成!已移除K8s组件、nerdctl及相关配置(保留containerd) =====" + # 卸载完成汇总 + echo -e "\n========================================" + success "卸载流程全部完成!" + echo -e "${YELLOW}[残留说明]${NC}" + echo " - 已保留:containerd及相关配置" + echo " - 建议:若需重新安装,直接执行 '--install' 选项即可" + echo -e "========================================" } -# 主逻辑:参数解析与流程控制 + +# ========================== 主逻辑 ========================== main() { local install=0 local uninstall=0 @@ -284,7 +464,7 @@ main() { ;; --version) if [[ -z "$2" ]]; then - echo "错误:--version需要指定版本(如1.30.5)" + error "--version选项需指定K8s版本(如1.30.5)" usage fi k8s_version="$2" @@ -294,11 +474,11 @@ main() { usage ;; --script-version) - echo "脚本版本:$SCRIPT_VERSION" + echo "脚本版本:${SCRIPT_VERSION}" exit 0 ;; *) - echo "错误:未知参数 '$1'" + error "未知参数:'$1'" usage ;; esac @@ -306,15 +486,15 @@ main() { # 检查参数冲突 if [[ $install -eq 1 && $uninstall -eq 1 ]]; then - echo "错误:不能同时指定--install和--uninstall" + error "不能同时指定--install和--uninstall选项" usage fi if [[ $install -eq 0 && $uninstall -eq 0 ]]; then - echo "错误:必须指定--install或--uninstall" + error "必须指定--install(安装)或--uninstall(卸载)选项" usage fi - # 检查root权限 + # 检查root权限(安装/卸载均需) check_root # 处理安装逻辑 @@ -322,7 +502,7 @@ main() { # 未指定版本则使用默认 if [[ -z "$k8s_version" ]]; then k8s_version="$DEFAULT_K8S_VERSION" - echo "未指定版本,将安装默认K8s版本:$k8s_version" + info "未指定K8s版本,使用默认版本:${k8s_version}" fi # 校验版本格式 validate_version "$k8s_version" @@ -332,14 +512,6 @@ main() { # 处理卸载逻辑 if [[ $uninstall -eq 1 ]]; then - # 二次确认(防止误操作) - read -p "确认卸载Kubernetes、nerdctl及相关配置(保留containerd)?[y/N] " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "取消卸载" - exit 0 - fi - # 执行卸载 uninstall_k8s fi }