#!/bin/bash

source /etc/profile

MASTER_IP=""
OFFICE_ENV="false"

function tip() {
    echo "Usage:"
    echo "sh kubeadm-master-init.sh [-m MASTER_IP] [--office] [-h help]"
    echo "Description:"
    echo "MASTER_IP, kubeadm master node ip"
    echo "--office, 办公区网络环境，跳过 hosts 修改"
    exit -1
}

function checkpoint() {
    if [ $1 == 0 ]; then
        echo -e "\033[32m \ndone! \033[0m" 
    else
        echo -e "\033[31m \nfailed~ \033[0m"
        exit 1
    fi
}

for arg in "$@"; do
  shift
  case "$arg" in
    "--office") set -- "$@" "-o" ;;
    *)        set -- "$@" "$arg"
  esac
done

while getopts 'm:oh' OPT; do
    case $OPT in
        m) MASTER_IP="$OPTARG";;
        o) OFFICE_ENV="true";;
        h) tip;;
        ?) tip;;
    esac
done

function stage_info() {
    info_msg=$1
    echo -e "\033[36m \n======================== ${info_msg} ========================\n \033[0m"
}


stage_info "参数检查"
if [ "${MASTER_IP}" == "" ]; then
    echo -e "MASTER_IP is required, eg.'sh kubeadm-master-init.sh -master 1.2.3.4' \n\n"
    exit 1
else
    echo MASTER_IP: ${MASTER_IP}
fi
checkpoint $?

stage_info "debian10 修复 apt 源"
DEBIAN_VERSION=$(cat /etc/debian_version | cut -d'.' -f1)
if [ "$DEBIAN_VERSION" = "10" ]; then
    echo "检测到 Debian 10.x 系统，修复 apt 源..."
    cat > /etc/apt/sources.list << EOF
deb http://apt.x.netease.com:8660/debian-archive/  buster main contrib non-free
deb-src http://apt.x.netease.com:8660/debian-archive/  buster main contrib non-free
deb http://apt.x.netease.com:8660/debian-archive/  buster-updates main contrib non-free
deb-src http://apt.x.netease.com:8660/debian-archive/ buster-updates main contrib non-free
deb http://apt.x.netease.com:8660/debian-security-archive/  buster/updates main
deb-src http://apt.x.netease.com:8660/debian-security-archive/ buster/updates main
deb http://sa.apt.netease.com:8660/debian/ buster main
EOF
    apt-get update
    checkpoint $?
else
    echo "非 Debian 10.x 系统，跳过 apt 源修复"
    checkpoint 0
fi


if [ "${OFFICE_ENV}" = "false" ]; then
    stage_info "hosts 修改"
    cat >> /etc/hosts << EOF

7.119.0.196 git-sa.nie.netease.com

10.192.21.21 github.com
10.192.21.21 proxy.golang.org
10.192.21.21 google.golang.org
10.192.21.21 cloud.google.com
10.192.21.21 golang.org
10.192.21.21 raw.githubusercontent.com
10.192.21.21 go.googlesource.com
10.192.21.21 auth.docker.io
10.192.21.21 registry-1.docker.io
10.192.21.21 cr.l5d.io
10.192.21.21 docker.elastic.co
10.192.21.21 docker.io
10.192.21.21 gcr.io
10.192.21.21 ghcr.io
10.192.21.21 k8s.gcr.io
10.192.21.21 registry.k8s.io
10.192.21.21 mcr.microsoft.com
10.192.21.21 nvcr.io
10.192.21.21 quay.io
10.192.21.21 registry.jujucharms.com
10.192.21.21 rocks.canonical.com
10.192.21.21 k8s.m.daocloud.io
10.192.21.21 k8s-gcr.m.daocloud.io
10.192.21.21 quay.m.daocloud.io
10.192.21.21 docker.m.daocloud.io
EOF
    checkpoint $?
else
    stage_info "办公区环境，跳过 hosts 修改"
    checkpoint 0
fi


stage_info "系统参数配置优化"
# 创建一个名为 kubernetes.conf 的内核配置文件，并写入以下配置内容
cat > /etc/sysctl.d/kubernetes.conf << EOF
# 允许 IPv6 转发请求通过iptables进行处理（如果禁用防火墙或不是iptables，则该配置无效）
net.bridge.bridge-nf-call-ip6tables = 1

# 允许 IPv4 转发请求通过iptables进行处理（如果禁用防火墙或不是iptables，则该配置无效）
net.bridge.bridge-nf-call-iptables = 1

# 启用IPv4数据包的转发功能
net.ipv4.ip_forward = 1

# 禁用发送 ICMP 重定向消息
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# 提高 TCP 连接跟踪的最大数量
net.netfilter.nf_conntrack_max = 1000000

# 提高连接追踪表的超时时间
net.netfilter.nf_conntrack_tcp_timeout_established = 86400

# 提高监听队列大小
net.core.somaxconn = 1024

# 防止 SYN 攻击
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2

# 提高文件描述符限制
fs.file-max = 65536

# 设置虚拟内存交换（swap）的使用策略为0，减少对磁盘的频繁读写
vm.swappiness = 0
EOF
# 加载或启动内核模块 br_netfilter，该模块提供了网络桥接所需的网络过滤功能
modprobe br_netfilter
# 查看是否已成功加载模块
lsmod | grep br_netfilter
# 将读取该文件中的参数设置，并将其应用到系统的当前运行状态中
sysctl -p /etc/sysctl.d/kubernetes.conf
sysctl --system
checkpoint $?


stage_info "内核模块配置"
cat > /etc/modules-load.d/kubernetes.conf << EOF
# /etc/modules-load.d/kubernetes.conf

# Linux 网桥支持
br_netfilter

# IPv4 连接跟踪
nf_conntrack_ipv4

# IP 表规则
ip_tables
EOF
# 添加可执行权限
chmod a+x /etc/modules-load.d/kubernetes.conf
checkpoint $?


stage_info "关闭 swap"
swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab
checkpoint $?


stage_info "端口放通"
iptables -I INPUT -p tcp --dport 6001 -j ACCEPT && \
iptables -I INPUT -p udp --dport 8472 -j ACCEPT && \
iptables -I INPUT -p udp --dport 8285 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 30000:32767 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 27017 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 8081 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 80 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 18080 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 18090 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 18888 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 8000 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 18000 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 5000 -j ACCEPT && \
iptables -I INPUT -p udp --dport 111 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 111 -j ACCEPT && \
iptables -I INPUT -p udp --dport 2049 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 2049 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 10252 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 10251 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 10250 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 2380 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 2379 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 16443 -j ACCEPT && \
iptables -I INPUT -p tcp --dport 6443 -j ACCEPT

checkpoint $?

stage_info "iptables 持久化"
apt-get install -y iptables-persistent
netfilter-persistent save
checkpoint $?

stage_info "安装 containerd"
# 下载并安装 containerd
CONTAINERD_VERSION="1.7.13"
ARCH="amd64"
wget  https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz
tar Cxzvf /usr/local containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz
rm -f containerd-${CONTAINERD_VERSION}-linux-${ARCH}.tar.gz

# 下载并安装 runc
RUNC_VERSION="1.1.12"
wget  https://github.com/opencontainers/runc/releases/download/v${RUNC_VERSION}/runc.${ARCH}
install -m 755 runc.${ARCH} /usr/local/sbin/runc
rm -f runc.${ARCH}

# 下载并安装 CNI 插件
CNI_VERSION="1.4.0"
mkdir -p /opt/cni/bin
wget  https://github.com/containernetworking/plugins/releases/download/v${CNI_VERSION}/cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz
tar Cxzvf /opt/cni/bin cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz
rm -f cni-plugins-linux-${ARCH}-v${CNI_VERSION}.tgz

# 配置 containerd systemd 服务
wget  https://raw.githubusercontent.com/containerd/containerd/main/containerd.service -O /usr/lib/systemd/system/containerd.service

# 创建目录
mkdir -p /etc/containerd
mkdir -p /home/cld/var/lib/containerd
# 创建配置文件
cat > /etc/containerd/config.toml << EOF
version = 2
root = "/home/cld/var/lib/containerd"
state = "/run/containerd"

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"

  [plugins."io.containerd.grpc.v1.cri".containerd]
    default_runtime_name = "runc"
    snapshotter = "overlayfs"

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
      runtime_type = "io.containerd.runc.v2"
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
        SystemdCgroup = true

  [plugins."io.containerd.grpc.v1.cri".registry]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
        endpoint = ["https://ncr-mirror.nie.netease.com:1443"]
EOF

# 启动并设置开机自启
systemctl daemon-reload
systemctl enable --now containerd
systemctl restart containerd

# 配置 crictl
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF

checkpoint $?


stage_info "kubernetes v1.32.3 源"
apt-get update && \
apt-get install -y apt-transport-https ca-certificates curl gpg && \
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/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://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list && \
apt update
apt-cache madison kubeadm
checkpoint $?

stage_info "安装 kubeadm / kubelet / kubectl v1.32.3"
apt-get install -y kubeadm=1.32.3-1.1 kubelet=1.32.3-1.1 kubectl=1.32.3-1.1 && \
systemctl start kubelet && \
systemctl enable kubelet
checkpoint $?

stage_info "kubeadm 更换100年证书版本"
mv /usr/bin/kubeadm /usr/bin/kubeadm_bak
wget http://files.joeyj.io/kubeadm/kubeadm_100y_v132 -O /usr/bin/kubeadm && chmod +x /usr/bin/kubeadm
checkpoint $?


stage_info "kubeadm master 初始化"
kubeadm init --image-repository registry.aliyuncs.com/google_containers \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=1.32.0 \
--apiserver-advertise-address=${MASTER_IP}
checkpoint $?

stage_info "kubeconfig 配置"
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
checkpoint $?

stage_info "CNI: Flannel 部署"
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
checkpoint $?

stage_info "KUBEADM MASTER INIT SUCCESSFULLY !"
