基于Proxmox VE 9.1 环境的Kubernetes v1.35 高可用控制平面部署指南
Proxmox VE 9.1 环境
三台高可用虚拟机
配置为8 核 CPU、16 GB 内存、256 GB SSD开启writeback和discard
操作系统ubuntu24.04 amd64
192.168.7.51 k8s-control-plane-01
192.168.7.52 k8s-control-plane-02
192.168.7.53 k8s-control-plane-03
1. 主机名与网络配置
在所有控制平面节点上执行以下操作,确保主机名解析一致:
sudo tee -a /etc/hosts <<EOF
192.168.7.51 k8s-control-plane-01 k8s-control-plane-01.forestry
192.168.7.52 k8s-control-plane-02 k8s-control-plane-02.forestry
192.168.7.53 k8s-control-plane-03 k8s-control-plane-03.forestry
EOF
同时确认每台主机的 /etc/hostname 文件内容与上述名称一致。
2. 禁用 Swap 并配置内核参数
Kubernetes 要求禁用 swap:
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
加载必要的内核模块:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
配置 sysctl 参数:
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
3. 安装 containerd 运行时
3.1 安装二进制文件
# 解压 containerd
sudo tar Cxzvf /usr/local containerd-2.2.1-linux-amd64.tar.gz
# 安装 runc
sudo install -m 755 runc.amd64 /usr/local/sbin/runc
# 安装 CNI 插件
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.9.0.tgz
3.2 生成并修改配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 启用 systemd cgroup 驱动
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
3.3 配置 systemd 服务
sudo curl -fsSLo /etc/systemd/system/containerd.service \
https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo systemctl daemon-reload
sudo systemctl enable --now containerd
4. 安装 crictl
VERSION="v1.35.0"
wget https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-$VERSION-linux-amd64.tar.gz
sudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/bin
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 10
debug: false
EOF
验证配置:
crictl info | grep '"systemdCgroup": true'
应有输出,表明配置正确。
5. 安装 kubeadm、kubelet 和 kubectl
5.1 配置 APT 源(使用清华大学镜像)
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.35/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://mirrors.tuna.tsinghua.edu.cn/kubernetes/core:/stable:/v1.35/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
5.2 安装指定版本
sudo apt update
sudo apt install -y kubelet=1.35.0-1.1 kubeadm=1.35.0-1.1 kubectl=1.35.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl
注意:此时不要启动 kubelet,由 kubeadm 初始化后自动管理。
6. 部署外部负载均衡器(HAProxy)
在独立主机 192.168.7.8 上配置 HAProxy:
# /etc/haproxy/haproxy.cfg
frontend k8s-api
bind *:6443
mode tcp
option tcplog
default_backend k8s-api-nodes
backend k8s-api-nodes
mode tcp
balance roundrobin
server cp1 192.168.7.51:6443 check
server cp2 192.168.7.52:6443 check
server cp3 192.168.7.53:6443 check
重启服务:
sudo systemctl restart haproxy
API Server 访问地址为:https://192.168.7.8:6443
7. 初始化第一个控制平面节点
创建 kubeadm 配置文件:
# /etc/kubernetes/kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.35.0
controlPlaneEndpoint: "192.168.7.8:6443"
networking:
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
nodeRegistration:
criSocket: "unix:///run/containerd/containerd.sock"
执行初始化(务必加上 --upload-certs):
sudo kubeadm init --config /etc/kubernetes/kubeadm-config.yaml --upload-certs
初始化成功后,按提示配置 kubectl:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
8. 部署 Flannel CNI
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
等待几分钟,直到节点状态变为 Ready:
kubectl get nodes
9. 加入其余控制平面节点
在 k8s-control-plane-02 和 k8s-control-plane-03 上完成前述步骤 1–5 后,执行 join 命令。
从第一个节点的 kubeadm init 输出中获取以下信息:
- token(如
ni7w9j.l9tvvh3oy76ont6p) - discovery-token-ca-cert-hash(如
sha256:c413...) - certificate key(若使用
--upload-certs,init 输出中会直接显示)
在新节点上运行:
sudo kubeadm join 192.168.7.8:6443 \
--token <your-token> \
--discovery-token-ca-cert-hash sha256:<hash> \
--control-plane \
--cri-socket unix:///run/containerd/containerd.sock \
--certificate-key <your-cert-key>
加入后无需额外操作,Flannel DaemonSet 会自动部署到新节点。
最终验证:
kubectl get nodes
# 应显示三个 Ready 状态的 control-plane 节点
10. 配置证书自动续签
Kubelet 客户端证书默认自动轮转(检查 /var/lib/kubelet/config.yaml 中 rotateCertificates: true)。
控制平面组件(apiserver、etcd 等)的证书需手动续签。建议通过 systemd timer 定期执行。
10.1 创建续签脚本
# /usr/local/bin/k8s-cert-renew.sh
#!/bin/bash
LOGFILE="/var/log/k8s-cert-renew.log"
exec >> "$LOGFILE" 2>&1
echo "[$(date)] Starting certificate renewal check..."
# 检查证书有效期
if sudo kubeadm certs check-expiration | grep -q "apiserver" && ! sudo kubeadm certs check-expiration | grep -E "(apiserver|etcd-server)" | awk '{print $2}' | xargs -I {} date -d {} +%s 2>/dev/null | while read expiry; do
now=$(date +%s)
if [ $((expiry - now)) -lt 2592000 ]; then # 小于30天
echo "Certificate expiring soon. Renewing..."
sudo kubeadm certs renew all
sudo systemctl restart kubelet
echo "Renewal completed."
exit 0
fi
done; then
echo "All certificates are valid."
fi
赋予执行权限:
sudo chmod +x /usr/local/bin/k8s-cert-renew.sh
10.2 配置 systemd 服务与定时器
# /etc/systemd/system/k8s-cert-renew.service
[Unit]
Description=Renew Kubernetes control plane certificates
[Service]
Type=oneshot
ExecStart=/usr/local/bin/k8s-cert-renew.sh
# /etc/systemd/system/k8s-cert-renew.timer
[Unit]
Description=Run Kubernetes certificate renewal weekly
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
启用定时器:
sudo systemctl daemon-reload
sudo systemctl enable --now k8s-cert-renew.timer
验证:
systemctl list-timers | grep k8s
sudo systemctl start k8s-cert-renew.service # 手动测试
tail /var/log/k8s-cert-renew.log
附录:注意事项
- 镜像拉取:国内环境建议提前使用脚本从阿里云等镜像仓库拉取所需镜像,并重命名为 kubeadm 所需格式。
- 时间同步:确保所有节点已配置 NTP 或 chrony,时间偏差可能导致证书验证失败。
- 防火墙:开放必要端口(6443、2379-2380、10250、10259、10257、8472/UDP 等)。
- 备份:定期备份
/etc/kubernetes/pki和/etc/kubernetes/admin.conf。
本方案已在实际环境中验证,适用于开发、测试及轻量级生产场景。