ansible-devops/scripts/k8s-base-setup.sh

521 lines
18 KiB
Bash
Raw Permalink Normal View History

2025-10-29 16:51:59 +08:00
#!/bin/bash
set -euo pipefail
2025-10-30 13:34:25 +08:00
# ========================== 全局配置 ==========================
2025-10-29 16:51:59 +08:00
# 脚本版本
2025-10-30 13:34:25 +08:00
SCRIPT_VERSION="1.8"
2025-10-29 16:51:59 +08:00
# 默认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"
2025-10-30 13:34:25 +08:00
# 颜色定义(终端兼容)
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # 无颜色
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
# 打印工具函数(统一格式)
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"; }
# ========================== 帮助信息 ==========================
2025-10-29 16:51:59 +08:00
usage() {
cat << EOF
Kubernetes Master组件 + nerdctl 完整安装脚本适配内网nerdctl下载
2025-10-30 13:34:25 +08:00
脚本版本:${SCRIPT_VERSION}
功能:
1. 安装K8s组件kubelet/kubeadm/kubectl、nerdctl配置crictl和kubectl补全
2. 卸载K8s组件、nerdctl及相关配置保留containerd
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
前提:
- 需预先安装containerd脚本会自动检测
- 确保能访问内网nerdctl下载地址${NERDCTL_DOWNLOAD_URL}
2025-10-29 16:51:59 +08:00
用法: $0 [选项]
选项:
2025-10-30 13:34:25 +08:00
--install 执行组件安装及配置
--uninstall 执行组件卸载及配置清理保留containerd
--version <ver> 指定K8s版本格式x.y.z如1.30.5,仅与--install配合
--help 显示此帮助信息
--script-version 显示脚本当前版本
2025-10-29 16:51:59 +08:00
示例:
2025-10-30 13:34:25 +08:00
1. 安装默认版本(${DEFAULT_K8S_VERSION}:
sudo $0 --install
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
2. 安装指定版本如1.30.5:
sudo $0 --install --version 1.30.5
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
3. 卸载(需二次确认):
sudo $0 --uninstall
2025-10-29 16:51:59 +08:00
EOF
exit 1
}
2025-10-30 13:34:25 +08:00
# ========================== 前置检查 ==========================
2025-10-29 16:51:59 +08:00
# 检查是否为root用户
check_root() {
if [ "$(id -u)" -ne 0 ]; then
2025-10-30 13:34:25 +08:00
error "请使用root权限运行脚本命令格式sudo $0 ..."
2025-10-29 16:51:59 +08:00
exit 1
fi
2025-10-30 13:34:25 +08:00
success "root权限检查通过"
2025-10-29 16:51:59 +08:00
}
# 检查containerd是否已安装并运行
check_containerd() {
2025-10-30 13:34:25 +08:00
step 1 1 "检查containerd状态"
# 检查是否安装
2025-10-29 16:51:59 +08:00
if ! command -v containerd &> /dev/null; then
2025-10-30 13:34:25 +08:00
error "未检测到containerd请先执行以下命令安装"
2025-10-29 16:51:59 +08:00
exit 1
fi
2025-10-30 13:34:25 +08:00
2025-10-29 16:51:59 +08:00
# 检查版本
local containerd_ver=$(containerd --version | head -n1 | awk '{print $3}')
2025-10-30 13:34:25 +08:00
info "已检测到containerd版本${containerd_ver}"
2025-10-29 16:51:59 +08:00
# 检查运行状态
if ! systemctl is-active --quiet containerd; then
2025-10-30 13:34:25 +08:00
info "containerd未运行尝试启动..."
if systemctl start containerd; then
success "containerd启动成功"
else
error "containerd启动失败请手动执行 'systemctl status containerd' 检查原因"
2025-10-29 16:51:59 +08:00
exit 1
2025-10-30 13:34:25 +08:00
fi
else
success "containerd已处于运行状态"
2025-10-29 16:51:59 +08:00
fi
}
# 校验K8s版本格式x.y.z
validate_version() {
local version=$1
if ! [[ $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
2025-10-30 13:34:25 +08:00
error "无效的K8s版本格式'${version}',正确格式为 x.y.z如1.30.5"
2025-10-29 16:51:59 +08:00
exit 1
fi
2025-10-30 13:34:25 +08:00
success "K8s版本格式校验通过${version}"
2025-10-29 16:51:59 +08:00
}
# 提取主版本如1.30.5 -> 1.30
get_major_version() {
local version=$1
echo "$version" | cut -d '.' -f 1,2
}
2025-10-30 13:34:25 +08:00
# ========================== 安装相关函数 ==========================
2025-10-29 16:51:59 +08:00
# 配置kubectl命令补全
configure_kubectl_completion() {
2025-10-30 13:34:25 +08:00
step 4 4 "配置kubectl命令补全"
2025-10-29 16:51:59 +08:00
# 安装bash-completion依赖
2025-10-30 13:34:25 +08:00
info "安装bash-completion依赖..."
if apt-get install -y -qq bash-completion; then
success "bash-completion安装完成"
else
error "bash-completion安装失败"
exit 1
fi
2025-10-29 16:51:59 +08:00
# 写入补全配置到全局profile所有用户生效
local bash_profile="/etc/profile.d/kubectl-completion.sh"
if ! grep -q "source <(kubectl completion bash)" "$bash_profile" 2>/dev/null; then
2025-10-30 13:34:25 +08:00
info "添加kubectl补全配置到 ${bash_profile}..."
2025-10-29 16:51:59 +08:00
echo "source <(kubectl completion bash)" | tee -a "$bash_profile" > /dev/null
2025-10-30 13:34:25 +08:00
success "kubectl补全配置写入成功所有用户生效"
2025-10-29 16:51:59 +08:00
else
2025-10-30 13:34:25 +08:00
info "kubectl补全配置已存在跳过写入"
2025-10-29 16:51:59 +08:00
fi
# 立即生效当前会话
2025-10-30 13:34:25 +08:00
info "使当前会话生效kubectl补全..."
2025-10-29 16:51:59 +08:00
source <(kubectl completion bash)
2025-10-30 13:34:25 +08:00
success "kubectl命令补全配置完成当前会话已生效"
2025-10-29 16:51:59 +08:00
}
# 安装nerdctl使用用户指定的内网下载地址
install_nerdctl() {
2025-10-30 13:34:25 +08:00
step 3 4 "安装nerdctl并配置crictl"
2025-10-29 16:51:59 +08:00
# 优先通过系统仓库安装(兼容性更好)
if apt-cache show nerdctl &> /dev/null; then
2025-10-30 13:34:25 +08:00
info "系统仓库存在nerdctl通过apt安装..."
if apt-get install -y -qq nerdctl; then
success "nerdctl通过系统仓库安装完成"
else
error "nerdctl系统仓库安装失败"
exit 1
fi
2025-10-29 16:51:59 +08:00
else
2025-10-30 13:34:25 +08:00
# 系统仓库无则使用内网地址下载二进制包
info "系统仓库无nerdctl从内网地址下载${NERDCTL_DOWNLOAD_URL}"
2025-10-29 16:51:59 +08:00
# 下载二进制包到临时目录
2025-10-30 13:34:25 +08:00
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} 测试)"
2025-10-29 16:51:59 +08:00
exit 1
fi
2025-10-30 13:34:25 +08:00
2025-10-29 16:51:59 +08:00
# 解压到/usr/local/bin系统可执行路径
2025-10-30 13:34:25 +08:00
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
2025-10-29 16:51:59 +08:00
# 清理临时文件
2025-10-30 13:34:25 +08:00
info "清理临时压缩包..."
2025-10-29 16:51:59 +08:00
rm -f /tmp/nerdctl.tar.gz
2025-10-30 13:34:25 +08:00
success "临时文件清理完成"
2025-10-29 16:51:59 +08:00
fi
# 配置crictl连接containerd
2025-10-30 13:34:25 +08:00
info "配置crictl连接containerd运行时..."
if crictl config runtime-endpoint unix:///run/containerd/containerd.sock; then
success "crictl配置完成已关联containerd"
else
error "crictl配置失败"
2025-10-29 16:51:59 +08:00
exit 1
2025-10-30 13:34:25 +08:00
fi
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
# 验证nerdctl安装
info "验证nerdctl版本..."
local nerdctl_ver=$(nerdctl --version | awk '{print $3}')
success "nerdctl安装完成版本${nerdctl_ver}"
2025-10-29 16:51:59 +08:00
}
# 安装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
2025-10-30 13:34:25 +08:00
info "开始执行Kubernetes组件安装目标版本${k8s_version}"
2025-10-29 16:51:59 +08:00
# 1. 更新系统并安装基础依赖
2025-10-30 13:34:25 +08:00
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密钥目录准备完成"
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
# 2. 添加阿里云K8s GPG密钥
step 2 4 "添加K8s GPG密钥与软件源"
2025-10-29 16:51:59 +08:00
local key_url="${ALIBABA_MIRROR_BASE}/v${major_version}/deb/Release.key"
2025-10-30 13:34:25 +08:00
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检查是否有效或更换网络环境"
2025-10-29 16:51:59 +08:00
exit 1
fi
# 3. 添加K8s软件源
local repo_url="${ALIBABA_MIRROR_BASE}/v${major_version}/deb/"
2025-10-30 13:34:25 +08:00
info "配置K8s软件源地址${repo_url}"
2025-10-29 16:51:59 +08:00
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] $repo_url /" | \
tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
2025-10-30 13:34:25 +08:00
success "K8s软件源配置完成保存到 /etc/apt/sources.list.d/kubernetes.list"
2025-10-29 16:51:59 +08:00
# 4. 刷新软件源
2025-10-30 13:34:25 +08:00
info "刷新新配置的软件源..."
if apt-get update -qq; then
success "软件源刷新完成"
else
error "软件源刷新失败,请检查网络或源地址"
2025-10-29 16:51:59 +08:00
exit 1
2025-10-30 13:34:25 +08:00
fi
2025-10-29 16:51:59 +08:00
# 5. 安装指定版本的K8s组件
2025-10-30 13:34:25 +08:00
step 3 4 "安装K8s核心组件kubelet/kubeadm/kubectl"
info "安装目标版本:${deb_version}..."
2025-10-31 09:46:34 +08:00
#调试 历史去掉-qq
if apt-get install -y --allow-downgrades\
2025-10-29 16:51:59 +08:00
kubelet="$deb_version" \
kubeadm="$deb_version" \
2025-10-30 13:34:25 +08:00
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"
2025-10-29 16:51:59 +08:00
exit 1
fi
# 6. 配置kubelet锁定版本+自启)
2025-10-30 13:34:25 +08:00
info "锁定K8s组件版本防止意外升级..."
2025-10-29 16:51:59 +08:00
apt-mark hold kubelet kubeadm kubectl > /dev/null
2025-10-30 13:34:25 +08:00
success "K8s组件版本锁定完成"
info "设置kubelet开机自启并启动..."
if systemctl enable kubelet --now; then
success "kubelet配置完成已开机自启并启动"
else
error "kubelet启动失败请执行 'systemctl status kubelet' 检查原因"
2025-10-29 16:51:59 +08:00
exit 1
2025-10-30 13:34:25 +08:00
fi
2025-10-29 16:51:59 +08:00
# 验证K8s组件安装
2025-10-30 13:34:25 +08:00
info "验证K8s组件版本..."
local kubelet_ver=$(kubelet --version | awk '{print $2}')
success "K8s核心组件安装验证通过版本${kubelet_ver}"
2025-10-29 16:51:59 +08:00
# 安装nerdctl使用内网地址
install_nerdctl
# 配置kubectl补全
configure_kubectl_completion
2025-10-30 13:34:25 +08:00
# 安装完成汇总
echo -e "\n========================================"
success "所有组件安装及配置全部完成!"
echo -e "${YELLOW}[汇总信息]${NC}"
echo " - K8s版本${k8s_version}"
echo " - nerdctl版本$(nerdctl --version | awk '{print $3}')"
echo " - 下一步:执行 'kubeadm init' 初始化集群(需根据网络配置参数)"
echo -e "========================================"
2025-10-29 16:51:59 +08:00
}
2025-10-30 13:34:25 +08:00
# ========================== 卸载相关函数 ==========================
2025-10-29 16:51:59 +08:00
# 卸载组件及配置保留containerd
uninstall_k8s() {
2025-10-30 13:34:25 +08:00
# 二次确认(防止误操作)
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个步骤"
2025-10-29 16:51:59 +08:00
# 1. 停止kubelet服务
2025-10-30 13:34:25 +08:00
step 1 6 "停止kubelet服务"
2025-10-29 16:51:59 +08:00
if systemctl is-active --quiet kubelet; then
2025-10-30 13:34:25 +08:00
info "kubelet当前处于运行状态正在停止..."
if systemctl stop kubelet; then
success "kubelet停止成功"
else
error "kubelet停止失败将强制继续卸载"
fi
else
info "kubelet已处于停止状态跳过停止步骤"
2025-10-29 16:51:59 +08:00
fi
# 2. 卸载K8s组件
2025-10-30 13:34:25 +08:00
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
2025-10-29 16:51:59 +08:00
# 3. 卸载nerdctl
2025-10-30 13:34:25 +08:00
step 3 6 "卸载nerdctl"
2025-10-29 16:51:59 +08:00
if command -v nerdctl &> /dev/null; then
2025-10-30 13:34:25 +08:00
info "检测到nerdctl正在卸载..."
2025-10-29 16:51:59 +08:00
# 根据安装方式选择卸载方法(系统仓库或二进制)
2025-10-30 13:34:25 +08:00
if dpkg -l | grep -q nerdctl; then
# 系统仓库安装apt卸载
if apt-get purge -y -qq nerdctl; then
success "nerdctl系统仓库版卸载完成"
else
error "nerdctl卸载失败"
exit 1
fi
2025-10-29 16:51:59 +08:00
else
2025-10-30 13:34:25 +08:00
# 二进制安装:删除文件
if rm -f /usr/local/bin/nerdctl; then
success "nerdctl二进制版删除完成"
else
error "nerdctl删除失败建议手动执行 'rm -f /usr/local/bin/nerdctl'"
exit 1
fi
2025-10-29 16:51:59 +08:00
fi
2025-10-30 13:34:25 +08:00
else
info "未检测到nerdctl跳过卸载步骤"
2025-10-29 16:51:59 +08:00
fi
2025-10-30 13:34:25 +08:00
# 4. 清理依赖残留
step 4 6 "清理系统依赖残留"
info "执行autoremove清理无用依赖..."
if apt-get autoremove -y -qq; then
success "系统依赖残留清理完成"
else
error "依赖残留清理失败,建议手动执行 'apt-get autoremove -y'"
2025-10-29 16:51:59 +08:00
fi
2025-10-30 13:34:25 +08:00
# 5. 解锁版本锁定
step 5 6 "解除版本锁定"
info "解除K8s组件和nerdctl的版本锁定..."
apt-mark unhold kubelet kubeadm kubectl nerdctl > /dev/null 2>&1 || true
success "版本锁定解除完成(无锁定则跳过)"
# 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
2025-10-29 16:51:59 +08:00
2025-10-30 13:34:25 +08:00
# 刷新软件源(确保清理生效)
info "刷新系统软件源,确保配置清理生效..."
apt-get update -qq > /dev/null
success "软件源刷新完成"
# 卸载完成汇总
echo -e "\n========================================"
success "卸载流程全部完成!"
echo -e "${YELLOW}[残留说明]${NC}"
echo " - 已保留containerd及相关配置"
echo " - 建议:若需重新安装,直接执行 '--install' 选项即可"
echo -e "========================================"
2025-10-29 16:51:59 +08:00
}
2025-10-30 13:34:25 +08:00
# ========================== 主逻辑 ==========================
2025-10-29 16:51:59 +08:00
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
2025-10-30 13:34:25 +08:00
error "--version选项需指定K8s版本如1.30.5"
2025-10-29 16:51:59 +08:00
usage
fi
k8s_version="$2"
shift 2
;;
--help)
usage
;;
--script-version)
2025-10-30 13:34:25 +08:00
echo "脚本版本:${SCRIPT_VERSION}"
2025-10-29 16:51:59 +08:00
exit 0
;;
*)
2025-10-30 13:34:25 +08:00
error "未知参数:'$1'"
2025-10-29 16:51:59 +08:00
usage
;;
esac
done
# 检查参数冲突
if [[ $install -eq 1 && $uninstall -eq 1 ]]; then
2025-10-30 13:34:25 +08:00
error "不能同时指定--install和--uninstall选项"
2025-10-29 16:51:59 +08:00
usage
fi
if [[ $install -eq 0 && $uninstall -eq 0 ]]; then
2025-10-30 13:34:25 +08:00
error "必须指定--install安装或--uninstall卸载选项"
2025-10-29 16:51:59 +08:00
usage
fi
2025-10-30 13:34:25 +08:00
# 检查root权限安装/卸载均需)
2025-10-29 16:51:59 +08:00
check_root
# 处理安装逻辑
if [[ $install -eq 1 ]]; then
# 未指定版本则使用默认
if [[ -z "$k8s_version" ]]; then
k8s_version="$DEFAULT_K8S_VERSION"
2025-10-30 13:34:25 +08:00
info "未指定K8s版本使用默认版本${k8s_version}"
2025-10-29 16:51:59 +08:00
fi
# 校验版本格式
validate_version "$k8s_version"
# 执行安装
install_k8s "$k8s_version"
fi
# 处理卸载逻辑
if [[ $uninstall -eq 1 ]]; then
uninstall_k8s
fi
}
# 启动主逻辑
main "$@"