k8s单master一键安装初始化脚本

经常要为别人部署一下小规模的测试环境的k8s集群,所以自己写了个脚本方便自己部署使用,配置基本没啥要改的,一键就能部署master,node节点也是一键,只需要手工kubeadm join一下就行。脚本放上来三个

1.配置文件:common.sh
2.环境基础配置和k8s安装脚本:deploy_1_k8s_install.sh 
3.master节点k8s初始化脚本:deploy_2_k8s_init.sh

就按照上述三个脚本执行即可,node节点不需要执行deploy_2_k8s_init.sh,执行了deploy_1_k8s_install.sh以后就可以使用join进集群了,如果需要集成到自己的部署项目中,可以提前创建好一个永不过期的token,那样kubeadm join的命令就固定下来了。创建永久有效的方法查看这个笔记:https://sulao.cn/post/800

common.sh内容如下

#!/bin/bash

K8S_VERSION="v1.32" #k8s版本,此脚本适配1.28-1.32
PAUSE_VERSION="3.10" #pause容器版本如果使用1.2X版本把这个修改为3.8或者3.9
CONTAINERD_VERSION="1.7.28" #容器运行时版本
NERDCTL_VERSION="2.1.4" #容器管理工具版本
POD_SUBNET="10.244.0.0/16" #k8s 网络子网
CALICO_VERSION="v3.29.1" #calico 版本
CILIUM_VERSION="v0.18.8" #cilium 版本
GPU_OPERATOR_VERSION="v25.3.4" #gpu operator 版本
METALLB_VERSION="v0.15.2" # metallb 版本
IP_POOL="192.168.0.190-192.168.0.199"
HOSTS=('192.168.0.180 master') #修改为当前部署的主机名和内网IP

function INFO(){
    /bin/echo -e "\e[104m\e[97m[I]\e[49m\e[39m ${*}"
}
function WARNING(){
    /bin/echo >&2 -e "\e[105m\e[97m[W]\e[49m\e[39m ${*}"
}
function ERROR(){
    /bin/echo >&2 -e "\e[101m\e[97m[E]\e[49m\e[39m ${*}"
}

deploy_1_k8s_install.sh文件内容如下

#!/bin/bash
#set -e

CURRENT_PATH=`readlink -f $(dirname $0)`
. ${CURRENT_PATH}/common.sh

function CONFIG_SUDOER(){
    INFO "配置当前用户sudo切换免密..."
    if [ "$(whoami)" == "root" ]; then
        INFO "当前用户为root,跳过配置!"
    else
        sudo tee /etc/sudoers.d/$(whoami) <<EOF
$(whoami) ALL=(ALL) NOPASSWD:ALL
EOF
    fi
}
function REPLACE_SOURCE(){
    INFO "替换APT源..."
    if [ ! -f "/etc/apt/sources.list_bak" ]; then
        sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak
    fi
    sudo tee /etc/apt/sources.list >/dev/null <<EOF
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-security main restricted universe multiverse
EOF
}
function ENV_CONFIG(){
    INFO "更新系统包..."
    sudo apt update -y
    sudo apt install -y gcc gcc+ make apt-transport-https ca-certificates \
        curl gnupg-agent gnupg lsb-release make software-properties-common \
        net-tools git curl ntpdate ipvsadm frr
    
    INFO "设置主机名内网IP绑定..."
    HOST_BIND=$(grep -c "${HOSTS[0]}" /etc/hosts)
    if [ $HOST_BIND -eq 0 ]; then
        echo "${HOSTS[0]}" | sudo tee -a /etc/hosts
    else
        WARNING "HOSTS 已经绑定,跳过!"
    fi

    INFO "关闭swap..."
    #sudo sed -i '/swap/d' /etc/fstab
    sudo sed -i '/swap/s/^/#/' /etc/fstab
    sudo swapoff -a
    sudo systemctl stop swap.target
    sudo systemctl disable swap.target

    INFO "关闭ufw防火墙..."
    sudo ufw disable || true
    sudo systemctl stop ufw || true
    sudo systemctl disable ufw || true

    INFO "设置时区并同步时间..."
    sudo timedatectl set-timezone Asia/Shanghai
    sudo ntpdate -u ntp.aliyun.com || INFO "时间同步完成"
}
function OPTIMIZE_LIMIT(){
    INFO "优化文件描述符..."
    if [ ! -f /etc/security/limits.conf_bak ]; then
        sudo cp /etc/security/limits.conf /etc/security/limits.conf_bak
    fi
        sudo tee /etc/security/limits.conf > /dev/null <<EOF
* soft nofile 1000000
* hard nofile 1000000
* soft nproc 2000000
* hard nproc 2000000
* soft memlock unlimited
* hard memlock unlimited
* soft stack unlimited
* hard stack unlimited
root soft nofile 1000000
root hard nofile 1000000
root soft nproc 2000000
root hard nproc 2000000
root soft memlock unlimited
root hard memlock unlimited
root soft stack unlimited
root hard stack unlimited
EOF
}
function OPTIMIZE_KERNEL(){
    INFO "设置k8s需要的内核配置..."
    sudo tee /etc/sysctl.d/k8s.conf >/dev/null <<EOF
# 允许转发
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
# 调整内核bridge-nf保护
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
# 调整系统IP端口限制
net.ipv4.ip_local_port_range = 1024 65535
# 增加最大文件打开数
fs.file-max = 1000000
# 调整最大进程数
kernel.pid_max = 4194304
# 调整TCP栈参数
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 360000
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_mtu_probing = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_retries2 = 8
net.ipv4.tcp_window_scaling = 1
# 调整网络设备队列长度
net.core.netdev_max_backlog = 16384
# 调整网络设备接收缓冲区大小
net.core.rmem_max = 16777216
net.core.rmem_default = 16777216
# 调整网络设备发送缓冲区大小
net.core.wmem_max = 16777216
net.core.wmem_default = 16777216
# 调整路由缓存
net.ipv4.route.gc_timeout = 100
# 调整arp缓存超时时间
net.ipv4.neigh.default.gc_stale_time = 120
# 调整arp缓存大小
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192
# 调整内核连接跟踪表大小
net.netfilter.nf_conntrack_max = 1000000
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
# 调整内核syn cookie保护
net.ipv4.tcp_syncookies = 1
# 调整最大虚拟内存区域
vm.max_map_count = 262144000
# 调整只使用物理内存
vm.swappiness = 0
EOF
    sudo sysctl --system >/dev/null

    INFO "开启内核IP转发..."
    echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward

    INFO "内核加载overlay和过滤模块到内核..."
    lsmod | grep -E 'overlay|br_netfilter'
    if [ $? -ne 0 ]; then
        sudo tee /etc/modules-load.d/containerd.conf >/dev/null <<EOF
overlay
br_netfilter
EOF
    sudo modprobe overlay
    sudo modprobe br_netfilter
    else
        WARNING "overlay和过滤模块已加载,跳过当前步骤!"
    fi

    INFO "配置ipvs并加载到内核..."
    lsmod | grep -iE 'ip_vs|nf_conntrack'
    if [ $? -ne 0 ]; then
        sudo mkdir -p /etc/sysconfig/modules/
        sudo tee /etc/sysconfig/modules/ipvs.modules >/dev/null <<EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack
EOF
        sudo chmod 755 /etc/sysconfig/modules/ipvs.modules
        sudo bash /etc/sysconfig/modules/ipvs.modules
    else
        WARNING "ipvs模块已加载,跳过当前步骤!"
    fi

    INFO "禁用内核自动更新..."
    sudo rm -f /etc/apt/apt.conf.d/50unattended-upgrades >/dev/null 2>&1
    sudo systemctl stop unattended-upgrades.service
    sudo systemctl disable unattended-upgrades.service
    for i in `dpkg --list | grep -E 'linux-(headers|image|modules)-[0-9]' | awk '{print $2}'`
        do sudo apt-mark hold $i
    done
}
function INSTALL_CRI(){
    INFO "安装容器运行时containerd..."
    if command -v "containerd" >/dev/null 2>&1; then
        WARNING "容器运行时已安装,跳过当前步骤!"
    else
        # sudo apt install containerd -y
        if [ ! -f "${CURRENT_PATH}/package/cri-containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz" ]; then
            wget -P ${CURRENT_PATH}/package/ \
            https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/cri-containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz
        fi
        sudo tar -zxvf ${CURRENT_PATH}/package/cri-containerd-${CONTAINERD_VERSION}-linux-amd64.tar.gz -C / >/dev/null
        sudo mkdir -p /etc/containerd
        containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
        sudo sed -i "s@registry.k8s.io/pause:3.8@registry.cn-hangzhou.aliyuncs.com/google_containers/pause:${PAUSE_VERSION}@g" /etc/containerd/config.toml
        sudo sed -i '/SystemdCgroup/s/false/true/g' /etc/containerd/config.toml
        
        sudo systemctl daemon-reload
        sudo systemctl enable --now containerd
    fi
    containerd --version
    if [ $? -ne 0 ]; then
        WARNING "容器运行时安装失败!"
        exit 1
    fi

    sudo tee /etc/crictl.yaml >/dev/null <<EOF
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10 
debug: false
EOF
}
function INSTALL_NERDCTL(){
    INFO "安装容器管理工具nerdctl..."
    sudo nerdctl --version >/dev/null 2>&1
    if [ $? -eq 0 ]; then
        WARNING "容器管理工具nerdctl已安装,跳过!"
    else
        if [ ! -f "${CURRENT_PATH}/package/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz" ]; then
            wget -P ${CURRENT_PATH}/package/ \
            https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz
        fi
        tar -zxvf ${CURRENT_PATH}/package/nerdctl-${NERDCTL_VERSION}-linux-amd64.tar.gz -C ${CURRENT_PATH}/package/
        sudo cp -a ${CURRENT_PATH}/package/nerdctl /usr/local/bin/
    fi
    sudo nerdctl --version
    if [ $? -ne 0 ]; then
        WARNING "容器管理工具nerdctl安装失败!"
    fi
}
function INSTALL_K8S(){
    INFO "配置k8s安装源仓库..."
    if ! command -v "kubectl" >/dev/null 2>&1; then
        sudo mkdir -p -m 755 /etc/apt/keyrings
        curl -fsSL https://pkgs.k8s.io/core:/stable:/${K8S_VERSION}/deb/Release.key | sudo 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:/${K8S_VERSION}/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
        sudo apt update -y
        sudo apt install -y kubelet kubeadm kubectl
        if [ $? -ne 0 ]; then
            ERROR "k8s 安装失败!"
            exit 1
        fi

        INFO "禁止k8s自动更新..."
        sudo apt-mark hold kubelet kubectl
        sudo systemctl enable kubelet

        INFO "修改k8s cgroup配置..."
        echo 'KUBELET_EXTRA_ARGS="--cgroup-driver=systemd"' | sudo tee /etc/default/kubelet
        
        INFO "指定k8s节点为内网ip..."
        sudo cp /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf_bak
        sudo sed -i "s/\$KUBELET_EXTRA_ARGS/\$KUBELET_EXTRA_ARGS --node-ip=${HOSTS[0]%% *}/g" /usr/lib/systemd/system/kubelet.service.d/10-kubeadm.conf
        sudo systemctl daemon-reload
    else
        WARNING "k8s 已安装,跳过当前步骤!"
    fi
}

#CONFIG_SUDOER
REPLACE_SOURCE
ENV_CONFIG
OPTIMIZE_LIMIT
OPTIMIZE_KERNEL
INSTALL_CRI
INSTALL_NERDCTL
INSTALL_K8S

deploy_2_k8s_init.sh文件内容下:

#!/bin/bash
#set -e

CURRENT_PATH=`readlink -f $(dirname $0)`
. ${CURRENT_PATH}/common.sh

function INSTALL_HELM(){
    INFO "安装helm..."
    if command -v "helm" >/dev/null 2>&1; then
        WARNING "helm已安装,跳过当前步骤!"
    else
        if [ ! -f "${CURRENT_PATH}/get_helm.sh" ]; then
            curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
        fi
        chmod 700 get_helm.sh
        sudo ./get_helm.sh
    fi
    helm version
}
function INIT_K8S(){
    INFO "k8s初始化配置修改..."
    ps -ef | grep -E 'kube-apiserver|etcd|kube-scheduler|kube-controller-manager' | grep -v "grep"
    if [ $? -ne 0 ]; then
        if ! command -v "kubeadm" >/dev/null 2>&1; then
            ERROR "初始化前请先安装k8s!"
            exit 1
        else
            kubeadm config print init-defaults | sudo tee /etc/kubernetes/default.yaml >/dev/null
            sudo sed -i "s/1.2.3.4/${HOSTS[0]%% *}/" /etc/kubernetes/default.yaml
            sudo sed -i "s#registry.k8s.io#registry.cn-hangzhou.aliyuncs.com/google_containers#" /etc/kubernetes/default.yaml
            sudo sed -i "/10.96.0.0\/12/a\  podSubnet: ${POD_SUBNET}" /etc/kubernetes/default.yaml
            sudo sed -i "s/name: node/name: ${HOSTS[0]##* }/g" /etc/kubernetes/default.yaml

            INFO "配置默认开启ipvs..."
            sudo tee -a /etc/kubernetes/default.yaml >/dev/null <<EOF
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  scheduler: "rr"
  minSyncPeriod: "1s"
  syncPeriod: "30s"
  strictARP: true
EOF
            INFO "预拉取k8s镜像..."
            sudo kubeadm config images pull --config /etc/kubernetes/default.yaml

            INFO "k8s初始化..."
            sudo kubeadm init --config=/etc/kubernetes/default.yaml --upload-certs
            if [ $? -ne 0 ]; then
                ERROR "k8s 初始化失败!"
                exit 1
            fi
            INFO "复制k8s管理配置..."
            mkdir -p $HOME/.kube
            sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
            sudo chown $(id -u):$(id -g) $HOME/.kube/config
            #export KUBECONFIG=/etc/kubernetes/admin.conf
            kubectl get node -o wide
            INFO "k8s初始化完成,请安装网络组件!"
        fi
    else
        WARNING "已有k8s服务在运行,跳过当前步骤!"
    fi
}

INSTALL_HELM
INIT_K8S

注意需要修改common.sh中的配置为实际配置,例如主机名ip,其他的版本可不用修改。

另外有些包最好提前下载好,网络不好容易安装失败,我都是放在package这个目录下,上面没写判断这个目录是否存在,需要提前mkdir创建下,最好是能按照配置版本提前下载放到这个目录下。

202511111447299140985612.png

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://sulao.cn/post/1145

评论列表

0%