Skip to content

内网 Kubernetes 高可用集群部署指南

环境说明

本教程基于以下环境配置:

  • 集群拓扑:3 个 Master 节点 + 2 个 Worker 节点
  • 操作系统:Debian 13
  • 网络段:172.18.0.0/16
  • 部署方式:内网环境,使用 kubeadm + Keepalived + HAProxy 实现高可用

第一步:所有节点前置配置

以下操作需要在所有节点(Master 和 Worker)上执行,确保集群基础环境一致性。

1.1 关闭 Swap 分区

Kubernetes 要求关闭 Swap 分区以保证 Pod 的性能可预测性和资源隔离。Swap 会导致内存管理的不确定性,影响 Kubernetes 的调度和资源限制机制。

bash
swapoff -a
vi /etc/fstab
# 删除或注释掉 swap 相关行

1.2 配置国内软件源

由于网络环境限制,需要将 APT 源替换为清华大学镜像站以加速软件包下载。

编辑 /etc/apt/sources.list 文件,删除或注释原有内容,添加以下配置:

bash
# 默认注释了源码镜像,如有需要可自行取消注释
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie main contrib non-free non-free-firmware

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-updates main contrib non-free non-free-firmware

deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-backports main contrib non-free non-free-firmware

deb https://mirrors.tuna.tsinghua.edu.cn/debian-security/ trixie-security main contrib non-free non-free-firmware

1.3 配置主机名解析

为集群节点配置主机名映射,避免依赖外部 DNS,提高集群内部通信的稳定性和响应速度。

将以下内容添加到 /etc/hosts 文件:

bash
172.18.130.1 master-01
172.18.130.2 master-02
172.18.130.3 master-03
172.18.130.4 node-04
172.18.130.5 node-05

1.4 配置防火墙规则

Kubernetes 集群组件之间需要大量的网络通信,需要配置防火墙以允许必要的流量。

bash
sudo apt install ufw ipset
sudo ufw allow ssh
ufw allow from 172.18.0.0/16  # 允许集群网段内的所有流量
sudo ufw default deny incoming  # 拒绝其他入站流量
sudo ufw default allow outgoing  # 允许所有出站流量
ufw enable
ufw status  # 查看防火墙规则

1.5 配置时间同步

Kubernetes 集群对时间同步有严格要求,证书验证、日志排序、分布式协调(如 etcd)都依赖准确的时间。通过 NTP 确保所有节点时间一致。

bash
apt install ntpsec
vi /etc/ntpsec/ntp.conf

# 添加以下阿里云 NTP 服务器配置
server ntp.aliyun.com iburst
server ntp1.aliyun.com iburst
server ntp2.aliyun.com iburst
server ntp3.aliyun.com iburst

systemctl restart ntpsec
systemctl enable ntpsec

ntpq -p  # 验证时间同步状态

1.6 加载必要的内核模块

Kubernetes 的网络插件需要内核支持 overlay 网络和桥接流量的 iptables 处理能力。

bash
# 配置开机自动加载内核模块
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

# 立即加载模块
sudo modprobe overlay
sudo modprobe br_netfilter

# 配置内核参数,使 iptables 能够正确处理桥接流量
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

参数说明:

  • overlay:支持 OverlayFS,容器运行时所需
  • br_netfilter:支持网桥过滤,Pod 间通信所需
  • net.ipv4.ip_forward:启用 IP 转发,跨节点通信的基础

1.7 安装 Kubernetes 仓库和必要软件包

根据 Kubernetes 官方文档配置 APT 仓库并安装核心组件。

更新软件包索引并安装依赖工具

bash
sudo apt-get update
# apt-transport-https 可能是虚拟包,若已存在可跳过安装
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

下载 Kubernetes 软件包仓库的公共签名密钥

所有版本的 Kubernetes 仓库使用相同的签名密钥。

bash
# 如果 /etc/apt/keyrings 目录不存在,需先创建
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

说明:在低于 Debian 12 和 Ubuntu 22.04 的发行版中,/etc/apt/keyrings 默认不存在,需手动创建。

添加 Kubernetes APT 仓库

此仓库仅包含 Kubernetes 1.34 版本的软件包。若需其他版本,需修改 URL 中的版本号。

bash
# 此操作会覆盖 /etc/apt/sources.list.d/kubernetes.list 中现存的所有配置
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.34/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

安装 Kubernetes 核心组件和容器运行时

bash
# 更新软件包列表
sudo apt-get update

# 查看可用的 kubeadm 版本
apt-cache madison kubeadm

# 一次性安装 containerd 和 Kubernetes 组件
sudo apt-get install -y kubelet kubeadm kubectl containerd

# 锁定这些软件包的版本,防止意外升级
sudo apt-mark hold kubelet kubeadm kubectl containerd

# (可选)启用 kubelet 服务,该服务会在 kubeadm init 后自动启动
sudo systemctl enable --now kubelet

版本锁定的必要性:

  • Kubernetes 集群对版本敏感,组件版本不一致可能导致兼容性问题
  • 防止自动更新导致集群异常

1.8 配置 Containerd 容器运行时

Containerd 是 Kubernetes 推荐的容器运行时,需配置 Cgroup 驱动和镜像加速。

步骤 1:生成默认配置文件并启用 SystemdCgroup

bash
# 创建配置目录
sudo mkdir -p /etc/containerd

# 生成默认配置文件
sudo containerd config default | sudo tee /etc/containerd/config.toml

# 启用 SystemdCgroup(Kubernetes 推荐使用 systemd 作为 Cgroup 驱动)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 指定配置补丁目录(用于存放镜像加速配置)
sudo sed -i 's|config_path = ""|config_path = "/etc/containerd/conf.d"|g' /etc/containerd/config.toml

配置说明:

  • SystemdCgroup = true:确保 Containerd 与 Kubelet 使用相同的 Cgroup 驱动,避免资源管理冲突
  • config_path:启用模块化配置目录,便于管理镜像加速等独立配置

步骤 2:配置镜像加速(使用 certs.d 方式)

由于国内网络环境限制,需要配置镜像加速以提高镜像拉取速度。本配置采用 DaoCloud 公共镜像镜像

镜像站映射关系

源站加速站点说明
docker.iodocker.m.daocloud.ioDocker Hub
gcr.iogcr.m.daocloud.ioGoogle Container Registry
ghcr.ioghcr.m.daocloud.ioGitHub Container Registry
registry.k8s.iok8s.m.daocloud.ioKubernetes 官方镜像
k8s.gcr.iok8s-gcr.m.daocloud.ioKubernetes 旧镜像地址
quay.ioquay.m.daocloud.ioRed Hat Quay 仓库
mcr.microsoft.commcr.m.daocloud.ioMicrosoft Container Registry
nvcr.ionvcr.m.daocloud.ioNVIDIA Container Registry

创建镜像仓库配置目录

bash
sudo mkdir -p /etc/containerd/certs.d

为各个镜像仓库创建配置文件

Docker Hub (docker.io):

bash
mkdir -p /etc/containerd/certs.d/docker.io
sudo tee /etc/containerd/certs.d/docker.io/hosts.toml <<EOF
server = "https://docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

gcr.io:

bash
mkdir -p /etc/containerd/certs.d/gcr.io
sudo tee /etc/containerd/certs.d/gcr.io/hosts.toml <<EOF
server = "https://gcr.io"

[host."https://gcr.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

ghcr.io:

bash
mkdir -p /etc/containerd/certs.d/ghcr.io
sudo tee /etc/containerd/certs.d/ghcr.io/hosts.toml <<EOF
server = "https://ghcr.io"

[host."https://ghcr.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

registry.k8s.io:

bash
mkdir -p /etc/containerd/certs.d/registry.k8s.io
sudo tee /etc/containerd/certs.d/registry.k8s.io/hosts.toml <<EOF
server = "https://registry.k8s.io"

[host."https://k8s.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

k8s.gcr.io(旧地址):

bash
mkdir -p /etc/containerd/certs.d/k8s.gcr.io
sudo tee /etc/containerd/certs.d/k8s.gcr.io/hosts.toml <<EOF
server = "https://k8s.gcr.io"

[host."https://k8s-gcr.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

quay.io:

bash
sudo mkdir -p /etc/containerd/certs.d/quay.io
sudo tee /etc/containerd/certs.d/quay.io/hosts.toml <<EOF
server = "https://quay.io"

[host."https://quay.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

mcr.microsoft.com:

bash
mkdir -p /etc/containerd/certs.d/mcr.microsoft.com
sudo tee /etc/containerd/certs.d/mcr.microsoft.com/hosts.toml <<EOF
server = "https://mcr.microsoft.com"

[host."https://mcr.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

nvcr.io:

bash
mkdir -p /etc/containerd/certs.d/nvcr.io
sudo tee /etc/containerd/certs.d/nvcr.io/hosts.toml <<EOF
server = "https://nvcr.io"

[host."https://nvcr.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
EOF

步骤 3:修改 Containerd 主配置文件

编辑 /etc/containerd/config.toml,确认已启用 certs.d 目录:

bash
vim /etc/containerd/config.toml

确认以下配置存在(已在步骤 1 中配置):

toml
version = 2

[plugins."io.containerd.grpc.v1.cri".registry]
  config_path = "/etc/containerd/certs.d"

步骤 4:重启 Containerd 服务

bash
sudo systemctl restart containerd
sudo systemctl status containerd

步骤 5:验证配置

bash
# 查看配置目录是否创建成功
ls -la /etc/containerd/certs.d/

# 测试拉取镜像
sudo crictl pull registry.k8s.io/pause:3.9
sudo crictl pull docker.io/library/nginx

certs.d 方式的优势

  • 模块化管理:每个镜像仓库独立配置,便于维护
  • 易于更新:修改单个仓库配置无需重启整个服务
  • 支持多个镜像源:可为同一仓库配置多个加速地址
  • 优先级控制:配置文件中的顺序决定尝试顺序

第二步:Master 节点高可用配置

以下操作需要在所有 Master 节点(master-01、master-02、master-03)上执行。

高可用架构通过 Keepalived + HAProxy 实现:

  • Keepalived:实现虚拟 IP(VIP)的漂移,确保 VIP 始终指向健康的 Master 节点
  • HAProxy:作为 API Server 的负载均衡器,将请求分发到所有健康的 Master 节点

2.1 安装 Keepalived 和 HAProxy

bash
sudo apt-get update
sudo apt-get install -y keepalived haproxy

2.2 配置 HAProxy

HAProxy 负责接收来自 VIP 的请求,并将其负载均衡到三个 Master 节点的 API Server。

备份原始配置文件

bash
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak

创建新的 HAProxy 配置

编辑 /etc/haproxy/haproxy.cfg,添加以下内容:

bash
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    ca-base /etc/ssl/certs
    crt-base /etc/ssl/private

#---------------------------------------------------------------------
# Common defaults that all the 'listen' and 'backend' sections will
# use if not overridden
#---------------------------------------------------------------------
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option                  http-server-close
    option                  forwardfor    except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

#---------------------------------------------------------------------
# Frontend for Kubernetes API Server
#---------------------------------------------------------------------
frontend kubernetes-apiserver
    # 绑定到 VIP 的 6443 端口
    bind 172.18.130.100:6443
    mode tcp
    option tcplog
    default_backend kube-apiserver-backend

#---------------------------------------------------------------------
# Backend for Kubernetes API Server
#---------------------------------------------------------------------
backend kube-apiserver-backend
    mode tcp
    option tcp-check
    balance roundrobin
    # 后端 Master 节点列表
    server master1 172.18.130.1:6443 check fall 3 rise 2
    server master2 172.18.130.2:6443 check fall 3 rise 2
    server master3 172.18.130.3:6443 check fall 3 rise 2

配置说明

  • bind 172.18.130.100:6443:HAProxy 监听 VIP 的 6443 端口(Kubernetes API Server 端口)
  • mode tcp:使用 TCP 模式转发 HTTPS 流量
  • balance roundrobin:使用轮询算法分发请求
  • check fall 3 rise 2:健康检查机制,连续 3 次失败标记为下线,连续 2 次成功标记为上线

2.3 配置 Keepalived

Keepalived 负责管理 VIP 的漂移。三台 Master 节点的配置略有不同,主要体现在 statepriority 参数上。

在 master-01 上配置(最高优先级)

创建 /etc/keepalived/keepalived.conf 文件:

bash
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight 20
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 102
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.18.130.100/24
    }
    track_script {
        check_haproxy
    }
}

重要参数说明

  • state MASTER:初始状态为主节点
  • interface eth0:根据实际网卡名称修改(通过 ip a 查看)
  • virtual_router_id 51:虚拟路由器 ID,三台机器必须一致
  • priority 102:优先级最高,VIP 默认分配给此节点
  • auth_pass 1111:VRRP 认证密码,三台机器必须一致
  • virtual_ipaddress:虚拟 IP 地址

在 master-02 上配置

创建 /etc/keepalived/keepalived.conf 文件:

bash
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    interval 2
    weight 20
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 101
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.18.130.100/24
    }
    track_script {
        check_haproxy
    }
}

变更说明

  • state BACKUP:备份节点
  • priority 101:优先级次于 master-01

在 master-03 上配置

创建 /etc/keepalived/keepalived.conf 文件:

bash
! Configuration File for keepalived

global_defs {
   router_id LVS_DEVEL
}

vrrp_script check_haproxy {
    script "/etc/keepalived/check_haproxy.sh"
    user root
    interval 2
    weight 20
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.18.130.100/24
    }
    track_script {
        check_haproxy
    }
}

变更说明

  • state BACKUP:备份节点
  • priority 100:优先级最低

2.4 创建健康检查脚本

Keepalived 使用此脚本检查本机的 HAProxy 进程是否存活。若 HAProxy 故障,Keepalived 会自动降低优先级,触发 VIP 漂移。

在所有三台 Master 节点上创建脚本:

bash
sudo vim /etc/keepalived/check_haproxy.sh

脚本内容:

bash
#!/bin/bash
# /etc/keepalived/check_haproxy.sh

# 检查 haproxy 进程是否存在
if [ -z "$(pgrep haproxy)" ]; then
  # 如果不存在,返回 1 表示失败
  exit 1
fi

# 如果存在,返回 0 表示成功
exit 0

赋予执行权限:

bash
sudo chmod +x /etc/keepalived/check_haproxy.sh

2.5 允许非本地 IP 绑定

此内核参数允许 HAProxy 在 VIP 尚未漂移到本机时也能启动并监听该 IP 地址。当 VIP 漂移到本机时,HAProxy 可以立即接管流量。

在所有三台 Master 节点上执行:

bash
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee /etc/sysctl.d/99-haproxy.conf
sudo sysctl -p /etc/sysctl.d/99-haproxy.conf

2.6 启动服务并设置开机自启

在所有三台 Master 节点上执行:

bash
sudo systemctl enable --now keepalived
sudo systemctl enable --now haproxy

2.7 验证高可用配置

检查 VIP 是否生效

在 master-01 上执行:

bash
ip a | grep 172.18.130.100

预期结果:VIP 应绑定在 master-01 的网卡上。

测试 VIP 漂移

模拟 master-01 故障:

bash
# 在 master-01 上停止 keepalived
sudo systemctl stop keepalived

检查 VIP 是否漂移到 master-02:

bash
# 在 master-02 上执行
ip a | grep 172.18.130.100

预期结果:VIP 应已漂移到 master-02。

从其他机器 ping VIP,应仍然可达:

bash
ping 172.18.130.100

恢复 master-01:

bash
# 在 master-01 上重新启动 keepalived
sudo systemctl start keepalived

# 检查 VIP 是否漂移回 master-01
ip a | grep 172.18.130.100

由于 master-01 优先级更高,VIP 应自动漂移回 master-01。

第三步:初始化 Kubernetes 集群

3.1 在 master-01 上初始化集群

在 master-01 节点执行以下命令初始化 Kubernetes 控制平面:

bash
sudo kubeadm init \
  --pod-network-cidr=192.168.0.0/16 \
  --apiserver-advertise-address=172.18.130.1 \
  --control-plane-endpoint "172.18.130.100:6443" \
  --upload-certs \
  --image-repository registry.aliyuncs.com/google_containers

参数说明

  • --pod-network-cidr=192.168.0.0/16:Pod 网络 CIDR 范围(与后续安装的 CNI 插件配置一致)
  • --apiserver-advertise-address=172.18.130.1:本节点 API Server 监听的 IP 地址
  • --control-plane-endpoint "172.18.130.100:6443":高可用集群的入口地址(VIP)
  • --upload-certs:将证书上传到集群,便于其他 Master 节点加入
  • --image-repository registry.aliyuncs.com/google_containers:使用阿里云镜像仓库加速镜像拉取(双重保险)

说明:虽然已配置 Containerd 镜像加速,但仍通过 --image-repository 指定阿里云镜像站,确保初始化过程中的镜像拉取成功。

3.2 配置 kubectl

初始化完成后,配置 kubectl 以便管理集群:

bash
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

3.3 加入其他 Master 和 Worker 节点

kubeadm init 命令执行成功后,会输出两条 kubeadm join 命令:

  1. 用于加入 Master 节点(包含 --control-plane--certificate-key 参数)
  2. 用于加入 Worker 节点(仅包含基本的 join 参数)

重要提示

  • Token 有效期:默认 24 小时
  • Certificate Key 有效期:默认 2 小时
  • 过期后需重新生成,请尽快执行加入操作

加入其他 Master 节点

在 master-02 和 master-03 上执行包含 --control-plane 的 join 命令:

bash
kubeadm join 172.18.130.100:6443 --token ttwyi5.es71wltm2ewrjlq3 \
    --discovery-token-ca-cert-hash sha256:e0fea29accbe058dae41ae45b40c194530bc9b157eaf528eb42860fe0b688af3 \
    --control-plane --certificate-key 1723798321cb48a063e785b4cd61f06d1838b681e3652bea919456881048a864

说明

  • --control-plane:表明加入的是控制平面节点
  • --certificate-key:用于下载加密的证书文件

在 master-03 上执行相同的命令。

验证 Master 节点加入

在 master-01 上执行:

bash
kubectl get nodes

预期结果:应显示 3 个 Master 节点,状态为 NotReady(因为尚未安装 CNI 网络插件)。

加入 Worker 节点

在 node-04 和 node-05 上执行不包含 --control-plane 的 join 命令:

bash
kubeadm join 172.18.130.100:6443 --token ttwyi5.es71wltm2ewrjlq3 \
    --discovery-token-ca-cert-hash sha256:e0fea29accbe058dae41ae45b40c194530bc9b157eaf528eb42860fe0b688af3

验证所有节点加入

bash
kubectl get nodes

预期结果:应显示 5 个节点(3 Master + 2 Worker),状态均为 NotReady

第四步:安装 CNI 网络插件

Kubernetes 集群需要 CNI 网络插件来实现 Pod 间的网络通信。常用的 CNI 插件包括 Calico、Flannel、Cilium 等。

安装 Calico(推荐)

bash
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

若无法访问官方地址,可使用国内镜像站:

bash
kubectl apply -f https://files.m.daocloud.io/github.com/projectcalico/calico/releases/latest/calico.yaml

验证网络插件安装

等待所有 Calico Pod 运行:

bash
kubectl get pods -n kube-system -w

所有 Pod 状态变为 Running 后,检查节点状态:

bash
kubectl get nodes

预期结果:所有节点状态变为 Ready

第五步:验证集群状态

检查节点状态

bash
kubectl get nodes -o wide

预期输出示例:

NAME        STATUS   ROLES           AGE     VERSION
master-01   Ready    control-plane   15m     v1.34.0
master-02   Ready    control-plane   12m     v1.34.0
master-03   Ready    control-plane   12m     v1.34.0
node-04     Ready    <none>          10m     v1.34.0
node-05     Ready    <none>          10m     v1.34.0

检查系统组件

bash
kubectl get pods -n kube-system

所有 Pod 状态应为 Running

验证高可用性

通过 VIP 访问集群:

bash
kubectl --kubeconfig=<(kubectl config view --flatten) --server=https://172.18.130.100:6443 get nodes

总结

至此,一个生产级的内网 Kubernetes 高可用集群已部署完成,具备以下特性:

  • 高可用性:3 Master 节点 + Keepalived + HAProxy,实现控制平面的高可用
  • 负载均衡:HAProxy 自动将 API Server 请求分发到健康的 Master 节点
  • 故障自愈:Keepalived 自动检测节点健康状态,VIP 自动漂移到健康节点
  • 镜像加速:配置国内镜像站,加速镜像拉取
  • 网络互通:安装 Calico CNI 插件,实现 Pod 间通信

后续可根据业务需求安装 Ingress Controller、存储插件、监控系统等组件。

用心记录,持续学习 | CNB