Kubernetes多节点集群部署指南:从Kubeadm初始化到生产级高可用
简介《Kubernetes部署指南.pdf》是一份面向容器运维人员、系统管理员及云原生开发者的实操型部署手册聚焦如何在不同环境下快速搭建高可用Kubernetes集群。文档围绕单机部署与集群部署两条主线系统讲解kubeadm、kops、Kubespray、kubeasz等工具在Azure、Windows、LinuxKit等平台上的操作要点并给出GCE虚拟机中Kubernetes-The-Hard-Way的逐级实践路径覆盖创建计算资源、配置证书、生成密钥、部署Etcd群集、初始化控制节点与计算节点、配置网络路由和DNS等完整步骤适合正在规划生产环境、希望离线对照实施的工程师参考。资源包为单个PDF文件大小3.91MB便于本地查阅目前已有178人学习下载。内容还整理了依赖组件的版本兼容对照Etcd、Docker、Go、CNI、CSI等、kubectl客户端安装、Sonobuoy烟雾测试以及国内镜像加速等实用经验同时描述单机选择、公有云和裸机集群的不同校验方法用户可按目录快速定位到自身场景减少部署与排障过程中的摸索时间。1. Kubernetes 部署指南从单机 Docker 到多节点集群中间卡住的不是概念手里有一批物理机或云服务器想在它们之上跑起一套 Kubernetes 集群这大概是每位运维和后端工程师都绕不过去的一道坎。网上的教程一搜一大把但真正落到自己环境里问题往往不是“Kubernetes 是什么”而是“这套部署流程为什么在我这里跑不通”。版本选型、容器运行时、网络插件、证书有效期任何一个环节没对齐初始化就会莫名其妙地失败。《Kubernetes部署指南.pdf》这份资料的核心价值恰好就是把散落在官方文档和社区帖子里的部署经验收敛成一套可直接复现的操作路径。它不负责解释 Kubernetes 的架构哲学而是解决一个更现实的问题照着做集群能起来业务能跑上去。适合手里有测试机或者生产服务器、正要动手从零搭建集群的工程师也适合集群已经Exists但想要梳理一遍部署合理性的人。2. 动手前先定盘子集群规模、版本选型与部署工具怎么选2.1 部署工具选型kubeadm、二进制还是发行版自带方案第一次看到kubeadm init觉得简单真正部署完才发现工具只解决了控制平面初始化的问题离“整个集群可运维”还很远。在考虑用什么工具之前先想清楚一个更基本的问题这套集群是给测试用的还是给线上业务用的还是给边缘节点用的。三种场景对部署工具的容忍度完全不同。常见做法是先用 kubeadm因为对于大多数中小规模集群kubeadm 已经能把 etcd、API Server、Controller Manager、Scheduler 这些控制平面组件打包成静态 Pod 管理起来升级和证书续期都有官方命令支撑。二进制部署的灵活性最大可以自定义每个组件的启动参数还可以把 etcd 单独拆到独立节点上适合对控制平面有特殊要求或者需要离线交付的环境但维护成本也最高。发行版自带方案比如 RKE2、K3s 这类封装程度高部署速度快但当集群出现诡异问题需要翻日志定位时多出来的一层封装可能会成为排查时的黑匣子。我个人的习惯是测试环境直接 kubeadm生产环境优先看团队有没有现成的运维体系如果是从零开始且服务器数量在几十台以内kubeadm 加少量脚本也能撑住。这个选择决定了后面每一步的排错路径别在工具选型上花太多时间纠结但要明确一点无论选哪种方式部署出来的集群都必须具备“坏了能修、升级能回滚、出问题能看日志”的基本能力。2.2 集群规划先算资源再定角色部署集群最忌讳的事情是边装边想我见过不少翻车现场都是因为节点角色没有提前规划。一个标准的高可用集群至少需要三台控制平面节点因为 etcd 需要奇数节点来保证选主可用性三台是最低配。如果只有一台控制平面节点那部署的是教学环境不是生产环境API Server 一挂整个集群就瘫痪了。硬件规划上控制平面节点对 CPU 和内存的敏感度远超工作节点。etcd 是磁盘敏感型应用它的写入性能直接决定整个集群的响应速度建议 SSD 起步机械硬盘在节点数量多了以后会明显拖慢 watch 事件的推送。工作节点则根据业务类型区分CPU 密集型的业务选高主频机型内存密集型的业务重视内存大小涉及模型推理或大数据计算的场景需要额外考虑 GPU 和本地盘。下表是一个常见的资源建议实际配置可以按业务压力浮动但不建议低于这个基线节点角色CPU 建议内存建议磁盘建议节点数量控制平面单节点测试2 核4 GB40 GB SSD1控制平面高可用4 核8 GB100 GB SSD3工作节点轻量业务4 核8 GB100 GB 以上按需工作节点数据密集型8 核以上16 GB 以上SSD 独立数据盘按需版本选型同样要提前锁定。Kubernetes 的版本迭代节奏很快每个版本会同时维护多个 minor release但并非所有版本都适合直接用。我的经验是选当前最新稳定版往前推一到两个 minor 版本等待社区反馈充分之后再用。同时还要核对容器运行时和网络插件的兼容矩阵Kubernetes 版本、containerd 版本、Calico/Cilium 版本三者之间任何一个不匹配都会在初始化或运行时报出非常难排查的错误。2.3 网络模型与存储方案部署前必须敲定的两个决策网络方案是整个部署过程中最容易让新手迷惑的部分。Kubernetes 自己不做网络实现它只定义了 CNI 接口具体的数据包转发由插件完成。Calico 是基于三层 BGP 路由的方案性能好、排错直观适合大多数传统运维团队Cilium 基于 eBPF功能更丰富可观测性好但对内核版本有要求旧版本内核可能需要先升级再部署。如果集群工作节点都在一起且网络简单Calico 的 IPIP 模式足够用如果对性能敏感且内核版本够新Cilium 值得投入。存储方案也一样需要在部署工作节点之前想清楚。集群跑起来以后有状态服务早晚会出现在业务清单里比如数据库、消息队列、对象存储网关。如果只打算跑无状态应用那存储可以先不部署但只要有持久化需求就得从本地卷、NFS、Ceph 这类方案里挑一个提前准备。部署指南里反复强调存储前置是因为 PVC 创建失败这个问题的表象极多但根源往往只有一个存储插件根本没装。3. 按顺序搭控制平面与工作节点节点准备到 Ingress 落地的完整部署步骤3.1 节点初始化主机名、内核参数与容器运行时集群节点的系统准备有一套固定动作在任何部署工具之前完成。第一步是设置主机名并写入/etc/hosts确保节点之间能通过主机名互相解析。这一步看起来简单但确实遇到过因为主机名带下划线或者大写字母导致 kubelet 证书生成异常的案例主机名一律使用小写字母加连字符不要包含特殊符号。第二步是内核参数调整。Kubernetes 要求开启net.bridge.bridge-nf-call-iptables和net.ipv4.ip_forward同时在有大量并发连接的场景下调整net.core.somaxconn和文件句柄限制。常见的做法是直接写入/etc/sysctl.d/k8s.conf然后执行sysctl --system使其生效。还需要关闭交换分区swapoff -a之后再从/etc/fstab里注释掉 swap 行这一步不做kubelet 会拒绝启动。第三步是安装容器运行时。当前主流选择是 containerd它比 dockershim 时代更轻量也是 Kubernetes 官方推荐的方向。安装完成后需要修改默认配置把SystemdCgroup设置为true否则 kubelet 与容器运行时的 cgroup 驱动不一致节点会一直处于 NotReady 状态。配置修改完毕后重启 containerd用ctr version确认运行时可用。3.2 初始化控制平面初始化参数、Pod 网段与证书有效期节点准备完成后在控制平面节点上执行初始化命令。初始化参数里最需要注意的是--apiserver-advertise-address和--pod-network-cidr。前者决定 API Server 对外通信的地址在有多个网卡的服务器上必须显式指定否则 kubeadm 会自动抓取默认路由对应的 IP可能抓到的是内网管理地址导致其他节点无法访问 API Server。后者是 Pod 网段需要和网络插件保持一 致比如 Calico 默认使用的192.168.0.0/16就需要在初始化时配上。常见的初始化命令如下kubeadm init \ --apiserver-advertise-address192.168.10.10 \ --pod-network-cidr192.168.0.0/16 \ --kubernetes-versionv1.28.2 \ --control-plane-endpoint192.168.10.10:6443命令里的--kubernetes-version需要指定一个实际存在的版本否则 kubeadm 会尝试从网上拉取最新版本信息离线环境下这一步会直接卡住。--control-plane-endpoint在高可用场景下应该指向负载均衡器的地址而不是某一台控制平面节点这样才能保证 API Server 入口的高可用。初始化完成后会在终端打印两段关键信息一段是加入集群的命令另一段是 kubeconfig 文件的拷贝命令。把这两段内容保存下来后面加入工作节点和控制平面节点都靠它们。然后执行mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config让kubectl命令可用。3.3 安装网络插件Calico 部署的最小操作集控制平面初始化完成后集群里的节点还处于 NotReady 状态因为没有网络插件。Calico 的部署在官方文档里有完整命令但实际执行中按照固定的操作顺序来做比较稳妥。先创建 Calico 的配置目录再用 kubectl 应用其 manifest 文件kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml这里有个细节值得注意custom-resources.yaml中默认的cidr字段是192.168.0.0/16如果初始化时设置的 Pod 网段不是这个值需要先编辑文件再提交。网络插件安装后kubectl get pods -n calico-system观察 Pod 状态等所有 Pod 进入 Running控制平面节点会先变为 Ready工作节点加入后再逐步 Ready。3.4 工作节点加入集群token 过期怎么办工作节点的加入命令就是初始化时打印出来的那条kubeadm join在每台工作节点上执行。如果当时没保存下来或者 token 已经过期可以在控制平面节点上重新生成kubeadm token create --print-join-command执行完 join 命令后回到控制平面节点执行kubectl get nodes查看节点状态。工作节点变为 Ready 需要等待一会儿因为要拉取镜像并启动 kubelet。如果节点长时间处于 NotReady优先查看 kubelet 日志journalctl -u kubelet是最直接的排查入口。大多数情况是容器运行时配置不一致或者网络插件没有就绪日志里通常会有明确的错误线索。3.5 最后一段Ingress Controller 的部署集群基础就绪后业务流量怎么进来是让整套部署方案真正完整的关键。有两种常见做法一是直接使用云平台提供的负载均衡器配合 Service 的 LoadBalancer 类型暴露服务二是在自建机房或没有云负载均衡的环境里部署 Ingress Controller。指南里推荐后者因为不依赖特定云厂商而且在裸金属和虚拟机环境里都能用。Ingress Controller 以 Deployment 方式运行配合 Service 对外暴露入口。如果在裸金属环境常见做法是用 hostNetwork 方式让 Ingress Controller 直接占用宿主机端口再在前面配一个 HAProxy 或 Nginx 做流量分发。部署完成后需要确认 IngressClass 资源是否存在否则创建 Ingress 时会把所有流量导向默认的 nil class导致后端规则一直不生效。检查命令是kubectl get ingressclass如果为空需要手动创建并标记为默认。4. 生产级高可用与安全加固etcd、证书与资源隔离的部署参数设计4.1 高可用架构控制平面负载均衡与 etcd 集群单控制平面集群适合开发和测试生产环境不推荐。把控制平面扩展成三节点首先需要一个负载均衡器把外部流量分发到三台 API Server 上。自建环境里用 HAProxy 或 Nginx 都行配置核心就一条把 6443 端口代理到三台控制平面节点的 6443 端口开启健康检查后端节点异常时自动摘除。etcd 的部署方式也要重新考虑。kubeadm 默认把 etcd 以静态 Pod 形式部署在控制平面节点上三台控制平面节点就组成一个三节点的 etcd 集群。这种部署方式简单但有个隐患控制平面节点的磁盘压力和 etcd 的性能会互相影响。更大规模的集群通常把 etcd 单独部署到专用节点上减少干扰但这意味着要放弃 kubeadm 的默认编排改用手动方式部署 etcd复杂度明显上升。对于大多数规模在几十台节点以内的集群控制平面和 etcd 共用节点是合理选择关键是磁盘别用机械盘。Etcd 的参数有几个关键项需要确认--listen-client-urls和--listen-peer-urls要监听在正确的网卡上--initial-cluster里的成员列表要写对--quota-backend-bytes默认 2GB 建议调整到 8GB 防止 etcd 空间耗尽。执行etcdctl endpoint health --cluster可以验证 etcd 集群的健康状态成员列表异常时会直接暴露出来。4.2 证书体系有效期查看与自动续期Kubernetes 集群内部的证书体系由 PKI 构成kubeadm 生成的证书有效期默认是一年。集群运行时间一旦超过这个期限API Server 和 kubelet 之间的通信就会中断。如果业务不敏感最简单的方案是每年手动执行一次kubeadm certs renew all然后逐个重启控制平面组件。但手册化的部署流程更推荐直接加一个定时任务。kubeadm certs renew all --config/etc/kubernetes/kubeadm-config.yaml systemctl restart kubelet证书续期后需要重启相关 Pod 才能生效常见做法是直接rm -rf /etc/kubernetes/manifests/下的静态 Pod 定义再恢复或者通过逐台滚动重启控制平面节点实现。这里有个血泪教训证书续期后如果不同步重启 kubelet节点会陷入证书轮换的循环报错。记住这个顺序——先续期再重启 kubelet再检查 Node 状态。4.3 资源隔离Namespace 配额与 LimitRange控制平面稳定后业务侧的规范化也要在部署阶段就位。Namespace 配额是资源管控的第一道闸门没有配额的集群会出现某个业务把资源占满、其他业务无法调度的情况。针对命名空间配置 ResourceQuota再配合 LimitRange 约束单个 Pod 的资源上下限。一个最小配置看起来像这样apiVersion: v1 kind: ResourceQuota metadata: name: quota spec: hard: requests.cpu: 8 requests.memory: 16Gi limits.cpu: 16 limits.memory: 32Gi没有设置 requests 和 limits 的 Pod 在高水位下会直接触发驱逐机制业务出现无规律重启。这个参数层面的内容在部署新业务时非常容易被忽略 YAML 只写镜像不写资源限制等集群 OOM 时才开始补课不如在部署阶段就把这些约束固化到流程里。4.4 审计日志与资源请求规范生产集群需要开启审计日志记录 API Server 收到的所有请求。kubeadm 方式部署时默认审计策略未配置需要手动添加--audit-log-path和--audit-policy-file参数。审计日志有助于回答两个问题谁在什么时间改了什么资源以及某个异常状态是哪个组件触发的。输出到标准输出的审计日志没有价值落盘加定期清理才是可用的方案。资源请求规范则应落实到模板或脚手架上所有新增服务一律要求写清 requests 和 limits。没有资源限制的服务在节点高负载时被 OOM Kill 的对象可能不是业务进程本身而是 kubelet 或系统关键进程。这一步不需要额外组件纯靠部署时的模板约束和 review 习惯但收益非常明显。5. 部署避坑指南初始化失败、被覆写的 Pod 与被“节点 NotReady”折磨的五个常见问题5.1 现象kubeadm init报错提示端口被占用现象初始化执行到一半失败提示[ERROR Port-6443]: Port 6443 is in use或类似信息检查端口后确认没有其他进程占用但 kubeadm 依旧拒绝继续。原因最隐蔽的一种情况是 before 初始化尝试过其他方式部署残留的 kubelet 服务或 etcd 静态 Pod 还挂在系统里另一种是 Docker 或 containerd 中的历史容器占用了端口。解决先彻底清理残留环境执行kubeadm reset并删除/etc/kubernetes/、/var/lib/etcd等目录再用ss -lntp确认端口真正释放。如果环境中存在容器运行时需要把残留容器一并删掉然后重新执行初始化。5.2 现象工作节点加入后一直 NotReady现象kubectl get nodes能看到节点但状态为NotReady等多久都不变。原因kubelet 无法连接到 API Server或者无法拉取必要的系统镜像也有可能是容器运行时的 cgroup 驱动和 kubelet 不一致这是最普遍的翻车原因。解决先执行journalctl -u kubelet -f查看日志如果日志中反复出现failed to get cgroup stats之类的内容修改 containerd 的/etc/containerd/config.toml把SystemdCgroup置为true重启 containerd再重启 kubelet。如果日志里报镜像拉取失败检查节点能否访问镜像仓库离线环境则需要提前导入镜像。5.3 现象集群运行一段时间后突然逐台失联现象节点全部 Ready但每隔一段时间某台工作节点上的 Pod 被重新调度节点状态在 Ready 和 NotReady 之间徘徊。原因常见诱因是 etcd 集群性能劣化导致控制平面的 watch 事件推送超时kubelet 的心跳上报没有被及时处理。或者节点的系统盘空间被镜像和日志占满kubelet 无法正常写状态文件。解决这条坑很隐蔽因为节点表面看是健康状态。先登录出问题的节点执行df -h检查磁盘余量再在控制平面节点上执行etcdctl endpoint status查看 etcd 的延迟指标。如果确认是磁盘问题清理/var/lib/containerd下的无用镜像层配置镜像 GC 策略给系统盘留出至少 20% 的余量。5.4 现象kubelet 反复重启日志里报证书过期现象节点状态异常kubelet 日志里出现certificate has expired or is not yet valid即使重启节点也没有改善。原因kubeadm 生成的证书默认为一年有效期集群运行超过一年kubelet 的客户端证书失效。部分场景下是集群运行期间做过主机的迁移或复制导致/etc/kubernetes/pki中的证书与新主机信息不匹配。解决在控制平面节点执行kubeadm certs renew all然后在所有节点上重启 kubelet。如果证书文件本身损坏需要在控制平面节点重新生成并分发到各个节点。这里给个后续部署时的建议集群证书有效期可以单独建立一个告警项别等到真断了才去排查续期操作非常简单但发现问题的过程会消耗大量时间。5.5 现象Ingress 规则配置正确但请求 404现象Ingress 的 rules 路径、后端 Service 和端口都确认没问题但访问时还是 404。原因大概率是 IngressClass 没有指定。集群里同时存在多个 Ingress Controller 时Ingress 对象不知道要挂到哪个 Controller 上流量被默认控制器接收但规则没有匹配到。解决执行kubectl get ingressclass确认默认 IngressClass 是否存在如果没有创建一个并加上ingressclass.kubernetes.io/is-default-class: true注解。同时检查 Ingress 的 YAML 声明里是否写了ingressClassName字段确保指向正确的 Controller。还有一个不太容易想到的点Ingress Controller 本身是通过 Service 暴露的如果 Service 的 selector 和 Controller 的 Pod 标签不匹配整个流量入口就是断的用kubectl get endpoints -n ingress-nginx检查后端的 IP 列表是否存在即可验证。6. 部署完成不等于能用验证链路与巡检化的最终收尾6.1 从 Pod 到域名一条完整的验证链路集群部署完第一件事不是立刻迁移业务而是验证整个数据链路是否真的通了。最快的验证方式创建一个测试 Deployment写一个 Service再配上 Ingress然后从集群外访问域名。kubectl create deployment nginx --imagenginx kubectl expose deployment nginx --port80 --target-port80 --typeClusterIP创建 Ingress 时host 先用test.example.local代替在客户端机器上解析到 Ingress Controller 所在节点的 IP。浏览器访问后能出现 Nginx 欢迎页说明从域名解析、Ingress Controller、Service 到后端 Pod 的整条链路没有问题。逐层排查的顺序是先看 Pod 是否 Running再看 Service 的 Endpoints 是否有 IP最后看 Ingress 是否绑定到了正确的 IngressClass。6.2 故障演练混沌工程式的验证方法链路通了只代表正向流程正常还要验证故障场景下的恢复能力。最常见的演练方法逐台重启控制平面节点观察集群是否还能正常服务逐台驱逐工作节点上的 Pod确认业务能调度到其他节点手动 kill 掉一个关键 Pod验证 ReplicaSet 能自动拉起新的副本。这套验证要验证的不是“kubectl get nodes”是否正常而是“业务是否真的不受影响”。重启控制平面节点时如果负载均衡的健康检查没有配合好API Server 的 VIP 会漂移半天才恢复。这类问题光靠观看节点状态发现不了必须实际访问一次业务域名才能暴露。6.3 巡检脚本把部署经验固化成可重复的动作部署完成不是终点而是运维周期的起点。我通常会把部署和巡检这两件事绑定到一起把常见的检查项写成一个脚本放到 cron 里定期执行。脚本的核心检查项包含节点状态、etcd 集群健康、证书过期时间、磁盘余量、API Server 的响应延迟。遇到异常直接输出到日志并触发告警这样就不用每天手动敲命令。检查证书过期时间用一行 openssl 命令即可配合定时任务实现自动化提醒。巡检的覆盖范围不需要一开始就追求全面把部署过程中遇到过的坑逐步沉淀成检查项是最实用的迭代路径。这套脚本的维护成本很低但对长期运行的集群来说它相当于一份会持续更新的部署手册。6.4 版本升级最后的常规操作部署完成三个月后大概率会面临版本升级。无论是大版本跳跃还是小版本迭代升级前先做一件事查看官方发布的版本差异和废弃 API 列表。Kubernetes 的 API 组有时会在某一版本被移除如果业务里的 YAML 还在用旧版本 API升级后可能会出现配置无法下发的问题。通常推荐用工具扫描一遍集群里已有的资源找出使用废弃 API 的对象提前修改。升级过程中优先升级控制平面节点再逐批升级工作节点。控制平面升级到一半发现异常至少可以先暂停保住业务的稳定。如果一切都验证过了整个集群就具备了持续演进的能力后续再聊扩节点、混部、GPU 调度都是顺手的事情。这套部署方案是否值得投入用上面这四条验证路径跑一遍答案自然就清楚了。希望帮到你。本文还有配套的精品资源点击获取