内网 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 的调度和资源限制机制。
swapoff -a
vi /etc/fstab
# 删除或注释掉 swap 相关行1.2 配置国内软件源
由于网络环境限制,需要将 APT 源替换为清华大学镜像站以加速软件包下载。
编辑 /etc/apt/sources.list 文件,删除或注释原有内容,添加以下配置:
# 默认注释了源码镜像,如有需要可自行取消注释
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-firmware1.3 配置主机名解析
为集群节点配置主机名映射,避免依赖外部 DNS,提高集群内部通信的稳定性和响应速度。
将以下内容添加到 /etc/hosts 文件:
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-051.4 配置防火墙规则
Kubernetes 集群组件之间需要大量的网络通信,需要配置防火墙以允许必要的流量。
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 确保所有节点时间一致。
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 处理能力。
# 配置开机自动加载内核模块
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 仓库并安装核心组件。
更新软件包索引并安装依赖工具
sudo apt-get update
# apt-transport-https 可能是虚拟包,若已存在可跳过安装
sudo apt-get install -y apt-transport-https ca-certificates curl gpg下载 Kubernetes 软件包仓库的公共签名密钥
所有版本的 Kubernetes 仓库使用相同的签名密钥。
# 如果 /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 中的版本号。
# 此操作会覆盖 /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 核心组件和容器运行时
# 更新软件包列表
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
# 创建配置目录
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.io | docker.m.daocloud.io | Docker Hub |
| gcr.io | gcr.m.daocloud.io | Google Container Registry |
| ghcr.io | ghcr.m.daocloud.io | GitHub Container Registry |
| registry.k8s.io | k8s.m.daocloud.io | Kubernetes 官方镜像 |
| k8s.gcr.io | k8s-gcr.m.daocloud.io | Kubernetes 旧镜像地址 |
| quay.io | quay.m.daocloud.io | Red Hat Quay 仓库 |
| mcr.microsoft.com | mcr.m.daocloud.io | Microsoft Container Registry |
| nvcr.io | nvcr.m.daocloud.io | NVIDIA Container Registry |
创建镜像仓库配置目录:
sudo mkdir -p /etc/containerd/certs.d为各个镜像仓库创建配置文件:
Docker Hub (docker.io):
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"]
EOFgcr.io:
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"]
EOFghcr.io:
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"]
EOFregistry.k8s.io:
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"]
EOFk8s.gcr.io(旧地址):
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"]
EOFquay.io:
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"]
EOFmcr.microsoft.com:
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"]
EOFnvcr.io:
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 目录:
vim /etc/containerd/config.toml确认以下配置存在(已在步骤 1 中配置):
version = 2
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"步骤 4:重启 Containerd 服务
sudo systemctl restart containerd
sudo systemctl status containerd步骤 5:验证配置
# 查看配置目录是否创建成功
ls -la /etc/containerd/certs.d/
# 测试拉取镜像
sudo crictl pull registry.k8s.io/pause:3.9
sudo crictl pull docker.io/library/nginxcerts.d 方式的优势:
- 模块化管理:每个镜像仓库独立配置,便于维护
- 易于更新:修改单个仓库配置无需重启整个服务
- 支持多个镜像源:可为同一仓库配置多个加速地址
- 优先级控制:配置文件中的顺序决定尝试顺序
第二步:Master 节点高可用配置
以下操作需要在所有 Master 节点(master-01、master-02、master-03)上执行。
高可用架构通过 Keepalived + HAProxy 实现:
- Keepalived:实现虚拟 IP(VIP)的漂移,确保 VIP 始终指向健康的 Master 节点
- HAProxy:作为 API Server 的负载均衡器,将请求分发到所有健康的 Master 节点
2.1 安装 Keepalived 和 HAProxy
sudo apt-get update
sudo apt-get install -y keepalived haproxy2.2 配置 HAProxy
HAProxy 负责接收来自 VIP 的请求,并将其负载均衡到三个 Master 节点的 API Server。
备份原始配置文件
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bak创建新的 HAProxy 配置
编辑 /etc/haproxy/haproxy.cfg,添加以下内容:
#---------------------------------------------------------------------
# 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 节点的配置略有不同,主要体现在 state 和 priority 参数上。
在 master-01 上配置(最高优先级)
创建 /etc/keepalived/keepalived.conf 文件:
! 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 文件:
! 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 文件:
! 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 节点上创建脚本:
sudo vim /etc/keepalived/check_haproxy.sh脚本内容:
#!/bin/bash
# /etc/keepalived/check_haproxy.sh
# 检查 haproxy 进程是否存在
if [ -z "$(pgrep haproxy)" ]; then
# 如果不存在,返回 1 表示失败
exit 1
fi
# 如果存在,返回 0 表示成功
exit 0赋予执行权限:
sudo chmod +x /etc/keepalived/check_haproxy.sh2.5 允许非本地 IP 绑定
此内核参数允许 HAProxy 在 VIP 尚未漂移到本机时也能启动并监听该 IP 地址。当 VIP 漂移到本机时,HAProxy 可以立即接管流量。
在所有三台 Master 节点上执行:
echo "net.ipv4.ip_nonlocal_bind = 1" | sudo tee /etc/sysctl.d/99-haproxy.conf
sudo sysctl -p /etc/sysctl.d/99-haproxy.conf2.6 启动服务并设置开机自启
在所有三台 Master 节点上执行:
sudo systemctl enable --now keepalived
sudo systemctl enable --now haproxy2.7 验证高可用配置
检查 VIP 是否生效
在 master-01 上执行:
ip a | grep 172.18.130.100预期结果:VIP 应绑定在 master-01 的网卡上。
测试 VIP 漂移
模拟 master-01 故障:
# 在 master-01 上停止 keepalived
sudo systemctl stop keepalived检查 VIP 是否漂移到 master-02:
# 在 master-02 上执行
ip a | grep 172.18.130.100预期结果:VIP 应已漂移到 master-02。
从其他机器 ping VIP,应仍然可达:
ping 172.18.130.100恢复 master-01:
# 在 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 控制平面:
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 以便管理集群:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config3.3 加入其他 Master 和 Worker 节点
kubeadm init 命令执行成功后,会输出两条 kubeadm join 命令:
- 用于加入 Master 节点(包含
--control-plane和--certificate-key参数) - 用于加入 Worker 节点(仅包含基本的 join 参数)
重要提示
- Token 有效期:默认 24 小时
- Certificate Key 有效期:默认 2 小时
- 过期后需重新生成,请尽快执行加入操作
加入其他 Master 节点
在 master-02 和 master-03 上执行包含 --control-plane 的 join 命令:
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 上执行:
kubectl get nodes预期结果:应显示 3 个 Master 节点,状态为 NotReady(因为尚未安装 CNI 网络插件)。
加入 Worker 节点
在 node-04 和 node-05 上执行不包含 --control-plane 的 join 命令:
kubeadm join 172.18.130.100:6443 --token ttwyi5.es71wltm2ewrjlq3 \
--discovery-token-ca-cert-hash sha256:e0fea29accbe058dae41ae45b40c194530bc9b157eaf528eb42860fe0b688af3验证所有节点加入
kubectl get nodes预期结果:应显示 5 个节点(3 Master + 2 Worker),状态均为 NotReady。
第四步:安装 CNI 网络插件
Kubernetes 集群需要 CNI 网络插件来实现 Pod 间的网络通信。常用的 CNI 插件包括 Calico、Flannel、Cilium 等。
安装 Calico(推荐)
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml若无法访问官方地址,可使用国内镜像站:
kubectl apply -f https://files.m.daocloud.io/github.com/projectcalico/calico/releases/latest/calico.yaml验证网络插件安装
等待所有 Calico Pod 运行:
kubectl get pods -n kube-system -w所有 Pod 状态变为 Running 后,检查节点状态:
kubectl get nodes预期结果:所有节点状态变为 Ready。
第五步:验证集群状态
检查节点状态
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检查系统组件
kubectl get pods -n kube-system所有 Pod 状态应为 Running。
验证高可用性
通过 VIP 访问集群:
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、存储插件、监控系统等组件。