gongdear

gongdear的技术博客

欢迎大家参观我的博客
  menu
117 文章
89355 浏览
10 当前访客
ღゝ◡╹)ノ❤️

基于Proxmox VE 9.1 环境的Kubernetes v1.35 高可用控制平面部署指南

基于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-02k8s-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.yamlrotateCertificates: 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

本方案已在实际环境中验证,适用于开发、测试及轻量级生产场景。

宝剑锋从磨砺出,梅花香自苦寒来.