从零搭建 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 + 以优化容器性能,下文附升级方法)
  • 依赖工具dockercontainerd(容器运行时,本文以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 映射。

  1. 设置主机名(Master 节点执行):

    hostnamectl set-hostname k8s-master
    

    Worker 节点执行(以 k8s-worker-1 为例):

    hostnamectl set-hostname k8s-worker-1
    

    执行后可通过hostname命令验证。

  2. 添加 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 会限制容器权限,测试环境建议直接关闭。

  1. 关闭防火墙

    # 停止防火墙服务
    systemctl stop firewalld
    # 禁止开机自启
    systemctl disable firewalld
    # 验证状态(应显示inactive)
    systemctl status firewalld
    
  2. 关闭 SELinux

    # 临时关闭(立即生效,重启后失效)
    setenforce 0
    # 永久关闭(编辑配置文件,需重启生效)
    vi /etc/selinux/config
    

    SELINUX=enforcing改为SELINUX=disabled,保存退出。后续重启节点后,执行getenforce验证,应显示Disabled

2.3 禁用 Swap 分区

K8s 要求禁用 Swap,避免容器内存被 Swap 置换,影响性能和稳定性。

  1. 临时禁用 Swap(立即生效):

    swapoff -a
    
  2. 永久禁用 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),需手动加载并配置内核参数。

  1. 加载内核模块:创建模块配置文件:

    vi /etc/modules-load.d/k8s.conf
    

    插入以下内容:

    overlay
    br_netfilter
    

    保存退出后,执行以下命令加载模块:

    modprobe overlay
    modprobe br_netfilter
    

    验证模块是否加载成功:

    lsmod | grep -E "overlay|br_netfilter"
    

    若输出结果包含两个模块,说明加载成功。

  2. 配置内核参数:创建内核参数配置文件:

    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 + 内核对容器网络、存储的支持更优,建议升级。

  1. 安装 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
    
  2. 安装 4.19 内核

    yum --enablerepo=elrepo-kernel install kernel-lt-4.19.276-1.el7.elrepo -y
    
  3. 设置默认内核为 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
    
  4. 重启节点

    reboot
    

    重启后执行uname -r验证,应显示4.19.276-1.el7.elrepo.x86_64

2.6 安装容器运行时(containerd)

K8s 从 1.24 版本开始不再默认依赖 Docker,而是推荐使用containerd作为容器运行时(更轻量、无 Docker 守护进程依赖)。

  1. 安装 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
    
  2. 安装 containerd

    yum install -y containerd.io-1.6.28  # 选择稳定版本,避免最新版兼容性问题
    
  3. 配置 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 仓库,用于安装kubeadmkubeletkubectl(K8s 核心工具)。

  1. 创建仓库配置文件

    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
    

    保存退出。

  2. 安装 K8s 工具集:为避免版本兼容性问题,建议指定稳定版本(本文以1.28.2为例,可根据需求调整):

    yum install -y kubelet-1.28.2 kubeadm-1.28.2 kubectl-1.28.2 --disableexcludes=kubernetes
    
  3. 设置 kubelet 开机自启:kubelet 是 K8s 节点上的核心组件,需确保开机启动:

    systemctl enable kubelet
    # 此时kubelet未启动(需后续初始化Master后才会启动),状态为active (exited) 是正常的
    systemctl status kubelet
    

三、初始化 Master 节点(仅 Master 执行)

Master 节点是 K8s 集群的控制平面,包含apiserveretcdcontroller-managerscheduler等核心组件,需通过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 的命令行工具,需配置权限才能操作集群(按初始化成功提示的命令执行)。

  1. 非 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
    
  2. root 用户配置

    export KUBECONFIG=/etc/kubernetes/admin.conf
    # 若想永久生效,可添加到/etc/profile
    echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
    source /etc/profile
    
  3. 验证 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 分钟,执行以下命令验证:

  1. 查看 Calico Pod 状态(所有 Pod 应处于Running状态):
    kubectl get pods -n kube-system | grep calico
    
  2. 再次查看 Master 节点状态(应变为Ready):
    kubectl get nodes
    
    若输出STATUS: 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,优先检查以下两点:

  1. Calico 网络插件是否部署成功:Worker 节点需拉取 Calico 镜像并启动 Pod,执行kubectl get pods -n kube-system -o wide查看 Calico Pod 是否在 Worker 节点运行;
  2. 节点间网络连通性: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 验证部署结果

  1. 查看 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>
    
  2. 查看 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)。

  3. 访问 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 驱动不匹配、内核参数未配置。
  • 解决方案
    1. 确认 Swap 已永久禁用(free -h验证);
    2. 确认 containerd 的 Cgroup 驱动为systemd(查看/etc/containerd/config.toml);
    3. 重新加载内核参数(sysctl --system)。

7.3 Calico Pod CrashLoopBackOff

  • 原因:Pod 网络网段与主机网段冲突,或内核模块未加载。
  • 解决方案
    1. 检查--pod-network-cidr是否为10.244.0.0/16(Calico 默认网段);
    2. 确认br_netfilter模块已加载(lsmod | grep br_netfilter)。

7.4 Worker 节点无法加入集群

  • 原因:token 过期、Master 6443 端口不通、节点主机名重复。
  • 解决方案
    1. 在 Master 节点重新生成 token(kubeadm token create --print-join-command);
    2. 验证 Worker 节点能 ping 通 Master,且 6443 端口未被防火墙拦截;
    3. 确保所有节点主机名唯一(hostname验证)。

八、总结

本文基于kubeadm工具完成了 K8s 单 Master 测试环境的搭建,核心步骤包括:基础环境配置(关闭防火墙 / SELinux/Swap、配置内核参数)、安装 containerd 和 K8s 工具集、初始化 Master 节点、部署 Calico 网络插件、添加 Worker 节点,并验证了集群可用性。

测试环境满足日常开发、学习和功能验证需求,若需生产环境部署,需注意:

  1. 采用多 Master 节点架构(高可用);
  2. 使用持久化存储(如 NFS、Ceph)存储 etcd 数据;
  3. 开启防火墙并放行必要端口;
  4. 使用私有镜像仓库(如 Harbor)替代公网镜像源;
  5. 配置监控(Prometheus+Grafana)和日志(ELK)组件。

希望本文能帮助您快速搭建稳定的 K8s 测试环境,若有问题可在评论区交流,也可参考K8s 官方文档深入学习。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐