Skip to content

Instantly share code, notes, and snippets.

@yezihack
Last active December 4, 2025 03:03
Show Gist options
  • Select an option

  • Save yezihack/ae8f13e73ced17149f92130b36bdca22 to your computer and use it in GitHub Desktop.

Select an option

Save yezihack/ae8f13e73ced17149f92130b36bdca22 to your computer and use it in GitHub Desktop.
k8s 脚本
#!/bin/bash
# Kubernetes 环境检查与修复脚本
# 使用方法:
# 检查: ./k8s_check.sh check
# 修复: ./k8s_check.sh fix
# 设置hosts: ./k8s_check.sh set-host <hostname> <ip>
# 在线检查:curl -sSL https://gist.githubusercontent.com/yezihack/ae8f13e73ced17149f92130b36bdca22/raw/k8s-pre-check.sh | bash -s check
# 在线修复:curl -sSL https://gist.githubusercontent.com/yezihack/ae8f13e73ced17149f92130b36bdca22/raw/k8s-pre-check.sh | bash -s fix
# 在线设置hosts:curl -sSL https://gist.githubusercontent.com/yezihack/ae8f13e73ced17149f92130b36bdca22/raw/k8s-pre-check.sh | bash -s set-host <hostname> <ip>
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
BOLD='\033[1m'
# 检查结果统计
PASS_COUNT=0
WARN_COUNT=0
FAIL_COUNT=0
CHECK_NUM=0
# 打印带颜色的消息
print_header() {
echo -e "\n${BOLD}${BLUE}========================================${NC}"
echo -e "${BOLD}${BLUE} $1${NC}"
echo -e "${BOLD}${BLUE}========================================${NC}\n"
}
print_success() {
echo -e "${GREEN}✓ [$CHECK_NUM] $1${NC}"
((PASS_COUNT++))
}
print_warning() {
echo -e "${YELLOW}⚠ [$CHECK_NUM] $1${NC}"
((WARN_COUNT++))
}
print_error() {
echo -e "${RED}✗ [$CHECK_NUM] $1${NC}"
((FAIL_COUNT++))
}
print_info() {
echo -e "${BLUE}ℹ [$CHECK_NUM] $1${NC}"
}
# 检查是否为root用户
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "请使用root权限运行此脚本"
exit 1
fi
}
# 检查CPU核心数
check_cpu() {
((CHECK_NUM++))
print_info "检查CPU核心数..."
CPU_CORES=$(nproc 2>/dev/null || echo "0")
echo " 当前CPU核心数: $CPU_CORES"
if [ "$CPU_CORES" -ge 2 ]; then
print_success "CPU核心数满足要求 (≥2核)"
else
print_error "CPU核心数不足 (当前${CPU_CORES}核 < 要求2核)"
fi
}
# 检查内存
check_memory() {
((CHECK_NUM++))
print_info "检查内存大小..."
MEM_GB=$(free -g 2>/dev/null | awk '/^Mem:/{print $2}' || echo "0")
MEM_MB=$(free -m 2>/dev/null | awk '/^Mem:/{print $2}' || echo "0")
echo " 当前内存: ${MEM_MB}MB (约${MEM_GB}GB)"
if [ "$MEM_GB" -ge 2 ]; then
print_success "内存满足要求 (≥2GB)"
else
print_error "内存不足 (当前${MEM_GB}GB < 要求2GB)"
fi
}
# 检查磁盘空间
check_disk() {
((CHECK_NUM++))
print_info "检查磁盘空间..."
# 获取根分区信息
ROOT_DISK=$(df -h / 2>/dev/null | tail -1)
ROOT_SIZE=$(echo $ROOT_DISK | awk '{print $2}')
ROOT_AVAIL=$(echo $ROOT_DISK | awk '{print $4}')
ROOT_SIZE_GB=$(df -BG / 2>/dev/null | tail -1 | awk '{print $2}' | sed 's/G//' || echo "0")
echo " 根分区: / 总大小=${ROOT_SIZE} 可用=${ROOT_AVAIL}"
# 检查磁盘类型
ROOT_DEVICE=$(df / 2>/dev/null | tail -1 | awk '{print $1}' | sed 's/[0-9]*$//' || echo "")
if [ -n "$ROOT_DEVICE" ] && [ -e "$ROOT_DEVICE" ]; then
DISK_TYPE="未知"
ROTA=$(lsblk -d -o name,rota "$ROOT_DEVICE" 2>/dev/null | tail -1 | awk '{print $2}')
if [ "$ROTA" == "0" ]; then
DISK_TYPE="SSD"
elif [ "$ROTA" == "1" ]; then
DISK_TYPE="HDD(机械硬盘)"
fi
echo " 磁盘类型: $DISK_TYPE"
fi
if [ "$ROOT_SIZE_GB" -ge 30 ]; then
print_success "磁盘空间满足要求 (≥30GB)"
else
print_error "磁盘空间不足 (当前${ROOT_SIZE_GB}GB < 要求30GB)"
fi
}
# 检查操作系统版本
check_os() {
((CHECK_NUM++))
print_info "检查操作系统版本..."
if [ -f /etc/centos-release ]; then
OS_VERSION=$(cat /etc/centos-release 2>/dev/null || echo "未知")
echo " 系统版本: $OS_VERSION"
CENTOS_VERSION=$(rpm -q --queryformat '%{VERSION}' centos-release 2>/dev/null || echo "0")
MINOR_VERSION=$(rpm -q --queryformat '%{RELEASE}' centos-release 2>/dev/null | cut -d. -f1 || echo "0")
echo " CentOS版本: ${CENTOS_VERSION}.${MINOR_VERSION}"
if [ "$CENTOS_VERSION" == "7" ] && [ "$MINOR_VERSION" -ge 7 ] && [ "$MINOR_VERSION" -le 9 ]; then
print_success "操作系统版本满足要求 (CentOS 7.7~7.9)"
else
print_warning "操作系统版本建议使用 CentOS 7.7~7.9 (当前: ${CENTOS_VERSION}.${MINOR_VERSION})"
fi
else
print_warning "非CentOS系统,建议使用CentOS 7.7~7.9"
fi
}
# 检查系统架构
check_arch() {
((CHECK_NUM++))
print_info "检查系统架构..."
ARCH=$(uname -m 2>/dev/null || echo "未知")
echo " 系统架构: $ARCH"
if [ "$ARCH" == "x86_64" ]; then
print_success "系统架构为64位"
else
print_error "系统架构不是64位"
fi
}
# 检查内核版本
check_kernel() {
((CHECK_NUM++))
print_info "检查内核版本..."
KERNEL_VERSION=$(uname -r 2>/dev/null || echo "0.0.0")
echo " 当前内核: $KERNEL_VERSION"
KERNEL_MAJOR=$(echo $KERNEL_VERSION | cut -d. -f1)
KERNEL_MINOR=$(echo $KERNEL_VERSION | cut -d. -f2)
if [ "$KERNEL_MAJOR" -gt 3 ] || ([ "$KERNEL_MAJOR" -eq 3 ] && [ "$KERNEL_MINOR" -ge 10 ]); then
print_success "内核版本满足要求 (≥3.10)"
else
print_error "内核版本过低 (当前${KERNEL_VERSION} < 要求3.10)"
fi
}
# 检查防火墙
check_firewall() {
((CHECK_NUM++))
print_info "检查防火墙状态..."
if systemctl is-active --quiet firewalld 2>/dev/null; then
print_error "防火墙正在运行 (建议关闭)"
elif systemctl is-enabled --quiet firewalld 2>/dev/null; then
print_warning "防火墙已禁用但未关闭开机自启"
else
print_success "防火墙已关闭"
fi
}
# 检查SWAP
check_swap() {
((CHECK_NUM++))
print_info "检查SWAP状态..."
SWAP_SIZE=$(free -m 2>/dev/null | grep Swap | awk '{print $2}' || echo "0")
if [ "$SWAP_SIZE" -eq 0 ]; then
print_success "SWAP已关闭"
else
print_error "SWAP未关闭 (当前: ${SWAP_SIZE}MB)"
fi
}
# 检查SELinux
check_selinux() {
((CHECK_NUM++))
print_info "检查SELinux状态..."
SELINUX_STATUS=$(getenforce 2>/dev/null || echo "Unknown")
echo " 当前状态: $SELINUX_STATUS"
if [ "$SELINUX_STATUS" == "Disabled" ]; then
print_success "SELinux已禁用"
elif [ "$SELINUX_STATUS" == "Permissive" ]; then
print_warning "SELinux为宽容模式 (建议设置为Disabled)"
else
print_error "SELinux未禁用 (当前: $SELINUX_STATUS)"
fi
}
# 检查主机名和hosts解析
check_hostname() {
((CHECK_NUM++))
print_info "检查主机名与hosts解析..."
HOSTNAME=$(hostname 2>/dev/null || echo "未知")
HOSTNAME_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "未知")
echo " 主机名: $HOSTNAME"
echo " 主机IP: $HOSTNAME_IP"
if grep -q "$HOSTNAME" /etc/hosts 2>/dev/null; then
HOSTS_IP=$(grep "$HOSTNAME" /etc/hosts 2>/dev/null | grep -v "^#" | awk '{print $1}' | head -1 || echo "未找到")
echo " /etc/hosts中的解析: $HOSTS_IP"
if [ "$HOSTS_IP" == "$HOSTNAME_IP" ]; then
print_success "主机名解析正确"
else
print_warning "主机名解析IP不匹配 (hosts:$HOSTS_IP vs 实际:$HOSTNAME_IP)"
fi
else
print_warning "主机名未在/etc/hosts中配置"
fi
}
# 检查桥接流量转发
check_bridge() {
((CHECK_NUM++))
print_info "检查桥接流量转发..."
BR_NETFILTER_LOADED=false
if lsmod 2>/dev/null | grep -q br_netfilter; then
BR_NETFILTER_LOADED=true
fi
IPV4_FORWARD=$(sysctl -n net.ipv4.ip_forward 2>/dev/null || echo "0")
BRIDGE_NF_IPTABLES=$(sysctl -n net.bridge.bridge-nf-call-iptables 2>/dev/null || echo "0")
BRIDGE_NF_IP6TABLES=$(sysctl -n net.bridge.bridge-nf-call-ip6tables 2>/dev/null || echo "0")
echo " br_netfilter模块: $([ "$BR_NETFILTER_LOADED" == true ] && echo '已加载' || echo '未加载')"
echo " net.ipv4.ip_forward: $IPV4_FORWARD"
echo " net.bridge.bridge-nf-call-iptables: $BRIDGE_NF_IPTABLES"
echo " net.bridge.bridge-nf-call-ip6tables: $BRIDGE_NF_IP6TABLES"
if [ "$BR_NETFILTER_LOADED" == true ] && [ "$IPV4_FORWARD" -eq 1 ] && \
[ "$BRIDGE_NF_IPTABLES" -eq 1 ] && [ "$BRIDGE_NF_IP6TABLES" -eq 1 ]; then
print_success "桥接流量转发已正确配置"
else
print_error "桥接流量转发未正确配置"
fi
}
# 检查时间同步
check_time_sync() {
((CHECK_NUM++))
print_info "检查时间同步..."
if systemctl is-active --quiet chronyd 2>/dev/null || systemctl is-active --quiet ntpd 2>/dev/null; then
NTP_SYNCED=$(timedatectl 2>/dev/null | grep "NTP synchronized" | awk '{print $3}' || echo "no")
echo " NTP同步状态: $NTP_SYNCED"
if [ "$NTP_SYNCED" == "yes" ]; then
print_success "时间同步已启用且正常"
else
print_warning "时间同步服务运行中但未同步"
fi
else
print_error "时间同步服务未运行"
fi
}
# 执行所有检查
run_check() {
CHECK_NUM=0
print_header "Kubernetes 环境检查"
print_header "1. 硬件资源检查"
check_cpu
check_memory
check_disk
print_header "2. 系统环境检查"
check_os
check_arch
check_kernel
print_header "3. 系统配置检查"
check_firewall
check_swap
check_selinux
check_hostname
check_bridge
check_time_sync
print_header "检查结果汇总"
echo -e "总检查项: ${BOLD}$CHECK_NUM${NC} ${GREEN}✓ 通过: $PASS_COUNT${NC} ${YELLOW}⚠ 警告: $WARN_COUNT${NC} ${RED}✗ 失败: $FAIL_COUNT${NC}"
echo ""
if [ $FAIL_COUNT -gt 0 ]; then
echo -e "${RED}发现 $FAIL_COUNT 项不符合要求,请运行修复: $0 fix${NC}"
return 1
elif [ $WARN_COUNT -gt 0 ]; then
echo -e "${YELLOW}发现 $WARN_COUNT 项警告,建议检查${NC}"
return 0
else
echo -e "${GREEN}所有检查项均通过!${NC}"
return 0
fi
}
# 关闭防火墙
fix_firewall() {
((CHECK_NUM++))
print_info "关闭防火墙..."
systemctl stop firewalld 2>/dev/null || true
systemctl disable firewalld 2>/dev/null || true
print_success "防火墙已关闭并禁用"
}
# 关闭SWAP
fix_swap() {
((CHECK_NUM++))
print_info "关闭SWAP..."
swapoff -a 2>/dev/null || true
sed -i.bak '/swap/s/^/#/' /etc/fstab 2>/dev/null || true
print_success "SWAP已关闭并永久禁用"
}
# 禁用SELinux
fix_selinux() {
((CHECK_NUM++))
print_info "禁用SELinux..."
setenforce 0 2>/dev/null || true
if [ -f /etc/selinux/config ]; then
sed -i.bak 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
sed -i 's/^SELINUX=permissive/SELINUX=disabled/' /etc/selinux/config
fi
print_success "SELinux已禁用(重启后生效)"
}
# 配置主机名解析
fix_hostname() {
((CHECK_NUM++))
print_info "配置主机名解析..."
HOSTNAME=$(hostname 2>/dev/null || echo "localhost")
HOSTNAME_IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")
# 删除旧的主机名条目
sed -i.bak "/$HOSTNAME/d" /etc/hosts 2>/dev/null || true
# 添加新的主机名解析
echo "$HOSTNAME_IP $HOSTNAME" >> /etc/hosts
print_success "主机名解析已配置: $HOSTNAME_IP $HOSTNAME"
}
# 启用桥接流量转发
fix_bridge() {
((CHECK_NUM++))
print_info "配置桥接流量转发..."
# 加载br_netfilter模块
modprobe br_netfilter 2>/dev/null || true
echo "br_netfilter" > /etc/modules-load.d/k8s.conf
# 配置内核参数
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 >/dev/null 2>&1 || true
print_success "桥接流量转发已配置"
}
# 配置时间同步
fix_time_sync() {
((CHECK_NUM++))
print_info "配置时间同步..."
if ! command -v chronyd &> /dev/null; then
echo " 正在安装chrony..."
yum install -y chrony >/dev/null 2>&1 || true
fi
# 配置国内NTP服务器
cat > /etc/chrony.conf <<EOF
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
server ntp.ntsc.ac.cn iburst
server time1.cloud.tencent.com iburst
server time2.cloud.tencent.com iburst
driftfile /var/lib/chrony/drift
# allow 192.168.0.0/16
makestep 1.0 3
rtcsync
logdir /var/log/chrony
EOF
systemctl restart chronyd 2>/dev/null || true
systemctl enable chronyd 2>/dev/null || true
timedatectl set-ntp true 2>/dev/null || true
print_success "时间同步已配置"
}
# 执行修复
run_fix() {
check_root
print_header "Kubernetes 环境修复"
print_info "开始修复配置..."
echo ""
fix_firewall
fix_swap
fix_selinux
fix_hostname
fix_bridge
fix_time_sync
print_header "修复完成"
echo -e "${GREEN}所有配置项已修复完成${NC}"
echo -e "${YELLOW}注意: SELinux禁用需要重启系统后生效${NC}"
echo ""
echo "建议执行以下命令验证:"
echo " $0 check"
}
# 设置hosts
set_host() {
check_root
if [ $# -lt 1 ]; then
echo "用法: $0 set-host <hostname> [ip]"
echo "示例: $0 set-host k8s-master 192.168.1.100"
echo " $0 set-host k8s-master (使用本机第一个IP)"
exit 1
fi
HOSTNAME=$1
IP=${2:-}
if [ -z "$IP" ]; then
print_info "未指定IP,使用本机第一个IP地址"
IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "127.0.0.1")
fi
# 验证IP格式
if ! [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
print_error "IP地址格式不正确: $IP"
exit 1
fi
print_info "设置hosts解析: $IP $HOSTNAME"
# 删除旧的条目
sed -i.bak "/$HOSTNAME/d" /etc/hosts 2>/dev/null || true
# 添加新的条目
echo "$IP $HOSTNAME" >> /etc/hosts
print_success "Hosts解析已设置"
echo ""
echo "当前/etc/hosts内容:"
cat /etc/hosts
}
# 主函数
main() {
case "${1:-}" in
check)
run_check
;;
fix)
run_fix
;;
set-host)
shift
set_host "$@"
;;
*)
echo "Kubernetes 环境检查与修复脚本"
echo ""
echo "用法:"
echo " $0 check - 检查环境配置"
echo " $0 fix - 修复环境配置"
echo " $0 set-host <主机名> [IP] - 设置hosts解析"
echo ""
echo "示例:"
echo " $0 check"
echo " $0 fix"
echo " $0 set-host k8s-master 192.168.1.100"
echo " $0 set-host k8s-master # 使用本机IP"
echo ""
echo "在线使用:"
echo " curl -sSL <脚本URL> | bash -s check"
echo " curl -sSL <脚本URL> | bash -s fix"
echo " curl -sSL <脚本URL> | bash -s set-host k8s-master 192.168.1.100"
exit 1
;;
esac
}
main "$@"
#!/bin/bash
# 国内NTP时间同步脚本 - 配置并同步北京时间
# 使用方法: chmod +x sync_time.sh && sudo ./sync_time.sh
set -e
echo "=========================================="
echo " 国内NTP时间同步配置脚本"
echo "=========================================="
# 检查是否为root用户
if [ "$EUID" -ne 0 ]; then
echo "错误: 请使用root权限运行此脚本"
echo "使用方法: sudo $0"
exit 1
fi
# 备份原配置文件
echo "[1/5] 备份原始配置文件..."
if [ -f /etc/chrony.conf ]; then
cp /etc/chrony.conf /etc/chrony.conf.bak.$(date +%Y%m%d%H%M%S)
echo "✓ 已备份到 /etc/chrony.conf.bak.*"
fi
# 创建新的chrony配置文件
echo "[2/5] 配置国内NTP服务器..."
cat > /etc/chrony.conf << 'EOF'
# 使用国内NTP服务器
# 阿里云NTP服务器
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst
# 腾讯云NTP服务器(备用)
server time1.cloud.tencent.com iburst
server time2.cloud.tencent.com iburst
# 中国国家授时中心NTP服务器(备用)
server ntp.ntsc.ac.cn iburst
# 记录系统时钟的增减速率
driftfile /var/lib/chrony/drift
# 允许系统时钟在前三次更新中进行大幅度调整
# 如果时间偏差超过1秒,则直接修正
makestep 1.0 3
# 启用内核模式,同步硬件时钟
rtcsync
# 允许本地网络的NTP客户端访问(可选)
# allow 192.168.0.0/16
# 日志目录
logdir /var/log/chrony
# 即使未同步到时间源也提供时间服务(可选)
# local stratum 10
EOF
echo "✓ 配置文件已更新"
# 设置时区为Asia/Shanghai(北京时间)
echo "[3/5] 设置时区为Asia/Shanghai..."
timedatectl set-timezone Asia/Shanghai
echo "✓ 时区已设置为北京时间"
# 启用NTP同步
echo "[4/5] 启用NTP同步..."
timedatectl set-ntp true
echo "✓ NTP同步已启用"
# 重启chronyd服务
echo "[5/5] 重启chronyd服务..."
systemctl restart chronyd
systemctl enable chronyd
sleep 2
echo "✓ chronyd服务已重启并设置为开机自启"
# 强制立即同步时间
echo ""
echo "强制同步时间..."
chronyc makestep
sleep 2
# 显示同步状态
echo ""
echo "=========================================="
echo " 同步状态检查"
echo "=========================================="
echo ""
echo "当前系统时间信息:"
timedatectl
echo ""
echo "----------------------------------------"
echo "Chrony同步源状态:"
chronyc sources -v
echo ""
echo "----------------------------------------"
echo "Chrony跟踪状态:"
chronyc tracking
echo ""
echo "=========================================="
echo "✓ 时间同步配置完成!"
echo "=========================================="
echo ""
echo "说明:"
echo "- 系统已配置使用国内NTP服务器"
echo "- 时区已设置为Asia/Shanghai(北京时间)"
echo "- chronyd服务已启动并设置为开机自启"
echo ""
echo "常用命令:"
echo " 查看同步状态: chronyc tracking"
echo " 查看时间源: chronyc sources -v"
echo " 强制同步: chronyc makestep"
echo " 查看时间: timedatectl"
echo ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment