搭建Kubernetes集群我踩过最多的坑几乎都集中在最开始的环境配置阶段。很多人喜欢一上来就急着跑kubeadm init结果报错千奇百怪看来看去都是因为系统参数、容器运行时没对齐。实际上K8s集群搭建的学习记录第一部分就应该把“配置环境”这层地基夯实后面所有节点加入、Pod调度、网络打通全都依赖这一步的细节。这篇文章就围绕我在搭建K8s集群时对环境配置的完整梳理适合刚开始接触K8s、准备自己动手从零搭一套集群的读者。即使你之前没碰过容器只要能跟着把系统初始化、容器运行时、核心组件这三块做好后面初始化控制平面就不会一脸懵。1. 环境设计先想清楚再动手1.1 硬件规划与节点角色分配搭建K8s集群第一步不是装软件而是想清楚要几台机器、每台机器承担什么角色。常见的方案有两种单节点用于学习和测试和多节点接近生产或复杂实验。我这次采用的是三节点方案一台控制平面节点master两台工作节点worker。如果你手头机器少也可以只用两台但至少保证一台控制平面加一台工作节点这样能体验到Pod调度和跨节点通信的完整流程。硬件上没有特别夸张的要求控制平面节点建议至少2核CPU、2GB内存工作节点同理。存储方面系统盘留出20GB左右就够了因为K8s本身不大真正占空间的是镜像和日志。如果只是学习虚拟机完全没问题我用的是VirtualBox和VMware都试过网络模式记得选桥接或NAT方便各节点互通。角色分配上控制平面节点运行kube-apiserver、kube-controller-manager、kube-scheduler这些组件工作节点主要跑kubelet和kube-proxy以及实际容器负载。如果做高可用实验可以在前文提到的“三台master”场景下加负载均衡器但那是后话初期单控制平面就够。1.2 操作系统与版本选型的取舍操作系统我优先推荐Ubuntu 20.04 LTS或22.04 LTS以及Rocky Linux 9。热词里提到的“ubuntu20.04搭建yolov8环境”说明很多人用这个版本确实稳定。Ubuntu的包管理简单社区资料多遇到问题容易搜到答案。Rocky Linux 9是CentOS的替代方案如果你的生产环境是RHEL系可以选它。版本选择上K8s版本建议用稳定版尽量别追最新。当前主流是1.28系列但像1.29、1.30也在普及。关键要保证kubeadm版本、kubelet版本与K8s版本对应比如用1.28.2那三件套就都用1.28.2。容器运行时方面目前K8s默认支持containerdDocker也兼容但Docker需要额外的cri-dockerd适配器。这里我选择containerd理由后面详细说。网络方面需要规划好节点之间的通信网段。比如每个节点设置静态IP并保证能互相ping通。还要预留Pod网络和Service网络的CIDR比如Pod网段用10.244.0.0/16Service网段用10.96.0.0/12这是安装Flannel等插件的默认值不想折腾就沿用这个。2. 系统初始化把底层基础打牢2.1 关闭交换分区与防火墙的实操细节所有节点都需要执行系统初始化这一步不做后面kubeadm init会直接报错。首先关闭swapK8s要求必须禁用交换分区否则kubelet会出现性能问题。执行sudo swapoff -a sudo sed -i / swap / s/^/#/ /etc/fstab第一行临时关闭第二行永久生效。如果你有多块交换分区都要处理。防火墙方面Ubuntu默认可能没启用ufw但为保险起见查看并关闭。CentOS系则用systemctl。同时SELinux必须设置为permissive或disabled否则K8s组件访问文件会受限。执行sudo setenforce 0 sudo sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config还有iptables的桥接流量转发K8s要求开启因为容器和Pod的网络依赖内核转发。创建一个配置文件cat EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF加载模块并设置sysctl参数sudo modprobe overlay sudo modprobe br_netfilter 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这里要注意net.ipv4.ip_forward很关键如果不开启节点之间无法路由数据包Pod跨节点通信会失败。2.2 主机名与时间同步的必要准备每个节点都要有唯一的主机名方便集群内识别。比如控制平面叫k8s-master工作节点叫k8s-node1和k8s-node2。修改主机名sudo hostnamectl set-hostname k8s-master同时在所有节点的/etc/hosts中添加主机名解析否则节点之间可能无法互相找到对方。类似192.168.1.10 k8s-master 192.168.1.11 k8s-node1 192.168.1.12 k8s-node2时间同步是我一开始忽略的。集群节点时间不一致会导致证书校验失败因为K8s的证书有有效期节点间通信依赖时间戳。安装chrony或直接用systemd-timesyncdsudo apt update sudo apt install -y chrony sudo systemctl enable chrony确保各节点时间与网络时间同步。踩坑后我才意识到这一步省了后面kubeadm join时报证书错误会查到头大。3. 容器运行时选型与安装3.1 为什么现代K8s选择containerd而不是Docker热词里有“kafka集群安装”“redis集群部署”很多人习惯先装Docker再跑K8s。但K8s从1.24版本开始宣布不再直接支持Docker运行时必须通过CRI容器运行时接口适配层进行转换。Docker本身不原生支持CRI需要额外装cri-dockerd。而containerd是Docker的核心组件之一由它提供镜像管理和容器执行并且原生支持CRI。因此使用containerd更轻量、更稳定也更符合K8s生态标准。如果你有Docker使用经验containerd的命令稍有不同比如拉镜像用crictl pull查看容器用crictl ps而不是docker命令。但实际的容器运行逻辑和Docker一样。我在学习过程中发现直接用containerd能减少一层适配故障排查也更直接。3.2 安装containerd的具体步骤与配置调整系统准备完成后安装containerd。Ubuntu下可以直接用官方源sudo apt update sudo apt install -y containerd但建议手动生成默认配置因为安装后默认配置可能不适用于K8s。执行sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml关键调整是SystemdCgroup参数。默认配置可能是false但K8s推荐true因为K8s的cgroup驱动默认是systemd与containerd保持一致才不会报错。找到[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options]将SystemdCgroup设为true。另外国内网络下拉取镜像可能慢可以配置镜像加速器。在config.toml中将sandbox_image改为国内可访问的地址比如registry.aliyuncs.com/google_containers/pause:3.9。修改完成后重启containerdsudo systemctl restart containerd sudo systemctl enable containerd此时可以用ctr version或crictl version验证安装。crictl需要额外安装属于K8s的CRI工具包后面安装kubeadm时一般会带。4. 核心组件安装kubeadm三件套4.1 安装kubeadm、kubelet、kubectl及版本锁定环境配置的最后一环是安装kubeadm、kubelet、kubectl这三个工具。它们的作用分别是kubeadm负责初始化集群和管理节点加入kubelet是每个节点上负责运行Pod的核心代理kubectl是命令行控制工具。我使用阿里云源安装速度和稳定性都更好。以Ubuntu为例sudo apt update sudo apt install -y apt-transport-https curl curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - echo deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main | sudo tee /etc/apt/sources.list.d/kubernetes.list sudo apt update然后指定版本安装sudo apt install -y kubeadm1.28.2-00 kubelet1.28.2-00 kubectl1.28.2-00版本锁定很重要使用apt-mark hold防止意外升级sudo apt-mark hold kubelet kubeadm kubectl然后设置kubelet开机自启sudo systemctl enable kubelet注意此时kubelet可能处于启动失败状态因为还没有初始化集群这是正常现象稍后会变正常。4.2 kubeadm init前的预检与常见参数说明正式初始化前kubeadm会自检环境我们可以先手动检查关键项。用kubeadm init --dry-run不影响现有系统只做预检。如果输出[preflight]后没有任何error说明准备完成。此时可以规划初始化命令。初始化控制平面节点时需要指定--apiserver-advertise-address为本节点IP--pod-network-cidr为之前规划的网络段--service-cidr默认是10.96.0.0/12。示例sudo kubeadm init \ --apiserver-advertise-address192.168.1.10 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/12--dry-run能提前发现一些问题比如cgroup驱动不一致、端口占用等建议先跑一遍。初始化成功后会输出一段kubeadm join命令务必保存下来工作节点就靠它加入。5. 常见问题与排查技巧实录5.1 cgroup驱动不一致导致kubelet启动失败这是我从热词“k8s集群证书过期自动续签”联想到的同类隐蔽问题但更常见的是cgroup驱动。初始化时如果报failed to run Kubelet或container runtime is not running多半是containerd的cgroup驱动与kubelet不一致。检查cat /etc/containerd/config.toml | grep SystemdCgroup ps aux | grep kubelet | grep cgroup确保两边都是systemd。我一开始用了默认containerd配置kubelet用的是systemd结果节点加入后状态一直是NotReady后来改成SystemdCgrouptrue问题才解决。5.2 网络插件未安装导致节点状态NotReady初始化成功后控制平面节点状态如果是NotReady绝大多数原因是网络插件没装。K8s本身不提供Pod网络需要安装Flannel或Calico。Flannel配置最简单kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml但有些网络环境下无法访问GitHub建议预先下载文件到本地节点。同时确保初始化时--pod-network-cidr和Flannel的网段一致否则Pod网络无法分配IP会一直ContainerCreating。5.3 端口冲突与证书过期类问题kubeadm init报端口被占用通常是之前实验残留。用swapoff -a或关闭冲突服务能临时解决但最好检查netstat确认。证书过期问题在长期学习环境中很常见热词也提到了初期可能不会遇到但如果实验间隔很久再重启集群kube-apiserver会提示证书过期。解决方法是手动更新或者直接重新初始化学习环境下后者更快。注意学习阶段不要在生产环境使用kubeadm reset后反复快速初始化容易残留缓存和端口占用。建议每次实验完成后用kubeadm reset清理环境再重新开始。另外所有节点的操作系统版本、内核对齐能减少大量诡异问题。我用的三台Ubuntu 20.04内核版本一致从未遇到跨版本兼容问题。如果你按这个顺序配置环境后面初始化集群基本能一气呵成。我个人在实操中还有一个习惯把每一步命令的执行结果截图或存成日志尤其是sysctl和kubeadm preflight的输出一旦后续报错对比日志能快速定位问题。配置环境阶段宁可慢一点也别图快这比启动K8s之后再折腾要省心得多。最后分享一个扩展技巧如果你打算以后搭建高可用集群环境配置阶段就可以把多台master节点的硬件统一规格并预留负载均衡器的IP。虽然这属于配置环境的“稍微超纲”范围但前期规划到位后面少走许多弯路。
企业数字化 ERP 产品动态
相关推荐
苍穹外卖day6:订单模块核心链路与状态机流转实践 咱们继续聊苍穹外卖,day6。前面几天工作区还算是岁月静好,到这天开始才是真正进入“订单”这个核心领域。你会发现,之前写的分类、菜品、购物车、地址簿,到了这一步全部串联起来了,整个系统的业务主链路开始闭合。day6… · 2026/9/26 20:18:59
如何无损迁移曲库?Spotify歌单一键导入Echo Music完整教程 如何无损迁移曲库?Spotify歌单一键导入Echo Music完整教程 【免费下载链接】Echo-Music A modern Android music app with ad-free streaming, synced lyrics, offline playback, and an intuitive user experience. 项目地址: https://gitcode.com/gh_mirrors/ec… · 2026/9/26 20:18:59
组件化架构设计与工程实践:业务边界重构与依赖管理 1. 组件化方案的整体设计思路1.1 什么是组件化,为什么要做组件化很多团队对组件化的理解是“把代码拆开就行了”。如果你也这么想,那大概率会在改造的中后期付出惨痛代价。我在一线做客户端架构也快十年了,先后经历过几个从零到一、从一到N的… · 2026/9/26 20:18:59
从失控到可控:构建Claude Code模板体系的完整指南 我有段时间对 Claude Code 又爱又恨,后来想明白一件事:我从来没给它准备过一套像样的 claude-code-templates。爱的是它写起代码来确实快,恨的是它老自作主张——让它修一个小 bug,它顺手把你的测试文件全部重构了;让它… · 2026/9/26 20:54:05
RTX 3060 12G跑通MiniMax H3视频大模型实操指南 1. 项目概述:一张消费级显卡跑通国产视频大模型的实操现场RTX 3060 12G跑MiniMax H3——这个标题在最近两周的AI绘画和视频生成圈子里反复刷屏。不是因为它是性能怪兽,恰恰相反,它是一次“降维打击”式的可行性验证:用一张二手市场… · 2026/9/26 20:54:05
DCG与DAG架构对比:揭秘HDR图像传感器的动态范围提升之道 1. 为什么 Linear 模式的 Sensor 快被 HDR 需求逼到墙角了 先聊一个我在实际项目里经常遇到的场景:一颗标称 72dB 动态范围的 sensor,打在强逆光的路口,车牌照脸黑成一团,天空又白成一片。客户拿着测试图来找你,第一句… · 2026/9/26 20:54:05
SpringBoot+Vue高校疫情防控管理系统设计与业务闭环拆解 每年一到毕业设计季,后台就会收到大量同类的需求:给我一个能用的管理系统、最好前后端分离、技术栈时髦一点、能答辩能演示。而“SpringBootVue高校疫情防控web系统管理平台”这类项目,几乎是这几年被问得最频繁的选题之一。原因很简单——它… · 2026/9/26 20:54:05
RFT+自蒸馏提升LLM工具调用鲁棒性实战 1. 项目概述:这不是一次普通微调,而是对工具调用链路的外科手术式修复最近在复现几篇关于大模型工具调用鲁棒性的论文时,偶然看到一条技术动态:“Perplexity 后训练新研究:工具调用失败降 21%”。没点开原文前… · 2026/9/26 20:53:51
数据库课后习题答案别硬背:当测试用例集刷,效率翻倍 简介:万常选版《数据库原理与设计》课后习题答案资源,覆盖第2至6章及第9章,适合正在学习关系模型、数据库建模、关系数据理论与模式求精的本科生、自学者作为复习与自测材料。压缩包共7个文件,含3个doc参考答案、2个sql示例脚本、… · 2026/9/26 0:00:21
OpenClaw 替代品?Hermes Agent 踩坑实录:macOS 飞书接入 TaoToken 配置 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/26 0:00:40
向下兼容与向上兼容:接口设计中的兼容性策略与工程实践 一次版本升级事故,是很多团队绕不过去的坎。线上环境里,服务端明明已经上线了新版接口,老的移动端还在照着旧文档传参数。请求一到网关,校验直接拒绝,用户操作失败,客服群炸了锅,开发群里开始互… · 2026/9/26 0:00:46