#!/bin/bash # --------------------------------------------------------- # Kubernetes (K8s) 高可用集群自动化脚本 (Ubuntu 终极可用版) # --------------------------------------------------------- # ================= 变量配置区 (执行前请核对以下 IP) ================= K8S_VERSION="1.28.2-*" POD_SUBNET="10.244.0.0/16" SERVICE_SUBNET="10.96.0.0/12" # 1. 高可用 VIP 配置 (你的 Keepalived 虚拟IP) VIP="192.168.40.100" VIP_PORT="16443" # 自动获取当前机器的主网卡名称 VIP_INTERFACE=$(ip route | grep default | awk '{print $5}' | head -n 1) # 2. 你的三台 Master 节点真实 IP MASTER01_IP="192.168.40.10" MASTER02_IP="192.168.40.11" MASTER03_IP="192.168.40.12" CONTROL_PLANE_ENDPOINT="${VIP}:${VIP_PORT}" # =============================================================== RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' export DEBIAN_FRONTEND=noninteractive if [ "$EUID" -ne 0 ]; then echo -e "${RED}请使用 root 权限运行此脚本!(sudo -i 或者 sudo ./script.sh)${NC}" exit 1 fi function prepare_env() { echo -e "${GREEN}==> 1. 开始初始化系统环境 (Ubuntu)...${NC}" ufw disable 2>/dev/null systemctl stop ufw 2>/dev/null && systemctl disable ufw 2>/dev/null swapoff -a sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab cat < /dev/null overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # 【关键防坑】ip_nonlocal_bind 允许 HAProxy 强行绑定还未飘过来的 VIP cat < /dev/null net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 net.ipv4.ip_nonlocal_bind = 1 EOF sysctl --system > /dev/null echo -e "${GREEN}==> 系统环境准备完毕。${NC}" } function install_containerd() { echo -e "${GREEN}==> 2. 开始安装 Containerd (锁定 1.6.x 避开 2.x 的断层坑)...${NC}" # 强行解锁并清理之前可能残留的坏包 apt-mark unhold containerd containerd.io 2>/dev/null || true apt-get purge -y --allow-change-held-packages containerd containerd.io 2>/dev/null || true apt-get autoremove -y > /dev/null rm -rf /etc/containerd/ /var/run/containerd/ /run/containerd/ apt-get update -y > /dev/null apt-get install -y apt-transport-https ca-certificates curl software-properties-common gpg # 配置官方 Docker 源 install -m 0755 -d /etc/apt/keyrings rm -f /etc/apt/keyrings/docker.gpg curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | gpg --dearmor --yes -o /etc/apt/keyrings/docker.gpg chmod a+r /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null apt-get update -y > /dev/null # 动态抓取 1.6.x 稳定版,防止 2.x 导致 kubeadm 崩溃 local VER=$(apt-cache madison containerd.io | grep ' 1.6.' | head -n 1 | awk -F '|' '{print $2}' | tr -d ' ') if [ -z "$VER" ]; then echo -e "${RED}无法找到 containerd.io 1.6.x 版本,请检查网络!${NC}" exit 1 fi apt-get install -y --allow-downgrades --allow-change-held-packages containerd.io=$VER apt-mark hold containerd.io > /dev/null # 【终极防坑】生成配置后,暴杀 disabled_plugins 屏蔽项,防止 CRI 插件装死 mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml > /dev/null sed -i '/disabled_plugins/d' /etc/containerd/config.toml sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml sed -i 's#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g' /etc/containerd/config.toml systemctl daemon-reload systemctl restart containerd systemctl enable containerd # 消除 crictl 警告 cat < /dev/null runtime-endpoint: unix:///run/containerd/containerd.sock image-endpoint: unix:///run/containerd/containerd.sock timeout: 10 debug: false EOF echo -e "${GREEN}==> Containerd (1.6.x) 安装配置完毕。${NC}" } function install_k8s_tools() { echo -e "${GREEN}==> 3. 开始安装 kubeadm, kubelet, kubectl...${NC}" apt-mark unhold kubelet kubeadm kubectl 2>/dev/null || true mkdir -p /etc/apt/keyrings rm -f /etc/apt/keyrings/kubernetes-apt-keyring.gpg curl -fsSL https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/deb/ /" | tee /etc/apt/sources.list.d/kubernetes.list > /dev/null apt-get update -y > /dev/null apt-get install -y --allow-downgrades --allow-change-held-packages kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl > /dev/null systemctl enable --now kubelet echo -e "${GREEN}==> K8s 核心组件安装完毕。${NC}" } function setup_vip() { local STATE=$1 local PRIORITY=$2 echo -e "${GREEN}==> 开始部署高可用 HAProxy & Keepalived (网卡: ${VIP_INTERFACE})...${NC}" apt-get install -y haproxy keepalived cat < /dev/null global log /dev/log local0 log /dev/log local1 notice daemon defaults mode tcp log global option tcplog timeout connect 10s timeout client 1m timeout server 1m frontend kubernetes-apiserver bind ${VIP}:${VIP_PORT} mode tcp default_backend kubernetes-master backend kubernetes-master mode tcp balance roundrobin option tcp-check server master01 ${MASTER01_IP}:6443 check server master02 ${MASTER02_IP}:6443 check server master03 ${MASTER03_IP}:6443 check EOF cat < /dev/null ! Configuration File for keepalived global_defs { router_id LVS_DEVEL } vrrp_script check_haproxy { script "killall -0 haproxy" interval 3 weight -2 fall 10 rise 2 } vrrp_instance VI_1 { state ${STATE} interface ${VIP_INTERFACE} virtual_router_id 51 priority ${PRIORITY} advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { ${VIP} } track_script { check_haproxy } } EOF systemctl restart haproxy keepalived systemctl enable haproxy keepalived echo -e "${GREEN}==> 负载均衡组件部署完毕 (当前角色: ${STATE})。${NC}" } function init_first_master() { echo -e "${YELLOW}==> 正在清理历史脏数据,确保纯净初始化...${NC}" kubeadm reset -f > /dev/null 2>&1 rm -rf /etc/cni/net.d $HOME/.kube/config ip link delete cni0 2>/dev/null || true ip link delete flannel.1 2>/dev/null || true echo -e "${GREEN}==> 验证基础服务健康状态...${NC}" ping -c 3 ${VIP} > /dev/null 2>&1 || { echo -e "${RED}致命错误: VIP (${VIP}) 无法连通,Keepalived未生效或存在IP冲突!${NC}"; exit 1; } crictl ps > /dev/null 2>&1 || { echo -e "${RED}致命错误: Containerd 通道未就绪 (CRI报错),请检查状态!${NC}"; exit 1; } echo -e "${GREEN}==> 开始初始化 Master01 集群...${NC}" kubeadm init \ --control-plane-endpoint="${CONTROL_PLANE_ENDPOINT}" \ --upload-certs \ --kubernetes-version=v1.28.2 \ --pod-network-cidr=${POD_SUBNET} \ --service-cidr=${SERVICE_SUBNET} \ --image-repository=registry.aliyuncs.com/google_containers if [ $? -eq 0 ]; then echo -e "${YELLOW}========================================================================${NC}" echo -e "${GREEN}恭喜!集群初始化成功!请务必复制好上方的 kubeadm join 命令。${NC}" echo -e "${YELLOW}========================================================================${NC}" export KUBECONFIG=/etc/kubernetes/admin.conf mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config echo -e "${GREEN}==> 正在部署 Calico 网络插件...${NC}" kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml else echo -e "${RED}初始化彻底失败!请检查上方输出。${NC}" fi } # =============== 路由逻辑 =============== case "$1" in base) prepare_env install_containerd install_k8s_tools ;; init-vip-master) setup_vip "MASTER" 100 ;; init-vip-backup) setup_vip "BACKUP" 90 ;; init-master) init_first_master ;; *) echo -e "${YELLOW}用法说明 (sudo ./install_k8s.sh <命令>):${NC}" echo " base - 所有机器(包括Node)加集群前【必跑】,装依赖排雷" echo " init-vip-master - Master01执行,配置主负载均衡" echo " init-vip-backup - Master02/03执行,配置备用负载均衡" echo " init-master - 仅Master01执行,进行最后的K8s集群初始化" exit 1 esac