#!/bin/bash
set -euo pipefail  # 严格模式：出错即停、未定义变量报错、管道错误传递

##############################################################################
# 基础配置参数
##############################################################################
LOG_FILE="/var/log/k8s-1.30-ubuntu-init-$(date +%Y%m%d).log"  # 初始化日志（带日期）
TIMEZONE="Asia/Shanghai"  # 时区（集群节点需统一）
# K8s 1.30+必需依赖（网络、时间、证书等基础工具）
K8S_DEPS=(
     lrzsz nfs-common socat chrony ca-certificates openssl conntrack iproute2 ipvsadm
)

##############################################################################
# 日志函数
##############################################################################
log() {
    # 输出格式：[时间] [级别] 内容（同时写入日志文件）
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] [$1] $2" | tee -a "$LOG_FILE"
}

##############################################################################
# 前置环境校验（确保满足K8s 1.30+最低要求）
##############################################################################
pre_check() {
    log "INFO" "开始环境校验"
    
    # 必须为root用户（需修改系统底层配置）
    if [ "$(id -u)" -ne 0 ]; then
        log "ERROR" "必须使用root用户执行"
        exit 1
    fi

    # 必须是Ubuntu系统（脚本仅适配Ubuntu）
    . /etc/os-release 2>/dev/null || { log "ERROR" "非Linux系统"; exit 1; }
    if [ "$ID" != "ubuntu" ]; then
        log "ERROR" "仅支持Ubuntu系统，当前为$ID"
        exit 1
    fi

    # 版本需≥22.04（K8s 1.30+官方最低要求）
    local ver_num=$(echo "$VERSION_ID" | tr -d '.' | cut -c1-4)
    if [ "$ver_num" -lt 2204 ]; then
        log "ERROR" "仅支持Ubuntu 22.04及以上，当前版本$VERSION_ID"
        exit 1
    fi
    log "INFO" "检测到Ubuntu $VERSION_ID（符合要求）"

    # 内核需≥5.15（K8s 1.30+强制要求）
    local kernel_ver=$(uname -r | cut -d'.' -f1-2)
    if ! echo "$kernel_ver" | awk -F. '$1*100 + $2 >= 515 {exit 0} {exit 1}'; then
        log "ERROR" "K8s 1.30+要求内核≥5.15，当前$kernel_ver"
        exit 1
    fi

    log "INFO" "环境校验通过"
}

##############################################################################
# 系统初始化（适配K8s 1.30+核心配置）
##############################################################################
system_init() {
    log "INFO" "开始系统初始化"

    # 1. 配置阿里云APT源（加速国内下载）
    local codename=$(lsb_release -cs)  # 自动获取版本代号（如22.04=jammy）
    log "INFO" "配置阿里云APT源（适配Ubuntu $codename）"
    mv /etc/apt/sources.list "/etc/apt/sources.list.bak.$(date +%Y%m%d)"  # 备份原配置
    cat > /etc/apt/sources.list << EOF
deb http://mirrors.aliyun.com/ubuntu/ $codename main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $codename main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $codename-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $codename-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $codename-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $codename-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ $codename-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ $codename-backports main restricted universe multiverse
EOF

    # 2. 安装K8s必需依赖
    log "INFO" "安装依赖工具"
    apt update -y >> "$LOG_FILE" 2>&1  # 更新软件包列表
    apt install -y "${K8S_DEPS[@]}" >> "$LOG_FILE" 2>&1  # 安装依赖（已安装则跳过）

    # 3. 配置时间同步（K8s对时间偏差敏感，需＜1s）
    log "INFO" "配置时间同步"
    timedatectl set-timezone "$TIMEZONE"  # 统一时区
    systemctl enable --now chrony.service  >/dev/null 2>&1  # 启动chrony服务（开机自启）
    chronyc -a makestep >> "$LOG_FILE" 2>&1  # 强制同步时间
    log "INFO" "当前时间：$(date)"

    # 4. 加载K8s必需内核模块
    # overlay：容器分层存储驱动依赖
    # br_netfilter：桥接网络的iptables规则生效依赖
    # nf_conntrack  # K8s 1.30新增：增强网络连接跟踪
    log "INFO" "加载内核模块：overlay、br_netfilter"
    for module in overlay br_netfilter nf_conntrack; do
        modprobe "$module"  # 临时加载（立即生效）
        echo "$module" >> /etc/modules-load.d/k8s.conf  # 永久加载（重启生效）
    done

    # 5. 配置K8s专用内核参数
    log "INFO" "配置内核参数"
    cat > /etc/sysctl.d/k8s.conf << EOF
# 网络基础（容器通信与网络策略）
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
net.ipv4.conf.all.forwarding        = 1

# 高并发优化（支持大量Pod连接）
net.core.somaxconn         = 65535
net.core.netdev_max_backlog = 65535
net.ipv4.tcp_tw_reuse      = 1
net.ipv4.tcp_fin_timeout   = 30

# 内存与文件系统（避免K8s组件异常）
vm.swappiness              = 0  # 禁用Swap（K8s强制要求）
vm.overcommit_memory       = 1
vm.panic_on_oom            = 0
fs.file-max                = 1048576
fs.inotify.max_user_watches = 1048576

# IPVS模式支持（Service负载均衡）
net.ipv4.vs.conntrack      = 1
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
EOF
    sysctl --system >> "$LOG_FILE" 2>&1
    for module in ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack; do
        modprobe "$module"  # 临时加载（立即生效）
        echo "$module" >> /etc/modules-load.d/k8s.conf  # 永久加载（重启生效）
    done

    # 6. 禁用Swap（K8s 1.30+强制要求，否则kubelet启动失败）
    log "INFO" "禁用Swap"
    swapoff -a  # 临时禁用
    sed -i '/swap/s/^/#/' /etc/fstab  # 永久禁用（注释fstab中Swap配置）

    # 7. 提升文件描述符限制（支持高并发场景）
    log "INFO" "配置文件描述符限制"
    cat >> /etc/security/limits.conf << EOF
* soft nofile 1048576
* hard nofile 1048576
* soft nproc  1048576
* hard nproc  1048576
root soft nofile 1048576
root hard nofile 1048576
EOF

    log "INFO" "系统初始化完成"
}

##############################################################################
# 主执行流程
##############################################################################
main() {
    log "INFO" "==================== K8s 1.30+初始化开始 ===================="
    pre_check
    system_init
    log "INFO" "==================== K8s 1.30+初始化完成 ===================="
}

main