从零搭建 K8s 测试环境:详细教程(基于 kubeadm)
本文详细介绍了使用kubeadm工具在CentOS7系统上搭建单Master节点Kubernetes测试环境的完整流程。主要内容包括:环境准备(硬件要求、系统配置)、基础环境设置(关闭防火墙/SELinux/Swap、内核参数调整)、容器运行时containerd安装、K8s工具集部署、Master节点初始化、Calico网络插件配置、Worker节点加入,以及集群功能测试和日常运维操作。教程针对
从零搭建 K8s 测试环境:详细教程(基于 kubeadm)
在日常开发、测试或学习 Kubernetes(简称 K8s)时,搭建一套轻量、稳定的测试环境是基础需求。本文将以CentOS 7.x系统为例,采用官方推荐的kubeadm工具,带您从零构建单 Master 节点的 K8s 测试环境,步骤清晰可复现,新手也能轻松上手。
一、环境准备:明确前提与规划
在开始部署前,需确认硬件、系统、网络等基础条件满足要求,避免后续出现兼容性问题。
1.1 硬件要求(测试环境最低配置)
K8s 对硬件资源有基础要求,测试环境无需高性能,但需满足以下底线:
- CPU:至少 2 核(Master 节点需稳定运行控制平面组件,1 核可能出现资源不足)
- 内存:至少 2GB(Master 节点建议 4GB,避免因内存不足导致组件崩溃)
- 硬盘:至少 20GB(需存储系统、容器镜像、K8s 组件日志等,推荐 SSD 提升镜像拉取速度)
- 网络:所有节点(Master+Worker)需处于同一局域网,且能访问互联网(拉取镜像和依赖)
1.2 系统与软件要求
- 操作系统:CentOS 7.x(64 位,推荐 7.9 版本,兼容性最佳);也可使用 Ubuntu 20.04 LTS,步骤类似
- 内核版本:至少 3.10(CentOS 7 默认内核满足,但建议升级到 4.19 + 以优化容器性能,下文附升级方法)
- 依赖工具:
docker或containerd(容器运行时,本文以containerd为例,更轻量且是 K8s 默认推荐) - 关闭冲突服务:需关闭防火墙、SELinux、Swap(K8s 要求禁用 Swap,避免影响容器内存管理)
1.3 节点规划(单 Master 架构)
测试环境推荐 “1 个 Master 节点 + 1 个 Worker 节点” 的架构,节点信息示例如下:
| 节点角色 | 主机名 | IP 地址 | 系统版本 |
|---|---|---|---|
| Master | k8s-master | 192.168.1.100 | CentOS 7.9 |
| Worker | k8s-worker-1 | 192.168.1.101 | CentOS 7.9 |
提示:若仅用于学习,也可搭建 “单节点集群”(Master 节点同时作为 Worker),步骤一致,只需省略 Worker 节点的部署流程。
二、基础环境配置:所有节点执行(关键!)
注意:以下步骤需在所有节点(Master+Worker) 上执行,确保基础环境一致。
2.1 配置主机名与 Hosts 解析
为方便节点间通信(避免依赖 DNS),需设置主机名并添加 Hosts 映射。
-
设置主机名(Master 节点执行):
hostnamectl set-hostname k8s-masterWorker 节点执行(以 k8s-worker-1 为例):
hostnamectl set-hostname k8s-worker-1执行后可通过
hostname命令验证。 -
添加 Hosts 映射:编辑
/etc/hosts文件,添加所有节点的 IP 与主机名映射:vi /etc/hosts插入以下内容(需替换为您的实际 IP 和主机名):
192.168.1.100 k8s-master 192.168.1.101 k8s-worker-1保存退出(
:wq),执行ping k8s-master验证是否能通。
2.2 关闭防火墙与 SELinux
K8s 各组件间需通过特定端口通信,防火墙会拦截流量;SELinux 会限制容器权限,测试环境建议直接关闭。
-
关闭防火墙:
# 停止防火墙服务 systemctl stop firewalld # 禁止开机自启 systemctl disable firewalld # 验证状态(应显示inactive) systemctl status firewalld -
关闭 SELinux:
# 临时关闭(立即生效,重启后失效) setenforce 0 # 永久关闭(编辑配置文件,需重启生效) vi /etc/selinux/config将
SELINUX=enforcing改为SELINUX=disabled,保存退出。后续重启节点后,执行getenforce验证,应显示Disabled。
2.3 禁用 Swap 分区
K8s 要求禁用 Swap,避免容器内存被 Swap 置换,影响性能和稳定性。
-
临时禁用 Swap(立即生效):
swapoff -a -
永久禁用 Swap(编辑 fstab 文件,重启后生效):
vi /etc/fstab注释掉包含
swap的行(在行首加#),示例:# /dev/mapper/centos-swap swap swap defaults 0 0保存退出,后续重启节点后,执行
free -h验证,Swap 行应显示0。
2.4 配置内核参数(开启容器相关模块)
K8s 依赖 Linux 内核的特定模块(如br_netfilter),需手动加载并配置内核参数。
-
加载内核模块:创建模块配置文件:
vi /etc/modules-load.d/k8s.conf插入以下内容:
overlay br_netfilter保存退出后,执行以下命令加载模块:
modprobe overlay modprobe br_netfilter验证模块是否加载成功:
lsmod | grep -E "overlay|br_netfilter"若输出结果包含两个模块,说明加载成功。
-
配置内核参数:创建内核参数配置文件:
vi /etc/sysctl.d/k8s.conf插入以下内容(用于开启 IP 转发、桥接流量等):
net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1保存退出后,执行以下命令使参数生效:
sysctl --system验证参数是否生效:
sysctl -a | grep -E "net.bridge.bridge-nf-call-iptables|net.ipv4.ip_forward"若输出值均为
1,说明配置成功。
2.5 升级内核(可选但推荐)
CentOS 7 默认内核为 3.10,虽然能运行 K8s,但 4.19 + 内核对容器网络、存储的支持更优,建议升级。
-
安装 ELRepo 仓库(提供高版本内核):
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm -
安装 4.19 内核:
yum --enablerepo=elrepo-kernel install kernel-lt-4.19.276-1.el7.elrepo -y -
设置默认内核为 4.19:
# 查看内核启动顺序(0为默认) awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg # 假设4.19内核对应的序号是0,执行以下命令设置默认 grub2-set-default 0 # 生成新的grub配置 grub2-mkconfig -o /boot/grub2/grub.cfg -
重启节点:
reboot重启后执行
uname -r验证,应显示4.19.276-1.el7.elrepo.x86_64。
2.6 安装容器运行时(containerd)
K8s 从 1.24 版本开始不再默认依赖 Docker,而是推荐使用containerd作为容器运行时(更轻量、无 Docker 守护进程依赖)。
-
安装 containerd 依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加Docker仓库(containerd包含在Docker仓库中) yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo -
安装 containerd:
yum install -y containerd.io-1.6.28 # 选择稳定版本,避免最新版兼容性问题 -
配置 containerd(关键:设置 Cgroup 驱动为 systemd):K8s 推荐使用
systemd作为 Cgroup 驱动,需手动配置:# 生成默认配置文件 containerd config default > /etc/containerd/config.toml # 编辑配置文件,修改Cgroup驱动 vi /etc/containerd/config.toml找到以下内容,将
SystemdCgroup = false改为SystemdCgroup = true:[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true # 改为true保存退出后,重启 containerd 并设置开机自启:
systemctl restart containerd systemctl enable containerd # 验证状态(应显示active) systemctl status containerd
2.7 配置 K8s yum 仓库
添加 K8s 官方 yum 仓库,用于安装kubeadm、kubelet、kubectl(K8s 核心工具)。
-
创建仓库配置文件:
vi /etc/yum.repos.d/kubernetes.repo插入以下内容:
[kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl保存退出。
-
安装 K8s 工具集:为避免版本兼容性问题,建议指定稳定版本(本文以
1.28.2为例,可根据需求调整):yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 --disableexcludes=kubernetes -
设置 kubelet 开机自启:kubelet 是 K8s 节点上的核心组件,需确保开机启动:
systemctl enable kubelet # 此时kubelet未启动(需后续初始化Master后才会启动),状态为active (exited) 是正常的 systemctl status kubelet
三、初始化 Master 节点(仅 Master 执行)
Master 节点是 K8s 集群的控制平面,包含apiserver、etcd、controller-manager、scheduler等核心组件,需通过kubeadm init初始化。
3.1 拉取 K8s 镜像(关键:避免网络问题)
K8s 默认从k8s.gcr.io拉取镜像,但该地址在国内无法访问,需先通过kubeadm config images pull指定国内镜像源(如阿里云)。
执行以下命令拉取镜像(替换1.28.2为您安装的 K8s 版本):
kubeadm config images pull \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.2
若输出 “[config/images] Pulled registry.aliyuncs.com/google_containers/xxx”,说明镜像拉取成功。
3.2 初始化 Master 节点
执行kubeadm init命令,指定 Pod 网络网段(需与后续 Calico 网络插件一致,推荐10.244.0.0/16)和国内镜像源。
kubeadm init \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.28.2 \
--pod-network-cidr=10.244.0.0/16 \
--service-cidr=10.96.0.0/12 \ # 服务网段,默认即可
--ignore-preflight-errors=Swap # 若未禁用Swap(不推荐),可加此参数忽略错误
初始化成功的标志
若输出以下内容,说明 Master 初始化成功(请保存最后几行命令,用于 Worker 节点加入集群):
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
3.3 配置 kubectl(Master 节点)
kubectl是 K8s 的命令行工具,需配置权限才能操作集群(按初始化成功提示的命令执行)。
-
非 root 用户配置(推荐,如普通用户 test):
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config -
root 用户配置:
export KUBECONFIG=/etc/kubernetes/admin.conf # 若想永久生效,可添加到/etc/profile echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile source /etc/profile -
验证 Master 节点状态:执行以下命令,查看 Master 节点是否就绪:
kubectl get nodes此时输出应类似:
NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 5m v1.28.2状态为
NotReady是正常的,因为尚未部署网络插件。
3.4 部署网络插件(Calico)
K8s 集群必须部署网络插件才能实现 Pod 间通信,本文选择官方推荐的 Calico(轻量、稳定)。
执行以下命令部署 Calico(版本需与 K8s 版本兼容,此处为 v3.26.1):
kubectl apply -f https://docs.projectcalico.org/v3.26/manifests/calico.yaml
部署完成后,等待 3-5 分钟,执行以下命令验证:
- 查看 Calico Pod 状态(所有 Pod 应处于
Running状态):kubectl get pods -n kube-system | grep calico - 再次查看 Master 节点状态(应变为
Ready):
若输出kubectl get nodesSTATUS: Ready,说明 Master 节点初始化完成!
四、添加 Worker 节点(仅 Worker 执行)
Worker 节点是运行容器的节点,需通过kubeadm join命令加入 Master 集群(使用 Master 初始化时保存的join命令)。
4.1 执行 join 命令
在 Worker 节点上,以 root 用户执行 Master 初始化时输出的kubeadm join命令(示例如下,需替换为您自己的命令):
kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
常见问题:token 过期
若join命令中的 token 过期(默认 24 小时),可在 Master 节点上执行以下命令重新生成 token:
# 生成新token
kubeadm token create --print-join-command
执行后会输出新的kubeadm join命令,直接在 Worker 节点执行即可。
4.2 验证 Worker 节点加入状态
在 Master 节点上执行以下命令,查看 Worker 节点是否加入成功:
kubectl get nodes
若输出包含 Worker 节点且状态为Ready,说明加入成功,示例如下:
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 10m v1.28.2
k8s-worker-1 Ready <none> 2m v1.28.2
提示:Worker 节点角色显示
<none>是正常的,若需标记角色,可执行kubectl label node k8s-worker-1 node-role.kubernetes.io/worker=worker。
4.3 排查 Worker 节点 NotReady 问题
若 Worker 节点状态为NotReady,优先检查以下两点:
- Calico 网络插件是否部署成功:Worker 节点需拉取 Calico 镜像并启动 Pod,执行
kubectl get pods -n kube-system -o wide查看 Calico Pod 是否在 Worker 节点运行; - 节点间网络连通性:Master 节点的 6443 端口(apiserver)需能被 Worker 节点访问,执行
telnet 192.168.1.100 6443验证。
五、测试集群可用性:运行示例应用
集群搭建完成后,需验证核心功能是否正常,以nginx为例部署一个简单的 Deployment 和 Service。
5.1 部署 nginx Deployment
在 Master 节点执行以下命令,创建包含 2 个副本的 nginx Deployment:
kubectl create deployment nginx --image=nginx:1.24-alpine --replicas=2
5.2 暴露 nginx Service(NodePort 类型)
为了从集群外访问 nginx,创建 NodePort 类型的 Service:
kubectl expose deployment nginx --port=80 --type=NodePort --name=nginx-service
5.3 验证部署结果
-
查看 Pod 状态(所有 Pod 应处于
Running状态,且分布在 Worker 节点):kubectl get pods -o wide示例输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-7f979d879c-2x78z 1/1 Running 0 1m 10.244.1.2 k8s-worker-1 <none> <none> nginx-7f979d879c-8k57s 1/1 Running 0 1m 10.244.1.3 k8s-worker-1 <none> <none> -
查看 Service 信息(获取 NodePort 端口):
kubectl get svc nginx-service示例输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-service NodePort 10.96.123.45 <none> 80:30080/TCP 2m其中
30080是 NodePort 端口(随机分配,范围 30000-32767)。 -
访问 nginx 服务:在集群外的机器(如本地电脑),通过
Worker节点IP:NodePort访问,示例:curl http://192.168.1.101:30080若输出 nginx 的默认欢迎页面,说明集群功能正常!
六、集群日常运维(测试环境常用操作)
6.1 查看集群状态
# 查看节点信息
kubectl get nodes
# 查看所有命名空间的Pod
kubectl get pods -A
# 查看集群组件状态(kube-apiserver、etcd等)
kubectl get componentstatuses # 1.24+版本需用 kubectl get pods -n kube-system
# 查看集群版本
kubectl version --short
6.2 重启集群(节点重启后)
若节点重启,K8s 组件会自动启动(因 kubelet 已设置开机自启),只需验证节点状态:
kubectl get nodes
若状态为NotReady,等待 Calico Pod 重启完成即可(通常 1-2 分钟)。
6.3 重置集群(重新部署)
若需清理集群并重新部署,执行以下命令(谨慎操作,会删除所有集群数据):
# 所有节点执行:停止kubelet并清理容器
systemctl stop kubelet
containerd ctr containers rm -a
# Master节点执行重置
kubeadm reset -f
# Worker节点执行重置
kubeadm reset -f
# 清理网络规则(可选)
iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X
重置完成后,可重新执行 Master 初始化和 Worker 加入流程。
6.4 卸载 K8s(彻底清理)
若需完全卸载 K8s 和依赖组件:
# 重置集群
kubeadm reset -f
# 卸载kubelet、kubeadm、kubectl
yum remove -y kubelet kubeadm kubectl
# 卸载containerd
yum remove -y containerd.io
# 清理残留文件
rm -rf /etc/kubernetes /var/lib/etcd /var/lib/kubelet /etc/containerd
七、常见问题与解决方案
7.1 镜像拉取失败
- 原因:国内无法访问
k8s.gcr.io,或镜像版本不匹配。 - 解决方案:初始化时指定阿里云镜像源(
--image-repository registry.aliyuncs.com/google_containers),或手动拉取镜像并打标签:# 示例:拉取calico镜像 docker pull calico/node:v3.26.1 docker tag calico/node:v3.26.1 registry.aliyuncs.com/google_containers/calico-node:v3.26.1
7.2 kubelet 启动失败
- 原因:Swap 未禁用、Cgroup 驱动不匹配、内核参数未配置。
- 解决方案:
- 确认 Swap 已永久禁用(
free -h验证); - 确认 containerd 的 Cgroup 驱动为
systemd(查看/etc/containerd/config.toml); - 重新加载内核参数(
sysctl --system)。
- 确认 Swap 已永久禁用(
7.3 Calico Pod CrashLoopBackOff
- 原因:Pod 网络网段与主机网段冲突,或内核模块未加载。
- 解决方案:
- 检查
--pod-network-cidr是否为10.244.0.0/16(Calico 默认网段); - 确认
br_netfilter模块已加载(lsmod | grep br_netfilter)。
- 检查
7.4 Worker 节点无法加入集群
- 原因:token 过期、Master 6443 端口不通、节点主机名重复。
- 解决方案:
- 在 Master 节点重新生成 token(
kubeadm token create --print-join-command); - 验证 Worker 节点能 ping 通 Master,且 6443 端口未被防火墙拦截;
- 确保所有节点主机名唯一(
hostname验证)。
- 在 Master 节点重新生成 token(
八、总结
本文基于kubeadm工具完成了 K8s 单 Master 测试环境的搭建,核心步骤包括:基础环境配置(关闭防火墙 / SELinux/Swap、配置内核参数)、安装 containerd 和 K8s 工具集、初始化 Master 节点、部署 Calico 网络插件、添加 Worker 节点,并验证了集群可用性。
测试环境满足日常开发、学习和功能验证需求,若需生产环境部署,需注意:
- 采用多 Master 节点架构(高可用);
- 使用持久化存储(如 NFS、Ceph)存储 etcd 数据;
- 开启防火墙并放行必要端口;
- 使用私有镜像仓库(如 Harbor)替代公网镜像源;
- 配置监控(Prometheus+Grafana)和日志(ELK)组件。
希望本文能帮助您快速搭建稳定的 K8s 测试环境,若有问题可在评论区交流,也可参考K8s 官方文档深入学习。
更多推荐


所有评论(0)