写在前面
在 Kubernetes 1.6(2017 年)之前,社区主流的"高可用生产集群"基本是 3 master + N worker 手工二进制部署路线——比起 kubeadmin/kubeadm,手工二进制能完全掌控每个组件的 flag、证书路径和 systemd 单元,是国内大厂 2018-2022 年生产环境的标配方案。
本文是整个 K8s 二进制部署系列的前置篇,只讲集群起步:网络规划、服务器角色划分、Ubuntu 22.04 系统基础优化、IPVS/iptables 内核参数准备。不涉及任何 K8s 组件安装。
适用版本:Kubernetes 1.28.5 / etcd 3.5.11 / Ubuntu 22.04 server
集群规模:3 master(etcd + controlplane + nginx/keepalived)+ 10 worker
1. 集群网络与节点规划
1.1 角色划分
| 角色 | 数量 | 部署组件 |
|---|
| master | 3 | etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy、nginx、keepalived |
| worker | N | kubelet、kube-proxy、容器运行时 |
| VIP | 2 | 一个内网用,一个公网用,keepalived 漂移 |
1.2 IP 与 VIP 段(示例拓扑)
| 网段 | 用途 | 说明 |
|---|
<node-network> | 节点操作系统网段 | 物理网络,所有节点 IP 都在此 |
10.96.0.0/12 | Service 网段 | kube-apiserver 默认 --service-cluster-ip-range |
10.96.0.10 | CoreDNS Service IP | kube-dns 固定 IP |
172.218.0.0/12 | Pod 网络 | kube-controller-manager 的 --cluster-cidr |
<vip-internal> | 内网 VIP | 漂移在 master1 / master2 |
<vip-public> | 公网映射 VIP | 漂移在 master1 / master2 |
Service 段、Pod 段在生产中可以按需调整,前提是所有节点路由可达。
1.3 NodePort 端口范围
K8s 默认 Service NodePort 范围是 30000-32767,如果需要在前面用 Nginx 4 层反代 NodePort,必须在 kube-apiserver 启动参数里显式声明:
1
| --service-node-port-range=30000-32767
|
修改 /etc/systemd/system/kube-apiserver.service 后:
1
2
| systemctl daemon-reload
systemctl restart kube-apiserver.service
|
1.4 主机名与 hosts
1
2
3
4
| # 三个 master 设置 hostname
hostnamectl set-hostname master1 # 内网示例:<node-ip> 节点
hostnamectl set-hostname master2
hostnamectl set-hostname master3
|
所有节点配置 /etc/hosts(内网 IP 替换为实际值):
1
2
3
4
5
6
7
| cat << "EOF" >> /etc/hosts
<node-ip> master1
<node-ip> master2
<node-ip> master3
<node-ip> worker1
<node-ip> worker2
EOF
|
注意:内网 IP 已用占位符 <node-ip> 替代;实际操作时换成你集群的真实 IP。
2. 安装文件清单
在 master1 上准备好所有需要分发的二进制包(典型命名):
| 文件 | 用途 |
|---|
docker-24.0.7.tgz | Docker 静态二进制包 |
cri-dockerd-0.3.9.amd64.tgz | cri-dockerd(K8s 1.24+ 不再内置 dockershim) |
nginx-1.24.0.tar.gz | nginx 源码(编译 --with-stream) |
keepalived-2.2.8.tar.gz | keepalived 源码 |
etcd-v3.5.11-linux-amd64.tar.gz | etcd 二进制 |
kubernetes-server-linux-amd64.tar.gz | K8s 1.28.5 服务端二进制 |
cfssl_1.6.4_linux_amd64 | 证书签发工具 |
cfssljson_1.6.4_linux_amd64 | 证书 JSON 化工具 |
cfssl-certinfo_1.6.4_linux_amd64 | 证书查看工具 |
helm-v3.13.3-linux-amd64.tar.gz | Helm 包管理 |
coredns-1.29.0.tgz | CoreDNS chart(DNS 插件) |
3. 目录约定
每台机器统一下列目录结构,方便后面所有组件统一路径:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| # 系统服务目录
mkdir -p /etc/systemd/system
# 二进制目录
mkdir -p /usr/local/bin
# 所有节点安装包路径
mkdir -p /data/softs
# 所有节点 k8s 配置目录
mkdir -p /data/k8scnf
# 所有节点的 k8s 证书目录
mkdir -p /etc/kubernetes/pki
# 所有节点 k8s 运行目录
mkdir -p /etc/kubernetes/manifests/
mkdir -p /etc/systemd/system/kubelet.service.d
mkdir -p /var/lib/kubelet
mkdir -p /var/log/kubernetes
# 所有节点 docker 配置目录
mkdir -p /etc/docker
# 所有 master etcd 证书目录
mkdir -p /etc/etcd/ssl
# master1, master2 的 nginx 目录
mkdir -p /usr/local/nginx/conf/{conf.d,stream}
mkdir -p /usr/local/keepalived/conf
|
4. 节点免密登录(master1 推送前置)
master1 上一键推送 SSH 公钥到其他节点(密码用占位符):
1
2
3
4
5
6
| apt install -y sshpass
ssh-keygen -f /root/.ssh/id_rsa -P ''
for HOST in master2 master3 worker1 worker2 worker3 worker4 worker5 worker6 worker7 worker8 worker9; do \
sshpass -p "{{SSH_PASSWORD}}" ssh-copy-id -o StrictHostKeyChecking=no $HOST; \
done
|
非 22 端口的节点:
1
| ssh-copy-id -i ~/.ssh/id_rsa.pub "-p 10022 user@server"
|
文件批量推送到其他 master:
1
| for HOST in master2 master3; do scp -r /data/softs $HOST:/data; done
|
5. Ubuntu 22.04 源切换
为了避免 apt install 卡顿,所有节点切到清华源(或其他国内源):
1
2
3
4
5
6
7
8
9
10
| mv /etc/apt/sources.list /etc/apt/sources.listbak
cat > /etc/apt/sources.list << "EOF"
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
EOF
apt update
|
6. 系统基础优化
6.1 禁用 swap
K8s 1.20+ 仍要求关闭 swap(kubelet 默认 failSwapOn: true):
1
2
3
4
| free -m
swapoff -a
sed -ri 's/.*swap.*/#&/' /etc/fstab
cat /etc/fstab
|
6.2 关闭防火墙
1
2
3
| sudo systemctl stop ufw
sudo systemctl disable ufw
systemctl status ufw # 状态应为 inactive (dead)
|
6.3 关闭 systemd-resolved(关键)
Ubuntu 22.04 默认的 systemd-resolved 占用 53 端口,导致 CoreDNS 装不上:
1
2
3
4
5
| sudo apt install -y unbound
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo rm -rf /etc/resolv.conf
sudo touch /etc/resolv.conf
|
6.4 时间同步
1
2
3
4
5
6
7
8
9
| timedatectl status # System clock synchronized 必须是 yes
timedatectl set-timezone Asia/Shanghai
apt install -y ntpdate
ntpdate time1.aliyun.com
# 定时同步
crontab -e
*/5 * * * * ntpdate time1.aliyun.com
crontab -l
|
常见报错:Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend
解决:用 lsof /var/lib/dpkg/lock-frontend 查到占用 PID 后 kill -9 杀掉。
6.5 ulimit 与文件描述符
1
2
3
4
5
6
7
8
9
10
| ulimit -SHn 65535
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
|
6.6 内核升级
K8s 1.28 要求内核 ≥ 4.18,Ubuntu 22.04 默认 5.15 满足,无需额外升级。
1
2
| uname -r
# 5.15.0-91-generic 满足
|
7. IPVS 与内核网络参数
K8s kube-proxy 的 IPVS 模式比 iptables 模式在大规模集群下性能更好:
7.1 安装 IPVS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apt install -y ipvsadm ipset sysstat conntrack
cat >> /etc/modules-load.d/ipvs.conf << "EOF"
ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack
ip_tables
ip_set
xt_set
ipt_set
ipt_rpfilter
ipt_REJECT
ipip
EOF
systemctl restart systemd-modules-load.service
lsmod | grep -e ip_vs -e nf_conntrack
|
7.2 sysctl 优化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| cat << "EOF" > /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 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
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.ipv4.tcp_timestamps = 0
net.core.somaxconn = 16384
EOF
sysctl --system
|
8. 排错速查
| 现象 | 原因 | 解决 |
|---|
apt 卡 dpkg lock-frontend | 后台 unattended-upgrade 占用 | lsof /var/lib/dpkg/lock-frontend → kill -9 PID |
CoreDNS Pod 一直 CrashLoopBackOff | systemd-resolved 占用 53 | 关闭 systemd-resolved,见 6.3 |
kubelet 启动失败 failSwapOn | swap 未关 | swapoff -a + /etc/fstab 注释 |
| NodePort 配 80 端口启动失败 | 不在 30000-32767 范围 | kube-apiserver 加 --service-node-port-range |
节点 NotReady | 路由转发未开 | net.ipv4.ip_forward = 1 |
9. 小结
集群前置看似都是"复制粘贴"的体力活,但每一步都是后面所有组件能起来的前提。最容易踩的坑是:
systemd-resolved 没关 → CoreDNS 起不来swap 没禁 → kubelet 直接 failSwapOn 拒绝启动- 防火墙没关 → 跨节点 Service 不通
- 时间不同步 → 证书签名失败、etcd 集群脑裂
下一步:容器运行时:Docker + cri-dockerd 二进制部署实战。
前置知识 / 下一步
- 前置:了解 Linux 基础(systemd、apt、sysctl)
- 本篇:所有 master/worker 节点一致的系统基线
- 下一步:在所有节点上部署容器运行时(Docker 24 + cri-dockerd)