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

521 lines
18 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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