bash
#!/bin/bash
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查并安装依赖
install_dependencies() {
log_info "安装系统依赖包..."
if command -v apt-get &> /dev/null; then
# Ubuntu/Debian
apt-get update
apt-get install -y \
curl \
wget \
gnupg \
apt-transport-https \
ca-certificates \
software-properties-common \
python3 \
python3-pip \
sshpass
elif command -v yum &> /dev/null; then
# CentOS/RHEL/Rocky/AlmaLinux
yum install -y \
curl \
wget \
epel-release \
yum-utils \
python3 \
python3-pip \
sshpass
else
log_error "不支持的Linux发行版"
exit 1
fi
}
# 配置主机名
configure_hostname() {
local hostname=$1
log_info "配置主机名为: $hostname"
# 设置主机名
hostnamectl set-hostname "$hostname"
# 确保主机名在重启后仍然有效
if [ -f /etc/hostname ]; then
echo "$hostname" > /etc/hostname
fi
}
# 配置 hosts 文件
configure_hosts() {
log_info "配置 /etc/hosts 文件..."
# 备份原有文件
cp /etc/hosts /etc/hosts.bak
# 添加集群节点信息
cat >> /etc/hosts << 'EOF'
# Kubernetes Cluster Nodes
192.168.30.135 ccka-master
192.168.30.136 ccka-worker1
192.168.30.137 ccka-worker2
EOF
}
# 关闭防火墙
disable_firewall() {
log_info "关闭防火墙..."
if systemctl is-active --quiet firewalld; then
systemctl stop firewalld
systemctl disable firewalld
log_info "Firewalld 已关闭"
fi
if command -v ufw &> /dev/null && ufw status | grep -q "Status: active"; then
ufw disable
log_info "UFW 已关闭"
fi
}
# 关闭 SELinux
disable_selinux() {
log_info "关闭 SELinux..."
if command -v getenforce &> /dev/null; then
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
log_info "SELinux 已设置为 permissive 模式"
fi
}
# 关闭 Swap
disable_swap() {
log_info "关闭 Swap..."
# 立即关闭所有 swap
swapoff -a
# 永久关闭 - 注释掉所有 swap 行
if [ -f /etc/fstab ]; then
cp /etc/fstab /etc/fstab.bak
sed -i '/swap/s/^/#/' /etc/fstab
fi
# 移除 swap 分区(如果有)
if swapon --summary | grep -q swap; then
log_warning "检测到活跃的 swap 分区,已关闭"
fi
}
# 配置内核参数
configure_kernel() {
log_info "配置内核参数..."
# 创建模块加载配置
cat > /etc/modules-load.d/k8s.conf << 'EOF'
overlay
br_netfilter
EOF
# 立即加载模块
modprobe overlay
modprobe br_netfilter
# 创建 sysctl 配置
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
EOF
# 应用配置
sysctl --system
}
# 配置时区和时间同步
configure_time() {
log_info "配置时间同步..."
if command -v timedatectl &> /dev/null; then
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp true
fi
# 安装并启动 chrony 或 ntp
if command -v apt-get &> /dev/null; then
apt-get install -y chrony
systemctl enable chrony
systemctl restart chrony
elif command -v yum &> /dev/null; then
yum install -y chrony
systemctl enable chronyd
systemctl restart chronyd
fi
}
# 配置 Docker 容器运行时(可选)
configure_docker() {
log_info "安装 Docker..."
if command -v docker &> /dev/null; then
log_info "Docker 已安装,跳过"
return
fi
if command -v apt-get &> /dev/null; then
# Ubuntu/Debian
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
elif command -v yum &> /dev/null; then
# CentOS/RHEL
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
fi
# 配置 Docker
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2"
}
EOF
systemctl enable docker
systemctl start docker
}
# 配置 Containerd 容器运行时(推荐)
configure_containerd() {
log_info "配置 Containerd..."
if command -v containerd &> /dev/null; then
log_info "Containerd 已安装,跳过"
return
fi
# 安装 Containerd
if command -v apt-get &> /dev/null; then
apt-get install -y containerd
elif command -v yum &> /dev/null; then
yum install -y containerd
fi
# 生成默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 修改配置使用 systemd cgroup
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable containerd
systemctl restart containerd
}
# 主执行函数
main() {
log_info "开始 Kubernetes 节点预检准备..."
# 检测当前主机名并确定角色
local current_hostname=$(hostname -s)
local role="worker"
case $current_hostname in
ccka-master)
role="master"
;;
ccka-worker1|ccka-worker2)
role="worker"
;;
*)
log_warning "未知的主机名: $current_hostname,请手动确认节点角色"
read -p "请输入节点角色 (master/worker): " role
;;
esac
log_info "检测到节点角色: $role"
# 执行准备工作
install_dependencies
configure_hostname "$current_hostname"
configure_hosts
disable_firewall
disable_selinux
disable_swap
configure_kernel
configure_time
configure_containerd # 使用 containerd
log_info "所有预检准备工作已完成!"
log_info "节点角色: $role"
log_info "主机名: $(hostname)"
log_info "IP 地址: $(hostname -I | awk '{print $1}')"
echo -e "\n${GREEN}✅ 节点准备完成!现在可以运行 Ansible 部署 Kubernetes 集群了。${NC}"
}
# 执行主函数
main "$@"
主要功能模块
- 初始设置和颜色定义
set -e # 任何命令失败就立即退出脚本
定义颜色变量用于彩色输出
- 日志函数
log_info(): 绿色信息日志
log_warning(): 黄色警告日志
log_error(): 红色错误日志
- 依赖安装 (install_dependencies)
检测包管理器(apt-get 或 yum)
安装必要的系统工具:curl、wget、python3、sshpass 等
- 主机名配置 (configure_hostname)
设置并永久配置主机名
- Hosts 文件配置 (configure_hosts)
备份原有 hosts 文件
添加 Kubernetes 集群节点的 IP 和主机名映射
- 安全设置
disable_firewall: 关闭防火墙(生产环境不推荐)
disable_selinux: 禁用 SELinux
disable_swap: 关闭 swap 分区(Kubernetes 要求)
- 内核参数配置 (configure_kernel)
加载必要的内核模块(overlay、br_netfilter)
配置网络相关的 sysctl 参数
- 时间同步 (configure_time)
设置时区为亚洲/上海
启用 NTP 时间同步
安装并启动 chrony 服务
- 容器运行时配置
configure_containerd: 安装并配置 Containerd(推荐用于 Kubernetes)
设置 systemd cgroup 驱动
- 主执行逻辑 (main)
自动检测节点角色(通过主机名判断)
按顺序执行所有准备步骤
显示最终的准备状态信息
使用场景
这个脚本通常在以下情况下使用:
准备全新的服务器用于 Kubernetes 集群部署
确保所有节点满足 Kubernetes 的系统要求
为后续的 Ansible 自动化部署做好准备
注意事项
脚本会修改系统关键配置,建议在测试环境中先验证
关闭防火墙和 SELinux 可能影响系统安全性
需要以 root 权限运行
主要针对 Ubuntu/Debian 和 CentOS/RHEL 系列系统
执行流程
安装依赖包
配置网络和主机名
调整系统安全设置
配置内核参数
设置时间同步
安装容器运行时
输出准备完成信息
这个脚本为 Kubernetes 集群部署提供了标准化的基础环境准备。