#!/bin/bash set -euo pipefail # 脚本版本 SCRIPT_VERSION="1.7" # 默认K8s版本 DEFAULT_K8S_VERSION="1.30.5" # 阿里云K8s镜像基础路径(验证有效) 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" # 帮助信息 usage() { cat << EOF Kubernetes Master组件 + nerdctl 完整安装脚本(适配内网nerdctl下载) 功能:安装/卸载K8s组件(kubelet/kubeadm/kubectl)、nerdctl,配置crictl和kubectl补全 前提:需预先安装containerd(脚本会自动检测);确保能访问内网nerdctl下载地址 用法: $0 [选项] 选项: --install 安装组件及配置 --uninstall 卸载组件及配置(保留containerd) --version 指定K8s版本(如1.30.5,仅与--install配合) --help 显示帮助信息 --script-version 显示脚本版本 示例: 安装默认版本: sudo $0 --install 安装指定版本: sudo $0 --install --version 1.30.5 卸载: sudo $0 --uninstall EOF exit 1 } # 检查是否为root用户 check_root() { if [ "$(id -u)" -ne 0 ]; then echo "错误:请使用root权限运行(sudo $0 ...)" exit 1 fi } # 检查containerd是否已安装并运行 check_containerd() { if ! command -v containerd &> /dev/null; then echo "错误:未检测到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" # 检查运行状态 if ! systemctl is-active --quiet containerd; then echo "警告:containerd未运行,尝试启动..." systemctl start containerd || { echo "错误:启动containerd失败,请手动检查状态" exit 1 } fi } # 校验K8s版本格式(x.y.z) validate_version() { local version=$1 if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "错误:无效的K8s版本格式 '$version',正确格式为 x.y.z(如1.30.5)" exit 1 fi } # 提取主版本(如1.30.5 -> 1.30) get_major_version() { local version=$1 echo "$version" | cut -d '.' -f 1,2 } # 配置kubectl命令补全 configure_kubectl_completion() { echo -e "\n===== 配置kubectl命令补全 =====" # 安装bash-completion依赖 apt-get install -y -qq bash-completion > /dev/null # 写入补全配置到全局profile(所有用户生效) local bash_profile="/etc/profile.d/kubectl-completion.sh" if ! grep -q "source <(kubectl completion bash)" "$bash_profile" 2>/dev/null; then echo "source <(kubectl completion bash)" | tee -a "$bash_profile" > /dev/null echo "已添加kubectl补全配置到 $bash_profile(所有用户生效)" else echo "kubectl补全配置已存在,跳过写入" fi # 立即生效当前会话 source <(kubectl completion bash) echo "kubectl命令补全已生效(当前会话)" } # 安装nerdctl(使用用户指定的内网下载地址) install_nerdctl() { echo -e "\n===== 开始安装nerdctl =====" # 优先通过系统仓库安装(兼容性更好) 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 测试)" exit 1 fi # 解压到/usr/local/bin(系统可执行路径) tar -zxf /tmp/nerdctl.tar.gz -C /usr/local/bin nerdctl > /dev/null # 清理临时文件 rm -f /tmp/nerdctl.tar.gz echo "nerdctl二进制包已解压到 /usr/local/bin" fi # 配置crictl连接containerd echo -e "\n===== 配置crictl连接containerd =====" crictl config runtime-endpoint unix:///run/containerd/containerd.sock || { echo "错误:配置crictl失败" exit 1 } echo "crictl已配置为连接containerd运行时" # 验证安装 echo "===== nerdctl安装完成!版本信息:=====" nerdctl --version } # 安装Kubernetes组件(核心流程) install_k8s() { local k8s_version=$1 local major_version=$(get_major_version "$k8s_version") local deb_version="${k8s_version}-1.1" # 前置检查:containerd check_containerd echo "===== 开始安装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 # 确保密钥目录存在 # 2. 添加阿里云K8s GPG密钥(强制覆盖,无交互) echo "[2/6] 添加Kubernetes 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检查是否有效,或更换网络环境" exit 1 fi # 3. 添加K8s软件源 echo "[3/6] 配置Kubernetes软件源..." local repo_url="${ALIBABA_MIRROR_BASE}/v${major_version}/deb/" echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] $repo_url /" | \ tee /etc/apt/sources.list.d/kubernetes.list > /dev/null # 4. 刷新软件源 echo "[4/6] 加载新软件源..." apt-get update -qq > /dev/null || { echo "错误:刷新软件源失败,请检查网络" exit 1 } # 5. 安装指定版本的K8s组件 echo "[5/6] 安装kubelet、kubeadm、kubectl(版本: $deb_version)..." if ! apt-get install -y -qq \ kubelet="$deb_version" \ kubeadm="$deb_version" \ kubectl="$deb_version" > /dev/null 2>&1; then echo "错误:安装K8s组件失败,可能版本不存在" echo "建议:执行 'apt-cache madison kubeadm' 查看可用版本" exit 1 fi # 6. 配置kubelet(锁定版本+自启) echo "[6/6] 配置kubelet服务..." apt-mark hold kubelet kubeadm kubectl > /dev/null systemctl enable kubelet --now || { echo "错误:启动kubelet失败" exit 1 } echo "kubelet已设置为开机自启并启动成功" # 验证K8s组件安装 echo -e "\n===== K8s组件安装完成!版本信息:=====" kubelet --version # 安装nerdctl(使用内网地址) install_nerdctl # 配置kubectl补全 configure_kubectl_completion echo -e "\n===== 所有组件安装及配置完成 =====" echo "下一步可执行 'kubeadm init' 初始化集群(需根据网络配置参数)" } # 卸载组件及配置(保留containerd) uninstall_k8s() { echo "===== 开始卸载组件 =====" # 1. 停止kubelet服务 echo "[1/5] 停止kubelet服务..." if systemctl is-active --quiet kubelet; then systemctl stop kubelet > /dev/null 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 # 3. 卸载nerdctl echo "[3/5] 卸载nerdctl..." if command -v nerdctl &> /dev/null; then # 根据安装方式选择卸载方法(系统仓库或二进制) if dpkg -l nerdctl &> /dev/null; then apt-get purge -y -qq nerdctl > /dev/null else rm -f /usr/local/bin/nerdctl # 清理内网下载的二进制文件 fi fi apt-get autoremove -y -qq > /dev/null # 4. 解锁版本锁定 echo "[4/5] 解除版本锁定..." apt-mark unhold kubelet kubeadm kubectl nerdctl > /dev/null 2>&1 || true # 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 # 刷新软件源 apt-get update -qq > /dev/null echo "===== 卸载完成!已移除K8s组件、nerdctl及相关配置(保留containerd) =====" } # 主逻辑:参数解析与流程控制 main() { local install=0 local uninstall=0 local k8s_version="" # 解析命令行参数 while [[ $# -gt 0 ]]; do case "$1" in --install) install=1 shift ;; --uninstall) uninstall=1 shift ;; --version) if [[ -z "$2" ]]; then echo "错误:--version需要指定版本(如1.30.5)" usage fi k8s_version="$2" shift 2 ;; --help) usage ;; --script-version) echo "脚本版本:$SCRIPT_VERSION" exit 0 ;; *) echo "错误:未知参数 '$1'" usage ;; esac done # 检查参数冲突 if [[ $install -eq 1 && $uninstall -eq 1 ]]; then echo "错误:不能同时指定--install和--uninstall" usage fi if [[ $install -eq 0 && $uninstall -eq 0 ]]; then echo "错误:必须指定--install或--uninstall" usage fi # 检查root权限 check_root # 处理安装逻辑 if [[ $install -eq 1 ]]; then # 未指定版本则使用默认 if [[ -z "$k8s_version" ]]; then k8s_version="$DEFAULT_K8S_VERSION" echo "未指定版本,将安装默认K8s版本:$k8s_version" fi # 校验版本格式 validate_version "$k8s_version" # 执行安装 install_k8s "$k8s_version" fi # 处理卸载逻辑 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 } # 启动主逻辑 main "$@"