Kubernetes v1.28.2 离线部署实战
本篇覆盖单机/多节点、IPv4/双栈/纯 IPv6 三种网络模式,所有步骤均经过实战验证,可直接复制执行。
目录
1. 前置准备
环境要求
| 项目 | 最低要求 | 推荐配置 |
|---|---|---|
| OS | CentOS 7.9 / Rocky 8+ | Rocky 9 |
| CPU | 2 核 | 4 核+ |
| 内存 | 2 GB | 8 GB+ |
| 磁盘 | 20 GB | 50 GB+ SSD |
节点规划
10.0.0.1 k8s-master (Master)
10.0.0.2 k8s-worker-2 (Worker)
10.0.0.3 k8s-worker-3 (Worker)
10.0.0.4 k8s-worker-4 (Worker)
...
📌 Tips:如果你是学习或测试,单节点就够了。生产环境建议至少 3 个 Master 节点实现高可用。关于多 Master 部署,可以参考 K8s 官方文档 - Creating Highly Available Clusters。
2. 系统初始化
注意:这一步每台机器都要执行。
2.1 关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
K8s 自带安全策略(NetworkPolicy、RBAC),生产环境用这些替代防火墙,不要同时开两层互相打架。详见 K8s Network Policies。
2.2 设置主机名 & Hosts
hostnamectl set-hostname os-57
cat >> /etc/hosts <<EOF
10.0.0.1 k8s-master
10.0.0.2 k8s-worker-2
10.0.0.3 k8s-worker-3
10.0.0.4 k8s-worker-4
EOF
2.3 关闭 SELinux
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
SELinux 和 K8s 的 Pod 安全上下文容易冲突,官方 kubeadm 安装文档也建议临时关闭。参考
2.4 关闭 Swap
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
为什么必须关? K8s 设计假设 Pod 随时可能被驱逐和重建,Swap 会导致内存回收行为不可预测,影响调度决策。官方说明
2.5 内核参数 & 模块
# 内核参数
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
# 加载内核模块
modprobe br_netfilter
modprobe ipv6
验证一下:
sysctl net.ipv4.ip_forward
# 输出: net.ipv4.ip_forward = 1
lsmod | grep br_netfilter
# 应有输出
2.6 配置 IPVS
IPVS 比 iptables 性能好很多,尤其在大规模集群下。K8s 官方服务代理对比
yum install ipvsadm ipset sysstat conntrack libseccomp -y
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
全部准备就绪后,重启一次:
reboot now
3. 安装 Containerd
K8s 1.24+ 已经移除了 Docker-shim,Containerd 是当前主流选择。
3.1 安装
# 配置 Docker CE 源(用于安装 containerd)
wget -O /etc/yum.repos.d/docker-ce.repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum install -y containerd.io
3.2 配置
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
必须修改两个关键配置:
① 启用 SystemdCgroup(K8s 官方推荐)
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
为什么要用 SystemdCgroup?因为 kubelet 默认使用 systemd 作为 cgroup driver,两者不一致会导致 Pod 创建失败。官方文档
② 替换 Pause 镜像为国内源
sed -i 's#sandbox_image = "registry.k8s.io/pause:3.6"#sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.9"#' /etc/containerd/config.toml
3.3 启动 & 验证
sudo systemctl enable --now containerd
sudo systemctl status containerd
#查看版本
ctr version
#输出如下表示成功:
Client:
Version: 1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
Go version: go1.21.10
Server:
Version: 1.6.32
Revision: 8b3b7ca2e5ce38e8f31a34f35b2b68ceb8470d89
UUID: 1ea4e608-7776-477b-b718-81ffab8222cb
3.4 配置 crictl
cat > /etc/crictl.yaml <<EOF
runtime-endpoint: unix:///run/containerd/containerd.sock
image-endpoint: unix:///run/containerd/containerd.sock
timeout: 5
debug: false
pull-image-on-create: false
EOF
crictl version
4. 安装 Kubernetes 组件
4.1 配置 yum 源
cat > /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
EOF
4.2 安装指定版本
sudo yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2
sudo systemctl enable --now kubelet
#查看运行状态
sudo systemctl status kubelet
💡 kubelet 启动后会不断重试连接 API Server,这是正常的,等
kubeadm init完成后就好了。
5. 初始化集群
以下操作只在 Master 节点执行。
5.1 选择网络模式
根据你的环境选择一种:
| 模式 | 命令 | 适用场景 |
|---|---|---|
| 纯 IPv4 | --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 |
大多数内网环境 |
| 双栈 (IPv4+IPv6) | --pod-network-cidr=10.244.0.0/16,2001:10:244::/64 |
需要兼容两种协议 |
| 纯 IPv6 | --pod-network-cidr=2002:10:233::/64 --apiserver-advertise-address <你的IPv6> |
纯 IPv6 环境 |
5.2 执行初始化
纯 IPv4 示例:
sudo kubeadm init \
--v=5 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \
--image-repository registry.aliyuncs.com/google_containers
双栈示例:
sudo kubeadm init \
--v=5 \
--pod-network-cidr=10.244.0.0/16,2001:10:244::/64 \
--service-cidr=10.96.0.0/12,2001:10:244:1000::/112 \
--image-repository registry.aliyuncs.com/google_containers
--image-repository指向阿里云镜像,离线环境需要提前拉取所有镜像。详见官方离线安装说明。
5.3 配置 kubectl
初始化成功后,复制最后输出的 join 命令保存好,然后执行:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5.4 Worker 加入集群
在每台 Worker 节点上执行 kubeadm init 输出的命,注意这里的token和ca都是上面master执行 kubeadm init成功以后屏幕打印的数据(下列只是例子,不要完全复制)。
kubeadm join 10.0.0.1:6443 \
--token rijgg6.j4oq3rp1evjsg6z4 \
--discovery-token-ca-cert-hash sha256:e15747ff3267a2db0ca861d906124d124cffe5a353002ed98460e13308570062
如果 token 过期了,在 Master 上执行
kubeadm token create --print-join-command重新生成。
6. 安装 Calico CNI
集群初始化后节点会显示 NotReady,因为还没装网络插件。
6.1 离线安装(只需要在主上执行即可)
# 下载离线包(在有网络的机器上)
wget https://github.com/projectcalico/calico/releases/download/v3.27.3/release-v3.27.3.tgz
tar -xzvf release-v3.27.3.tgz
# 导入镜像到所有节点
ctr -n k8s.io images import release-v3.27.3/images/calico-cni.tar
ctr -n k8s.io images import release-v3.27.3/images/calico-kube-controllers.tar
ctr -n k8s.io images import release-v3.27.3/images/calico-node.tar
6.2 修改 calico.yaml
编辑 release-v3.27.3/manifests/calico.yaml,需要改两处:
① IPAM 配置 — 增加双栈支持(纯 IPv4 可跳过 assign_ipv6),注意:这里的格式是json,最后一个字段是没有逗号的,否则报错都知哪里出问题:
"ipam": {
"type": "calico-ipam",
"assign_ipv4": "true",
"assign_ipv6": "true"
},
② 环境变量:
- name: IP
value: "autodetect"
- name: IP6
value: "autodetect"
- name: CALICO_IPV4POOL_IPIP
value: "Always"
- name: CALICO_IPV6POOL_NAT_OUTGOING
value: "true"
- name: FELIX_IPV6SUPPORT
value: "true"
IP设为autodetect让 Calico 自动发现网卡。如果机器有多张网卡,需要指定具体网卡名或 IP,参考 Calico 官方文档 - IP Autodetection。
6.3 部署
kubectl apply -f calico.yaml
# 观察部署进度
kubectl get pod -n kube-system -w
#如果报错了,修改calico.yaml文件以后需要删除以后再安装
kubectl delete -f calico.yaml
kubectl apply -f calico.yaml
等所有 Pod 变成 Running 后检查节点状态:
kubectl get nodes
# 应该显示 Ready
💡 关于 CNI 插件的选择:Calico 适合通用场景,支持 NetworkPolicy;如果需要高并发短连接可以看看 Cilium,它基于 eBPF 性能更好。CNI 插件对比
7. 验证与测试
7.1 Pod 连通性测试
# 导入测试镜像(需要先找一个有docker环境pull镜像然后save生成tar.gz镜像文件)
ctr -n k8s.io images import busybox-v1.36.tar.gz
# 启动两个测试 Pod
kubectl run pod01 --image=busybox:1.36 --command -- sleep 10000
kubectl run pod02 --image=busybox:1.36 --command -- sleep 10000
# 进入 Pod 互 ping
kubectl exec -it pod01 -- ping <pod02的IP>
7.2 Service 测试
kubectl create deployment nginx --image=nginx:1.19
kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx --type=NodePort
kubectl get svc
curl <nginx CLUSTER-IP>
8. 生产加固
8.1 单节点也跑工作负载(选配)
默认 Master 不调度 Pod(只跑控制面),单节点部署需要移除污点:
# k8s 1.24以后
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
# k8s 1.24以前
kubectl taint nodes --all node-role.kubernetes.io/master-
生产多节点环境不要这样做,Master 节点应该专注于控制面。参考
8.2 开启 IPVS
kubectl edit configmap kube-proxy -n kube-system
# 找到 mode,改为:
mode: "ipvs"
iptables.masqueradeAll: true
# 重启 kube-proxy Pod 使配置生效
kubectl delete pod --all -n kube-system -l k8s-app=kube-proxy
验证:
kubectl logs -n kube-system <kube-proxy-pod> | grep "Using ipvs Proxier"
9. 常见问题
Q: kubeadm init 失败怎么办?
kubeadm reset # 清理状态
# 修正问题后重新 init
Q: Calico Pod 一直 CrashLoopBackOff?
# 查看日志定位
kubectl logs -n kube-system <calico-node-pod-name>
# 常见原因:
# 1. 双栈参数没配对 → 检查 calico.yaml 中的 IPAM 和环境变量
# 2. 镜像版本不匹配 → crictl images 确认镜像已导入
# 3. 网卡自动检测选错了 → 手动指定 IP_AUTODETECTION_METHOD
Q: 节点 NotReady?
# 检查 kubelet 状态
systemctl status kubelet
journalctl -u kubelet -f
# 常见原因:
# 1. CNI 未安装或安装失败
# 2. 容器运行时异常 → systemctl status containerd
# 3. 内核模块未加载 → lsmod | grep br_netfilter
Q: Token 过期了怎么加节点?
kubeadm token create --print-join-command
🔗 官方文档延伸阅读
| 主题 | 链接 |
|---|---|
| kubeadm 安装指南 | https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ |
| 容器运行时配置 | https://kubernetes.io/docs/setup/production-environment/container-runtimes/ |
| 创建高可用集群 | https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/high-availability/ |
| CNI 网络插件列表 | https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/ |
| Network Policy | https://kubernetes.io/docs/concepts/services-networking/network-policies/ |
| RBAC 最佳实践 | https://kubernetes.io/docs/concepts/security/rbac-good-practices/ |
| kube-proxy IPVS 模式 | https://kubernetes.io/docs/reference/networking/virtual-ips/ |
总结:整个流程就是 系统初始化 → 装运行时 → 装 K8s → 初始化集群 → 装 CNI → 验证。离线环境的关键在于提前准备好所有镜像(containerd + kubeadm 所需 + Calico),然后按步骤执行即可。遇到问题别慌,
journalctl -u kubelet -f和kubectl logs是你的好朋友。