Kubernetes集群部署实战:从版本锁定到CNI选型的完整指南

发布时间:2026/11/4 18:34:46

Kubernetes集群部署实战:从版本锁定到CNI选型的完整指南 简介一份面向Kubernetes初学者及运维人员的部署指南PDF系统梳理集群搭建中的关键步骤与常见问题适合本地实验或生产交付。整份资源为单个PDF文件体积约3.91MB内容覆盖单机部署、集群部署、kubeadm、kops、Kubespray、Azure、Windows、LinuxKit、kubeasz等主流方式并清晰说明依赖组件版本匹配、Docker和Go版本依赖、CNI与CSI版本关系等关键细节。这份指南还细致介绍了kubectl客户端安装、Etcd群集部署、控制节点和计算节点配置流程以及创建计算资源、配置证书、生成密钥、配置网络路由等环节覆盖集群上线的完整路径。部署验证与排障部分讲解了如何用Sonobuoy检查集群功能并针对国内镜像拉取慢的问题提供了国内镜像列表与加速方案降低实操门槛。目前已有178人学习适合需要快速搭建Kubernetes环境、排查部署问题或规划集群方案的研发与运维工程师参阅。 你大概也遇到过这种场景照着网上的Kubernetes部署教程一步步敲,kubeadm init跑完了kubectl get nodes却只有一个NotReady的master躺在那里日志翻半天找不到方向。我第一次搭集群就是这个状态后来才发现大部分问题根本不是操作问题而是版本、网段和运行时配置没对齐。这篇内容就是一份完整的Kubernetes部署指南从选版本、装运行时到控制平面初始化、节点接入、Dashboard落地、再到高频故障复盘一步步拆给你看顺手把每一步背后的工作原理也讲清楚。适合准备在测试或生产环境搭Kubernetes集群的运维和开发也适合面试前想补一轮部署原理的人。1. 部署前为什么要锁版本、量资源版本选型与集群规划1.1 三件套版本必须锁定Kubernetes部署的第一步不是执行命令而是确认版本。这里说的三件套是kubeadm、kubelet、kubectl这三个二进制必须来自同一个release管道版本号要一致。我自己见过最坑的情况kubeadm是v1.27kubelet却是v1.28init时校验不报错等到节点加入后apiserver和kubelet之间的通信频繁出现the server rejected our request之类的错排查成本非常高。官方支持的版本浮动范围允许kubelet比apiserver低一个minor版本但初学阶段没必要给自己挖这个坑。强烈建议直接锁同一个版本并且在apt或yum里把版本固定住防止某次系统更新把kubelet升上去造成整个集群的组件版本参差不齐。习惯用apt的可以这样装apt-get update apt-get install -y kubelet1.28.2-00 kubeadm1.28.2-00 kubectl1.28.2-00 apt-mark hold kubelet kubeadm kubectlapt-mark hold这步很容易被忽略但很重要。我有一次就是忽略了这个系统自动升级后master和worker的kubelet版本不一致Pod调度全乱套。先把版本锁定后面运维会省掉很多麻烦。1.2 节点资源与网络端口规划资源规划是另一个容易被跑通教程就行心态跳过的事。Kubernetes控制平面至少需要2核4Getcd对磁盘IO很敏感有条件就直接上SSD。工作节点建议同样2核4G起步生产环境再根据业务叠加。一个我常用的规划参照角色CPU内存磁盘控制平面节点2核4GSSD50G工作节点2核4G100G按镜像存储量上浮etcd节点独立部署时4核8GSSD200G网络层面节点之间必须IP互通内网环境建议统一用静态IP并写入/etc/hosts。动态IP分配会造成一个非常隐蔽的问题初始化时apiserver把IP写进证书之后节点IP一变证书校验失败所有组件通信全部异常。端口方面至少要放行这几组API Server的6443etcd的2379-2380kubelet的10250以及NodePort范围的30000-32767。很多人的集群部署完跨节点访问诡异失败回头查才发现是防火墙把10250给拦了。2. 从裸机到可初始化系统参数与容器运行时准备2.1 为什么新版本直接选containerd而不是考虑DockerKubernetes从1.24版本开始移除了对Docker的dockershim支持虽然可以通过cri-dockerd这类适配器继续用Docker但官方推荐路径已经是直接用containerd。道理很简单containerd本身就是Docker拆出来的容器运行时但它没有Docker那一层CLI和后台服务资源占用更小启动更快也没有通过Docker再转发给containerd这层中间损耗。实际部署时我会先装containerd然后生成一份默认配置containerd config default | tee /etc/containerd/config.toml生成后必须检查一个关键参数SystemdCgroup是否设置成true。containerd默认配置在cgroup驱动上可能和kubelet不一致特别是使用systemd作为init系统的发行版。两者的cgroup驱动不一致Pod就会出现反复CrashLoopBackOff日志里写着failed to run Kubelet或unknown runtime。这个配置改完要重启containerd才生效systemctl restart containerd还要顺手看一下sandbox_image这个字段它指向pause容器镜像。这个镜像在每个节点上都必须有网络不好的时候kubeadm init会一直卡在等待kubelet启动上就是因为pause镜像拉不下来。可以把这个地址指向网络可达的镜像仓库或私有仓库的pause镜像改完同样记得重启containerd。2.2 内核参数和swapoff两个直接决定成败的细节初始化之前节点的基础环境要做三件事加载内核模块、设置sysctl参数、关闭swap。内核模块加载cat EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilteroverlay是容器镜像分层使用的文件系统驱动br_netfilter则让网桥设备上的数据包也能经过iptables规则处理。Kubernetes的Service转发依赖iptables或者IPVS如果br_netfilter没加载跨节点的Pod访问Service会出现超时或连接被重置。然后是sysctl参数cat EOF | 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 sysctl --system第一个参数让iptables规则能作用于容器网络的网桥数据包第二个是IPv4转发开关。没有这些参数Pod和Pod之间、Pod和外部网络之间的流量在节点转发层就断了。swapoff这一步看起来简单很多教程一句带过但实际坑很深。kubelet默认检测到节点开启了swap会直接拒绝启动日志里明确写着running with swap on is not supported。如果不想永久关闭swap至少要在部署期间关闭并把/etc/fstab里的swap行注释掉否则重启之后swap又回来了Pod调度和内存回收行为会出现大量不可预期的问题。3. kubeadm init不是魔法按钮控制平面初始化的常见gap3.1 每个初始化参数背后的含义kubeadm init是部署控制平面的核心命令问题在于很多人直接复制网上命令参数含义完全不知道。一旦踩坑连从哪排查都不知道。一个比较完整的init命令是这样的kubeadm init \ --apiserver-advertise-address192.168.10.10 \ --pod-network-cidr10.244.0.0/16 \ --service-cidr10.96.0.0/16 \ --kubernetes-versionv1.28.2--apiserver-advertise-address指定API Server对外广播的地址。如果你的节点有多个网卡不指定这个参数kubeadm可能选错IP导致后续所有kubectl请求都打到错误的地址上。--pod-network-cidr是Pod网段必须和后续部署的CNI插件定义的网段一致。Flannel的默认网段是10.244.0.0/16Calico的默认网段是192.168.0.0/16。如果你内网本身就在192.168.x.x段再直接用Calico默认网段大概率会导致节点路由冲突这个我在下一章展开。--service-cidr是Service的虚拟IP网段一般不用改。但要注意这个网段同样不能和节点网段、Pod网段重叠。网段一旦init完成就写死在集群配置里后期要改只能重建集群所以初始化之前一定要规划好。init完成后终端会输出两段关键信息一段是配置kubectl的命令另一段是给Worker节点的join命令。先把kubectl配置好mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config3.2 高可用部署时cert和control-plane-endpoint的联动生产环境通常不止一个master。高可用部署时kubeadm init多一个关键参数--control-plane-endpoint它指向负载均衡器的地址和端口。比如你前面挂了HAProxy或云平台SLB这个参数就填LB的VIPkubeadm init \ --control-plane-endpoint10.10.0.100:6443 \ --pod-network-cidr10.244.0.0/16 \ --upload-certs加--upload-certs是为了把证书上传到集群中这样后续新master节点加入时能用--control-plane参数直接把节点提升为控制平面节点。而Worker节点加入时不需要这个参数两者机制不同。高可用架构里最容易被忽视的是etcd。如果控制平面是3个masteretcd默认会以stacked方式和控制平面部署在同一批节点上数据落在master本地磁盘。这种情况下磁盘IO故障会直接影响集群可用性建议etcd数据目录所在的磁盘使用SSD并定期做etcd快照备份。没有etcd备份的集群在控制平面节点整体挂掉后基本没办法完整恢复。4. Worker节点怎么才算真正接入join、CNI选型与NotReady排查4.1 join之前worker节点也要先做全套预初始化加入Worker节点前有一个很常见的错误新节点只装了docker就执行join命令。实际上Worker节点同样需要完成系统参数设置、内核模块加载、containerd安装、kubeadm和kubelet安装也就是前面章节里的所有基础配置。少任何一步join后都可能出现cni插件找不到、kubelet启动失败、Pod调度过去就CrashLoopBackOff等问题。基础环境就绪后回到master节点上执行kubeadm token create --print-join-command这条命令会生成一个带有效期的join命令包含了token和discovery-token-ca-cert-hash。token默认有效期为24小时如果你在集群初始化当天没有立即加入Worker之后就要用这条命令重新生成。把输出复制到Worker节点执行看到This node has joined the cluster才算真正加入。之后在master上跑kubectl get nodes新节点大概率是NotReady状态这是正常的因为Pod网络还没装。4.2 CNI选型对比Flannel、Calico、CiliumCNI插件解决的是Pod网络互通问题不装CNI节点会一直停在NotReady。三种最常见方案的选型逻辑方案网络模型NetworkPolicy支持性能推荐场景FlannelVXLAN / Host-GW不支持适中测试环境、快速跑通CalicoBGP / IPIP支持较高生产环境需要网络策略CiliumeBPF支持高性能敏感、云原生进阶我的生产环境默认选Calico理由是对NetworkPolicy的支持可以让多团队共用集群时做网络隔离排查问题时的可视化工具也更加丰富。但Calico有个经典坑默认Pod网段是192.168.0.0/16而大量公司内网一直在用这个私网段。使用前先确认机房网段如果冲突可以把IPPool的CIDR改掉同时让kubeadm init的--pod-network-cidr保持一致。Calico部署命令kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml如果修改了默认网段先下载yaml找到CALICO_IPV4POOL_CIDR环境变量改成对应网段再apply。4.3 NotReady状态排查四步走节点加入后NotReady按下面顺序排查不要一上来就重启kubelet。第一步看节点状态kubectl describe node node-name重点看Conditions里的Item以及Message栏的具体内容。如果是network plugin is not ready说明CNI还没部署或没就绪直接检查Calico/Flannel的Pod状态。第二步看kubeletjournalctl -u kubelet -f这里能看到kubelet的完整错误日志比如证书不匹配、cgroup驱动错误、镜像拉取失败等。第三步看CNI插件的Podkubectl get pods -n kube-system -o wide明确是哪个组件异常再具体看它的日志。很多情况是calico-node的Pod一直Init:ImagePullBackOff归根结底又回到了镜像拉取问题上。第四步检查节点上的CNI二进制文件/opt/cni/bin目录是否为空。如果为空需要手动安装CNI pluginswget https://github.com/containernetworking/plugins/releases/download/v1.3.0/cni-plugins-linux-amd64-v1.3.0.tgz mkdir -p /opt/cni/bin tar -C /opt/cni/bin -xzf cni-plugins-linux-amd64-v1.3.0.tgz走完这四步大部分NotReady问题都能被定位到具体环节而不是漫无目的地乱试。5. Dashboard装完不等于集群好了部署验证与账号配置5.1 Dashboard的版本匹配和NodePort暴露Kubernetes Dashboard是个Web管理面板热词里排得上号的kubernetes安装dashboard。部署方式本身很简单kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml关键点是版本匹配。Dashboard v2.7.0适配的是Kubernetes v1.24到v1.27左右的集群新版集群建议查官方兼容矩阵。版本差太多会出现WebHook报错或RBAC权限异常因为不同版本的Kubernetes对RBAC资源的校验逻辑有差异。Dashboard默认Service类型是ClusterIP外部访问不到。改成NodePortkubectl -n kubernetes-dashboard edit service kubernetes-dashboard把type: ClusterIP改为type: NodePort保存后kubectl get svc -n kubernetes-dashboard查看实际分配的高位端口。然后浏览器访问https://masterIP:NodePort。有个需要适应的点Dashboard默认证书是自签的浏览器会弹证书信任警告选择信任继续访问就行。如果要在生产暴露给团队建议换成内部CA签发的证书或者直接通过Ingress把流量打到Dashboard上并绑定内部域名。5.2 管理员账号和Token获取Dashboard登录支持Token和Kubeconfig两种方式。要拿到管理员权限的Token先创建一个ServiceAccount并绑定cluster-admincat EOF | kubectl apply -f - apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard EOF然后生成Tokenkubectl -n kubernetes-dashboard create token admin-user这里注意是create token不是get secret。Kubernetes较新的版本中ServiceAccount默认不再自动创建对应的Secret所以老教程里的kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath{.secrets[0].name}) -o go-template{{.data.token | base64decode}}在新版本里拿不到东西。5.3 用真实负载验证跨节点调度Dashboard能打开只说明控制平面管理端可用不代表集群的调度和网络链路是通的。建议部署一个简单的Nginx做端到端验证kubectl create deployment nginx-test --imagenginx kubectl expose deployment nginx-test --typeNodePort --port80 kubectl get svc访问返回的NodePort地址确认能返回Nginx欢迎页。这一步验证了从外部流量进入节点再经过kube-proxy转发到Pod的完整链路。还不够再做一次跨节点验证把Pod删掉让它重新调度到另外一个Worker节点上再访问一次服务。如果新节点上的Pod能正常响应说明CNI网络跨节点通信没问题你的集群才算真正部署完成。6. 踩过的坑比文档多证书过期、镜像拉取与kube-proxy模式6.1 证书到期kubeadm集群最隐蔽的定时炸弹kubeadm生成的集群证书有效期是一年。过期后症状非常隐蔽不是全部服务挂掉而是kubectl执行命令时不定时报错比如x509: certificate has expired or is not yet valid或者连接直接被重置。很多团队对这类问题记忆深刻因为通常是业务反馈访问异常才开始排查结果发现是集群证书到期了。处理方式分两步。第一步在master上更新证书kubeadm certs renew all第二步重启控制平面组件。新版kubeadm可以通过更新kubeconfig来重新加载更稳妥的做法是滚动重启apiserver、controller-manager、scheduler这几个静态Pod最简单的操作是删除对应Pod让kubelet重建或者直接重启kubelet服务。Worker节点上的kubelet配置也需要同步更新一次。我的建议很直接不要等证书快过期才处理。把kubeadm certs renew all加进crontab定期执行或者设置日历提醒让这个问题从源头上消失。6.2 镜像拉取失败containerd配置与本地导入镜像拉取失败是部署过程里出现频率最高的问题表现多种多样kubeadm init卡在等待、Calico Pod停在ImagePullBackOff、Dashboard应用没法启动。排查方式先确定是哪个镜像拉不下来然后分两条路处理。第一条路配置containerd的镜像源。containerd配置和Docker不完全一样要在/etc/containerd/config.toml里对registry做镜像源配置或者使用网络可达的镜像仓库作为拉取源。改完配置需要重启containerd。这里想提醒的是改完不重启是很多人明明配置了却没生效的原因。第二条路离线导入。在一台网络可达的外部机器上把镜像拉下来导出再导入docker pull registry.k8s.io/pause:3.9 docker save registry.k8s.io/pause:3.9 -o pause.tar把tar包拷贝到目标节点ctr -n k8s.io images import pause.tar注意-n k8s.io这个namespacecontainerd默认namespace和Kubernetes使用的namespace不同不指定会导致导入后Kubernetes仍然认为镜像不存在。6.3 kube-proxy的iptables与IPVS模式选择kube-proxy是Service流量的转发代理默认工作在iptables模式。iptables模式的特点是规则完全交由内核netfilter处理逻辑简单稳定可靠。但Service数量上来之后iptables的规则链会变得非常长每条规则都需要遍历匹配转发延迟随之上升。切到IPVS模式可以解决这个问题。IPVS是内核内置的负载均衡模块采用hash表查找在Service数量较多时性能优势明显。切换方式kubectl -n kube-system edit configmap kube-proxy找到mode: 这一项改成mode: ipvs然后滚动重启kube-proxy。重启之前确认每个节点上装了ipvsadm和ipset否则kube-proxy会切不成功。切换完成后查看转发规则ipvsadm -L -n你会看到ClusterIP对应的规则和后端Pod列表。顺带说一句这是Kubernetes面试题里经常出现的一个考点Service的负载均衡底层如何实现答案本质上就是节点上的转发规则把ClusterIP的流量分发到后端的Podiptables模式用链式规则IPVS模式用hash表理解了这条链路后续做网络排障就不会一头雾水。我在实际部署中最后一点体会是Kubernetes部署这件事60%的时间花在版本对齐和网络参数上20%在镜像获取真正敲命令的时间很少。把版本锁好、网段规划清楚、运行时配置对齐再配合一套固定排查顺序你就能从照着教程都搭不起来进到看完报错就知道问题在哪的阶段。最后一个小建议每台机器的角色、IP、Pod网段写清楚做成表格join命令和证书到期时间记下来这些细节能在关键时刻省掉大量返工成本。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/11/2 5:21:31

施乐C3055维修手册PDF实战:从故障定位到排除闭环

简介:施乐(Fuji Xerox)DocuPrint C3055/C3055DX 彩色激光打印机官方维修服务手册(Service Manual),面向专业维修工程师和技术支持人员,用于日常维护、组件拆装与故障排查的规范参考。资源包为单…

2026/11/4 18:33:35

智慧社区全栈系统架构与高并发实践

1. 智慧社区活动商品管理系统架构解析 在社区服务数字化转型的浪潮中,活动与商品管理一直是运营效率提升的关键痛点。去年我为某大型社区集团设计的这套系统,成功将活动报名效率提升300%,商品库存周转率提高45%。这个基于Vue3SpringBootNode.…

2026/11/4 18:33:35

PCDN技术解析:家庭宽带变IDC的利与弊

1. 背景与行业现状最近两年,国内宽带市场出现了一个有趣的现象:普通家庭宽带用户突然发现自己的网速变慢了,甚至有些地区出现了频繁断网的情况。而与此同时,一些"聪明"的用户却通过某种技术手段,利用家庭宽带…

2026/11/4 18:33:35

无人机集群动态任务分配:两阶段贪婪拍卖算法解析

1. 项目背景与核心挑战无人机集群协同目标分配是当前智能无人系统领域的前沿研究方向。2024年AST SCI1区TOP期刊最新发表的这项研究,针对大规模无人机群(1000节点)在复杂战场环境下的动态任务分配问题,提出了创新的两阶段贪婪拍卖…

2026/11/4 18:33:35

光通信系统仿真:OptiSystem工程实践与性能优化

1. 项目概述:光通信仿真的工程价值在光纤通信系统设计中,工程师们常常面临一个关键矛盾:如何在实验室环境下验证复杂的光网络性能,又不必承担高昂的实物测试成本?这正是OptiSystem这类专业仿真工具大显身手的领域。作为…

2026/11/4 18:28:35

AgentScope 2.0:面向生产级多智能体协同的Java运行时基础设施

1. 这不是又一个“AI Agent框架”——AgentScope到底在解决什么真问题?最近在几个技术群和内部分享会上,总有人甩出一句:“推荐一个牛逼的AgentScope系统”,然后就没了下文。我一开始也以为是另一个披着Agent外衣、实则跑个LangCh…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/4 0:03:20

AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年…

2026/11/4 0:03:20

从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你…

2026/11/4 0:03:20

32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/3 14:24:53

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑