K8S高可用环境搭建与系统优化
引言
在部署生产级Kubernetes集群时,高可用性(High Availability, HA)是首要考虑的因素。一个高可用的K8S集群能够确保在单个或多个节点故障时,业务依然能够稳定运行。本文将手把手带你完成K8S高可用集群的基础环境搭建与系统优化,这是构建稳健K8S地基的关键第一步。
一、环境规划
1.1 架构设计
我们采用典型的"三节点"高可用架构,即三个节点同时承担控制平面(Control Plane)和工作节点(Worker)的角色。这种简化架构适合资源有限的学习和测试环境,同时保持了控制层面的高可用性。
[ 外部负载均衡器 / VIP: 10.0.0.240 ]
|
-----------------------------------------------------
| | |
[k8s-cluster241] [k8s-cluster242] [k8s-cluster243]
10.0.0.241 10.0.0.242 10.0.0.243
etcd成员1 etcd成员2 etcd成员3
kube-apiserver kube-apiserver kube-apiserver
kube-controller-manager kube-scheduler kube组件...
kubelet kubelet kubelet
kube-proxy kube-proxy kube-proxy
1.2 硬件与网络配置
| 主机名 | IP地址 | 角色 | 最低配置 |
|---|---|---|---|
| k8s-cluster241 | 10.0.0.241 | Master + Worker | 2核CPU, 4GB内存, 100GB磁盘 |
| k8s-cluster242 | 10.0.0.242 | Master + Worker | 2核CPU, 4GB内存, 100GB磁盘 |
| k8s-cluster243 | 10.0.0.243 | Master + Worker | 2核CPU, 4GB内存, 100GB磁盘 |
| apiserver-lb | 10.0.0.240 | 负载均衡VIP | - |
温馨提示:如果硬件资源有限,可以将多种角色进行复用。生产环境建议将etcd集群与控制平面分离部署。
二、系统基础优化
2.1 基础软件安装
在所有节点上执行以下命令,安装必要的工具包:
# 更新源并安装常用工具
apt update && apt -y install bind9-utils expect rsync jq psmisc net-tools lvm2 vim unzip rename tree
# 安装IPVS相关工具(kube-proxy的IPVS模式依赖)
apt -y install ipvsadm ipset sysstat conntrack
2.2 主机名与DNS配置
在主节点(k8s-cluster241)上配置所有节点的hosts解析:
cat >> /etc/hosts <<'EOF'
10.0.0.240 apiserver-lb
10.0.0.241 k8s-cluster241
10.0.0.242 k8s-cluster242
10.0.0.243 k8s-cluster243
EOF
2.3 配置SSH免密登录
为了方便集群管理,配置节点间的SSH免密登录:
# 创建免密登录脚本
cat > password_free_login.sh <<'EOF'
#!/bin/bash
# 创建密钥对
ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa -q
# 声明服务器密码(建议所有节点密码一致)
export mypasswd=1
# 定义主机列表
k8s_host_list=(k8s-cluster241 k8s-cluster242 k8s-cluster243)
# 配置免密登录
for i in ${k8s_host_list[@]};do
expect -c "
spawn ssh-copy-id -i /root/.ssh/id_rsa.pub root@$i
expect {
\"*yes/no*\" {send \"yes\r\"; exp_continue}
\"*password*\" {send \"$mypasswd\r\"; exp_continue}
}"
done
EOF
# 执行脚本
bash password_free_login.sh
2.4 创建数据同步脚本
编写一个通用的数据同步脚本,方便在集群间分发配置文件:
cat > /usr/local/sbin/data_rsync.sh <<'EOF'
#!/bin/bash
if [ $# -lt 1 ];then
echo "Usage: $0 /path/to/file(绝对路径) [mode: m|w]"
exit
fi
if [ ! -e $1 ];then
echo "[ $1 ] dir or file not find!"
exit
fi
fullpath=`dirname $1`
basename=`basename $1`
cd $fullpath
case $2 in
WORKER_NODE|w)
K8S_NODE=(k8s-cluster242 k8s-cluster243)
;;
MASTER_NODE|m)
K8S_NODE=(k8s-cluster242 k8s-cluster243)
;;
*)
K8S_NODE=(k8s-cluster242 k8s-cluster243)
;;
esac
for host in ${K8S_NODE[@]};do
tput setaf 2
echo ===== rsyncing ${host}: $basename =====
tput setaf 7
rsync -az $basename `whoami`@${host}:$fullpath
if [ $? -eq 0 ];then
echo "命令执行成功!"
fi
done
EOF
chmod +x /usr/local/sbin/data_rsync.sh
# 测试同步hosts文件
data_rsync.sh /etc/hosts
三、深度系统调优
3.1 禁用不必要的服务
# 禁用NetworkManager和UFW防火墙
systemctl disable --now NetworkManager ufw
3.2 关闭Swap并优化内存参数
Kubernetes 1.8+要求必须禁用Swap,以确保kubelet正常工作:
# 临时关闭Swap
swapoff -a
# 永久禁用Swap
sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
# 调整内存交换策略
sysctl -w vm.swappiness=0
3.3 时区与文件句柄优化
# 设置时区
ln -svf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 调整文件句柄数限制
cat >> /etc/security/limits.conf <<'EOF'
* soft nofile 655360
* hard nofile 131072
* soft nproc 655350
* hard nproc 655350
* soft memlock unlimited
* hard memlock unlimited
EOF
3.4 SSH服务优化
# 禁用DNS解析加速SSH连接
sed -i 's@#UseDNS yes@UseDNS no@g' /etc/ssh/sshd_config
sed -i 's@^GSSAPIAuthentication yes@GSSAPIAuthentication no@g' /etc/ssh/sshd_config
systemctl restart sshd
3.5 内核参数调优
创建K8S专用的内核参数配置文件:
cat > /etc/sysctl.d/k8s.conf <<'EOF'
# 开启IP转发(容器网络必需)
net.ipv4.ip_forward = 1
# 开启网桥数据包转发
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
# 禁用IPv6(可选)
net.ipv6.conf.all.disable_ipv6 = 1
# 容器运行时相关参数
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
# 文件系统限制
fs.file-max=52706963
fs.nr_open=52706963
# 连接跟踪表大小
net.netfilter.nf_conntrack_max=2310720
# TCP网络优化
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_intvl =15
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.core.somaxconn = 16384
EOF
# 应用内核参数
sysctl --system
3.6 加载IPVS内核模块
Kube-proxy的IPVS模式相比iptables模式有更好的性能和可扩展性:
# 创建IPVS模块加载配置
cat > /etc/modules-load.d/ipvs.conf << 'EOF'
ip_vs
ip_vs_lc
ip_vs_wlc
ip_vs_rr
ip_vs_wrr
ip_vs_lblc
ip_vs_lblcr
ip_vs_dh
ip_vs_sh
ip_vs_fo
ip_vs_nq
ip_vs_sed
ip_vs_ftp
nf_conntrack
br_netfilter
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
# 重启系统使模块生效
reboot
四、容器运行时安装
4.1 卸载旧版Docker(如存在)
# 如果有docker环境,请卸载
./install-docker.sh r
ip link del docker0
4.2 安装Containerd
Containerd是CNCF毕业项目,比Docker更轻量,是K8S推荐的运行时:
# 1. 下载二进制包
wget https://github.com/containerd/containerd/releases/download/v1.7.19/containerd-1.7.19-linux-amd64.tar.gz
# 2. 解压到系统目录
sudo tar Cxzvf /usr/local containerd-1.7.19-linux-amd64.tar.gz
# 3. 下载runc(容器运行工具)
wget https://github.com/opencontainers/runc/releases/download/v1.1.12/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
# 4. 下载CNI插件(容器网络)
wget https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.4.0.tgz
# 5. 创建配置文件目录
sudo mkdir -p /etc/containerd
# 6. 生成默认配置
containerd config default | sudo tee /etc/containerd/config.toml
# 7. 修改配置(使用systemd cgroup驱动)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 8. 创建systemd服务文件
sudo cat > /etc/systemd/system/containerd.service <<EOF
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target
[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=infinity
TasksMax=infinity
OOMScoreAdjust=-999
[Install]
WantedBy=multi-user.target
EOF
# 9. 启动并启用服务
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
# 10. 验证安装
sudo containerd --version
4.3 验证安装
# 检查Containerd版本
ctr version
# 预期输出
Client:
Version: v1.6.36
Revision: 88c3d9bc5b5a193f40b7c14fa996d23532d6f956
Go version: go1.22.7
Server:
Version: v1.6.36
Revision: 88c3d9bc5b5a193f40b7c14fa996d23532d6f956
UUID: 02339237-7847-4564-9733-1e6ac9618a33
五、验证与检查
5.1 检查内核模块加载
重启后验证IPVS等内核模块是否加载成功:
lsmod | grep --color=auto -e ip_vs -e nf_conntrack -e br_netfilter
# 预期看到大量IPVS相关模块
5.2 检查系统资源
free -h
# 确认Swap全部为0
uname -r
# 确认内核版本
ifconfig
# 确认网络配置
5.3 创建环境快照
在继续后续部署前,建议创建虚拟机快照:
快照名称: 'k8s操作系统环境准备就绪'
六、常见问题排查
问题1:IPVS模块未加载
症状:lsmod | grep ip_vs 无输出
解决:
# 手动加载模块
modprobe ip_vs
modprobe ip_vs_rr
# ... 加载其他所需模块
# 检查模块依赖
depmod -a
问题2:Swap仍然启用
症状:free -h 显示Swap有值
解决:
# 检查/etc/fstab中是否有swap条目
grep -i swap /etc/fstab
# 注释掉所有swap行
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab
问题3:文件句柄数限制未生效
症状:ulimit -n 显示值较小
解决:
# 检查limits.conf配置
grep -v "^#" /etc/security/limits.conf | grep -v "^$"
# 重新登录或重启系统
总结
至此,我们已经完成了K8S高可用集群的基础环境搭建。关键要点总结:
- 规划先行:合理的架构设计是成功的一半
- 系统优化:内核参数、资源限制、网络配置缺一不可
- 工具准备:SSH免密、同步脚本能极大提升效率
- 模块加载:IPVS等内核模块是高性能网络的基础
- 容器运行时:Containerd是现代化K8S的首选
经验分享:生产环境中,建议将上述优化步骤制作成系统镜像或使用Ansible等自动化工具部署,确保环境的一致性。