Kubernetes v1.30.3 集群安装实战:kubeadm 初始化与避坑指南

发布时间:2026/10/22 4:56:09
Kubernetes v1.30.3 集群安装实战:kubeadm 初始化与避坑指南 上次给团队搭集群我直接选了 v1.30.3 官方 kubeadm 这套组合整个过程从准备机器到控制平面和工作节点全部 Ready前后大概花了两三个小时。如果你第一次接触 Kubernetes建议把这篇当作一份操作笔记来读每一步我都会写清楚命令、参数以及这一步为什么必须这么做。已经装过旧版本、想看看 1.30 有哪些变化的朋友也建议重点读 containerd 配置和 kubeadm init 的参数部分这两个地方是最容易踩坑的。我用的是常见的 Linux 发行版包管理器以 apt 为例中间会穿插一些个人实测下来的经验和教训。不是说只能这么装而是这套流程在当前版本下足够稳生产环境也可以按这个思路去落地。1. 版本选型与环境规划1.1 为什么选择 v1.30.3很多人装集群第一反应是装最新版但生产环境我更推荐选稳定分支的补丁版本。Kubernetes 的版本号规则是主版本.次版本.补丁版本v1.30.3 属于 1.30 这条分支里的第三个补丁版本意味着它修复了前两个补丁版本里暴露出来的一部分问题同时又保持了 1.30 这个功能集的稳定性。另外一个现实原因是组件配套。v1.30 对应的 kubeadm、kubelet、kubectl 都处于官方的标准支持周期内不会出现某些组件版本和集群版本差太多导致 API 对象不兼容的情况。Kubernetes 官方支持的版本偏移策略是kubelet 可以比控制平面低一个小版本所以我给工作节点选的也是 v1.30.3 的 kubelet避免版本差异带来的行为不一致。安装工具本身也有讲究。kubeadm 是官方提供的集群引导工具它的价值在于把控制平面组件、etcd、证书、kubeconfig 这些容易被弄乱的东西变成标准化流程。相比二进制手动部署kubeadm 生成的证书和配置会更规整相比某些一键脚本kubeadm 的每一步都透明可查排错的时候能直接看到它卡在哪。所以我的建议很直接没有特殊理由就用 kubeadm。1.2 节点规划与资源要求我这次的实验环境属于最小的可用集群一台控制平面节点加一台工作节点。控制平面节点至少需要 2 核 CPU 和 2GB 内存工作节点建议也是 2GB 以上如果跑的 Pod 比较多内存尽量给到 4GB。存储方面etcd 的数据目录最好放在独立磁盘或高性能 SSD 上尤其是生产环境。我见过不少集群因为 etcd 和系统日志共用一块 IO 能力不足的磁盘导致控制平面偶发超时。实验环境可以放宽但目录规划一开始就按生产习惯来做后面迁移成本会小很多。网络规划要提前想清楚三件事节点 IP 段、Pod 网段、Service 网段。节点 IP 段就是每台机器实际的 IP比如 192.168.1.0/24Pod 网段由你在初始化时通过--pod-network-cidr指定Service 网段默认由 kubeadm 分配一般是 10.96.0.0/12。这三个网段不能重叠否则路由一乱整个集群的网络状态会变得非常诡异。1.3 系统基础初始化拿到一台新机器后我习惯先做一套物理层准备。首先是更新系统包然后确认主机名和 hosts 解析。不要忽略 hosts 解析控制平面初始化时 kubelet 会通过主机名去注册节点如果主机名解析不到节点状态会一直卡在 NotReady。接下来开启必要的内核模块并调整 sysctl 参数。Kubernetes 的 kube-proxy 和网络插件依赖iptables完成流量转发而容器网络需要overlay和br_netfilter这两个内核模块。我常用的配置片段是这样的cat EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter然后写入内核参数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这里最关键的是net.ipv4.ip_forward 1。如果这个参数没有开启Pod 与外部网络的通信会直接失败而且排查起来很容易绕弯路因为表面现象可能是 DNS 解析不出来实际是转发没开。然后就是关闭 swap。kubelet 默认不允许开启 swap因为它依赖内存资源计算的确定性。虽然可以通过 kubelet 参数强行容忍但生产环境我建议直接swapoff -a并把/etc/fstab里的 swap 条目注释掉一劳永逸。2. containerd 安装与配置2.1 为什么 1.30 不再需要 Docker很多老教程还停留在 kubeadm 加 Docker 的时代但 Kubernetes 从 1.24 开始把 dockershim 移除了你再用 Docker 作为运行时实际上是 Docker 自己把镜像转给 containerd中间多了一层没必要的转换。当前版本下最标准的运行时就是 containerd它直接通过 CRI 接口为 kubelet 提供容器服务。如果你对 Docker 比较熟可能会觉得少了 Docker 不习惯。其实 containerd 就是那个真正的容器引擎Docker 在底层也是调用它。所以在集群里直接用 containerd反而是更接近底层、性能更好、问题更少的选择。安装 containerd 建议直接装发行版仓库里的版本或者用 containerd 官方提供的二进制包。装完之后先不要急着改配置先用containerd config default生成一个默认配置再基于它去改需要调整的几项。containerd config default | tee /etc/containerd/config.toml2.2 启动前的两个关键配置第一个配置是 cgroup 驱动。当前主流的 Linux 发行版都用 systemd 作为 init 系统而 containerd 默认的 cgroup 驱动可能是cgroupfs。kubelet 如果使用 systemd 驱动两者不一致Pod 启动时就会出现奇怪的资源限制问题和 kubelet 报错。所以必须在 containerd 的配置里把SystemdCgroup设为true对应配置层级大约在[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options]下面。第二个配置是 sandbox_image。这个镜像是每个 Pod 启动时最先拉取的 pause 容器负责为 Pod 创建网络和进程命名空间。不同 Kubernetes 版本对应的 pause 镜像版本不太一样containerd 默认配置里的 sandbox_image 不一定会匹配你当前集群的版本。为了稳妥我建议把它显式设置成你对应版本的 pause 镜像比如 v1.30 通常使用 pause 3.9 或相近版本。显式设置的好处是当网络环境拉不到镜像时你能第一时间知道是哪个镜像出了问题。改完配置后重启 containerd 并确认状态systemctl restart containerd systemctl enable containerd systemctl status containerd如果你用的发行版自带 containerd 安装脚本一般会自动拉起服务。没有的话可以用systemctl start containerd手动启动。2.3 镜像拉取受限时的处理方案如果所在网络环境拉取registry.k8s.io下的官方镜像经常超时可以在 containerd 配置里设置 registry mirror。这不是什么“黑魔法”就是普通的镜像转发配置让 containerd 从一个你能够访问的镜像仓库去拉取原本在远端仓库里的镜像。我实际的做法是在config.toml的[plugins.io.containerd.grpc.v1.cri.registry.mirrors]区域对特定 registry 增加 mirror 地址[plugins.io.containerd.grpc.v1.cri.registry.mirrors] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.registry.k8s.io] endpoint [https://mirror.example.com]注意这里的mirror.example.com只是示意实际要替换成你内网或所在区域可访问的镜像仓库地址。配置完成后同样需要重启 containerd。这个方案我实测下来很稳定比初始化失败后再逐条 pull 镜像要省事得多。3. 用 kubeadm 初始化控制平面3.1 安装 kubeadm、kubelet、kubectl这一步是整个安装过程中最“按部就班”的环节但有一个很容易被忽略的点三个组件的版本必须一致。kubeadm 用来初始化kubectl 用来控制集群kubelet 是每台节点上真正干活的进程如果它们各自版本差太多后续升级和排错都会很痛苦。我习惯先配置 Kubernetes 官方软件源再用包管理器安装指定版本。以 apt 为例主要的逻辑是apt-get update apt-get install -y kubeadm1.30.3-* kubelet1.30.3-* kubectl1.30.3-*这里版本号里的*是因为不同软件源的包名后缀略有差异我会先执行apt-cache policy kubeadm查看可获取的确切版本再填入准确的版本串。强烈建议不要省略版本号直接安装最新否则下次登录服务器时包管理器自动升级集群可能就在你不知情的情况下变得不一致。安装好后执行apt-mark hold锁定版本是个好习惯apt-mark hold kubeadm kubelet kubectl锁定之后只有在你明确决定升级集群时再主动解除锁定这一步能避免很多意外。3.2 执行 kubeadm init初始化之前先检查 containerd 的 socket。默认路径是/run/containerd/containerd.sock如果你的 socket 不在这里初始化命令里必须用--cri-socket明确告诉 kubeadm。控制平面节点初始化命令我通常会写成这样kubeadm init \ --apiserver-advertise-address192.168.1.10 \ --pod-network-cidr10.244.0.0/16 \ --cri-socketunix:///run/containerd/containerd.sock参数解释--apiserver-advertise-address控制平面 API Server 对外广播的地址。通常就是这台主机的内网 IP。如果是单机实验环境这个参数可以省略kubeadm 会自动选择默认网卡 IP但生产环境建议显式指定避免机器多网卡时选错。--pod-network-cidrPod 网段。它必须和后面要部署的网络插件保持一致。我在这里用10.244.0.0/16是因为这个网段在很多网络插件的默认规划里是一致的省得过后还要改插件配置。--cri-socket告诉 kubeadm 使用 containerd 作为运行时。关于镜像仓库如果前面已经为 containerd 配置好了 registry mirror这一步通常不需要额外指定--image-repository。如果你的镜像仓库地址和官方不一致也可以通过这个参数统一替换。初始化过程中kubeadm 会先检查环境然后拉取控制平面组件镜像、生成证书、启动 etcd 和静态 Pod。整个过程会输出很多日志我的习惯是看到Your Kubernetes control-plane has been initialized successfully才算通过。如果中间失败先不要急着重新执行先看错误信息把失败的环节弄明白再说。3.3 配置 kubectl 并部署网络插件初始化成功之后会有一段明显的提示主要是配置 kubectl 的 kubeconfig 文件mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config这几行命令的作用是让当前用户可以用 kubectl 直接访问集群。如果跳过这一步kubectl 会因为没有可用的 kubeconfig 而报错。这个文件很关键它相当于集群的管理员凭证不要提交到代码仓库也不要随意拷贝给其他人。配置好 kubectl 后先查看节点状态kubectl get nodes这时候控制平面节点大概率是 NotReady这是正常的因为还没有部署网络插件。网络插件是 Kubernetes 集群里的“道路系统”没有它Pod 之间、Pod 和节点之间的网络通道就是断的。部署方式通常是kubectl apply -f一个网络插件的部署清单。不同插件的默认 Pod 网段不太一样如果你的初始化参数和我一样使用了10.244.0.0/16那就要选择默认网段匹配的插件或者在插件的配置里把网段改成和--pod-network-cidr一致。部署命令大致是kubectl apply -f 网络插件部署清单.yaml然后等待网络插件相关 Pod 进入 Runningkubectl get pods -n kube-system -w这步之后控制平面节点通常就会变为 Ready。如果还卡在 NotReady不要急着删节点重建先kubectl describe node查看具体原因下面第五节会详细讲。4. 工作节点加入与集群验证4.1 生成加入令牌控制平面初始化输出里会包含一条工作节点的加入命令类似kubeadm join 192.168.1.10:6443 --token token --discovery-token-ca-cert-hash sha256:hash这个 token 默认有效期是 24 小时。如果已经过期不需要重新初始化集群直接用以下命令生成新令牌并打印完整的加入命令kubeadm token create --print-join-command--print-join-command会把 CA 证书 hash 一起生成省得你手动去查。注意kubeadm init时输出的 hash 不会变但如果你不确定就用新生成的方式更稳。4.2 在工作节点上执行加入命令把上面生成的命令复制到工作节点直接执行。同样如果工作节点的 containerd socket 不在默认路径需要在 join 命令后面加上--cri-socketunix:///run/containerd/containerd.sock。执行成功后日志会提示This node has joined the cluster。回到控制平面节点执行kubectl get nodes应该能看到两个节点。新加入的工作节点一开始会是 NotReady等它把 kube-proxy 和网络插件相关的 Pod 拉起来后会自动变成 Ready这个过程通常需要一两分钟。4.3 验证集群是否真正可用节点 Ready 不代表集群就能正常跑业务了我一般还会再跑一个测试 Pod 验证调度和网络。先创建一个简单的 Deploymentkubectl create deployment nginx-test --imagenginx:latest kubectl get pods -o wide确认 Pod 调度到了工作节点并且状态为 Running。然后测试一个更关键的东西Pod 与外部网络的连通性。kubectl run nettest --imagebusybox --restartNever --command -- sleep 3600 kubectl exec -it nettest -- ping -c 3 1.1.1.1如果 ping 不通可能是前面说的net.ipv4.ip_forward没开或者网络插件的问题。这一步能帮你把问题范围快速缩小。再检查节点自身的网络策略。如果有防火墙需要确保 6443、10250、30000-32767 这些端口对集群内通信是放开的。我踩过一次 NodePort 服务无法访问的坑最后发现是云安全组没放行。5. 常见问题与故障排查实录5.1 镜像拉取失败这个问题在安装过程中出现频率很高。表象通常是kubeadm init卡在某个镜像拉取步骤或者kubectl get pods看到 Pod 一直是ImagePullBackOff。我的排查顺序是先从停止的 Pod 看具体事件kubectl describe pod pod-name -n kube-system再用容器运行时命令手动拉取镜像crictl pull registry.k8s.io/pause:3.9如果手动拉取也超时基本可以确定是网络或镜像仓库访问问题需要按 2.3 节的方式配置 containerd 的 registry mirror。如果手动拉取没问题而 kubelet 依然拉不到检查 containerd 配置是否被覆盖或者重启过没有。记住修改 containerd 配置后一定要重启 containerd不然配置不生效这个问题看起来最小实际上最容易反复出现。5.2 kubelet 服务异常kubelet 是节点上最核心的进程它异常时症状很多节点一直 NotReady、kubelet 反复重启、甚至 Pod 无法调度到该节点。先看服务状态systemctl status kubelet journalctl -u kubelet -f常见的 kubelet 启动失败原因swap 没有完全关闭kubelet 启动时报unable to handle swap。解决方法是swapoff -a并注释掉/etc/fstab里的 swap 行。cgroup 驱动不匹配containerd 是cgroupfskubelet 期望systemd。这个在前面配置 containerd 时已经说过这里是最容易暴露的地方。主机名无法解析kubelet 启动失败时会有类似unable to register node的日志。检查/etc/hosts和 DNS。建议在修改任何配置后都执行systemctl daemon-reload systemctl restart kubelet确保 kubelet 读取到最新配置。5.3 节点一直是 NotReady节点状态为 NotReady但 kubelet 本身没有报错这种情况我从经验看大部分是网络插件的问题。先看节点详情kubectl describe node node-name | tail -20如果 Conditions 里NetworkUnavailable是 True说明节点认为网络没有就绪。接下来看网络插件 Pod 的状态kubectl get pods -n kube-system -o wide看到网络插件 Pod 处于 CrashLoopBackOff 或者 Pending优先用kubectl logs看日志。我遇到过一种典型情况Pod 网段和插件默认网段不一致导致插件无法分配子网。解决方法是修改插件配置里的网段让它与--pod-network-cidr一致再重新 apply。还有一次是 sysctl 参数没生效iptables对 bridge 流量的处理没开启导致节点网络一直不通。重新执行sysctl --system并重启网络插件 Pod 后恢复。5.4 加入令牌与证书过期问题集群跑了一段时间后你再想加一个新工作节点会发现kubeadm token create --print-join-command可以生成新命令但证书相关的问题偶尔会出现。当 kubeadm 提示 CA 证书 hash 校验失败时最直接的办法是回到控制平面节点重新生成完整命令kubeadm token create --print-join-command如果出现控制平面证书过期比如 API Server 证书有效期接近一年可以用kubeadm certs check-expiration kubeadm certs renew all更新证书后重启控制平面组件。顺便提醒一句如果你经常搭临时环境可能会觉得证书和令牌很麻烦就想着直接关掉校验我非常不建议这样做。token 和 hash 的作用是防止非授权节点加入集群这是集群安全的第一道门宁可每次多一条命令也不要为了省事埋下隐患。6. 安装后的自检清单与避坑建议6.1 生产环境最小化建议如果是生产环境而不是测试环境我建议在安装完基础集群后再做这样几件事第一把 kubelet 的--node-labels用起来给节点打上角色标签后续可以用节点选择器控制工作负载的调度位置。第二确认控制平面组件使用本地存储还是外部存储etcd 的数据盘大小和性能要仔细评估。第三把所有节点的时间同步配置好时间不同步会导致证书校验和日志时间线各种小问题。第四锁定版本后把自动更新也关闭包括系统层面的自动升级策略避免宿主机某些内核参数意外变化影响集群。对于想在单机环境跑多节点模拟的也可以用 kubeadm 反复创建多个实例但要注意资源冲突。我的经验是最少准备一台 4 核 8GB 的机器否则两个节点上的 Pod 很容易因为资源不足被频繁驱逐。6.2 安装后的自检清单我把每次安装之后顺手要做的检查整理成一张表建议按这个顺序过一遍检查项命令预期结果节点状态kubectl get nodes所有节点 Ready核心组件kubectl get pods -n kube-system所有 Pod Running 或 Completed集群版本kubectl versionClient 和 Server 均为 v1.30.3DNS 解析运行一个 busybox Pod 后用nslookup解析内部服务名能返回 ClusterIP跨节点通信创建 Pod 后访问另一节点的 Pod IP能通NodePort 访问创建一个 Service 并通过节点 IP 加端口访问能通证书状态kubeadm certs check-expiration有效期正常时间同步timedatectl时间已同步这些检查看起来基础但恰恰能覆盖 90% 的集群安装问题。我见过很多团队装了集群后直接开始部署业务结果网络问题在业务层暴露排查成本反而高得多。最后再分享一个小技巧。如果你需要反复搭建多套集群可以把 kubeadm init 的完整参数和 containerd 的最终配置写成一个安装脚本放到内部代码仓库里维护。这样每次新环境只需要改 IP 和主机名就能跑通能省下大量重复排查的时间。我个人在这套安装流程里踩过最多的坑基本都集中在 containerd 的 cgroup 配置和网络插件的网段一致性上把这些提前固化到脚本里后续就顺利多了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询