云选科普

裸机部署 Kubernetes:从主机准备到集群验收

从节点规划、容器运行时和 kubeadm 初始化讲起,梳理裸机 Kubernetes 的部署主线,并补充 CNI、Harbor、证书、etcd 与生产化验收时容易忽略的检查项。

Kubernetes 裸机部署的难点,不是把命令逐条执行一遍,而是先把节点、运行时、网络和故障边界设计清楚。对于学习集群、内网服务或希望掌握底层运维流程的团队,kubeadm 仍然是一条清晰的入口;但生产环境不能简单照搬实验室脚本。

本文把一套从零搭建集群的过程重新整理为“先理解架构,再准备主机,最后初始化和验收”的路径,并重点说明 Docker、CRI、Harbor、Flannel 之间的关系。

先判断:裸机 K8S 适合什么场景

裸机部署适合以下情况:

  • 需要掌握控制平面、节点和容器运行时的工作边界;
  • 有多台云服务器或物理机,希望统一调度服务;
  • 需要自建镜像仓库、网络插件和发布流程;
  • 接受自行处理升级、证书、etcd 备份和节点故障。

如果目标只是快速运行几个网站或微服务,托管 Kubernetes 往往更省运维成本。裸机方案的价值在于可控和可学习,而不是命令更少。

集群架构:先分清控制平面与工作节点

一个 Kubernetes 集群由控制平面和一个或多个工作节点组成。控制平面负责接受声明、保存状态和做调度决策;工作节点负责运行 Pod。常见组件可以按职责理解:

  • API Server:集群资源的统一入口,kubectl、控制器和其他组件都通过它交互;
  • etcd:保存集群状态的键值数据库,磁盘可靠性和备份策略直接影响集群恢复;
  • Scheduler:根据资源、亲和性、污点等条件选择 Pod 的目标节点;
  • Controller Manager:持续比较“期望状态”和“实际状态”,并触发修复;
  • kubelet:运行在每个节点上,负责 Pod 生命周期和节点状态上报;
  • 容器运行时:真正创建和管理容器;
  • kube-proxy:协助实现 Service 的网络转发。

因此,部署前至少要规划三类信息:节点角色、节点间网络、Pod 与 Service 的地址段。地址段不能与办公网、云服务器 VPC 或 VPN 网段重叠,否则网络插件上线后可能出现“节点互通但服务不通”的问题。

主机准备:把不稳定因素提前消除

1. 统一系统和节点信息

所有节点尽量使用相同的 Linux 发行版、内核策略和时间同步方式,并为每台主机设置稳定的主机名。准备好节点清单:

control-plane  192.168.10.10
worker-1       192.168.10.11
worker-2       192.168.10.12

生产环境还应提前规划控制平面高可用、负载均衡入口、etcd 数据盘和备份位置。单控制平面适合实验和小规模内部服务,不应被称为高可用集群。

2. 检查 swap、内核参数和端口

按照所选 Kubernetes 版本的安装文档完成 swap、内核模块、桥接网络和转发参数配置。不要只复制旧教程中的参数:不同发行版的默认值、cgroup 驱动和防火墙策略可能不同。

部署前逐台检查:

hostnamectl
free -h
lsmod | grep -E 'overlay|br_netfilter'
sysctl net.ipv4.ip_forward

同时确认控制平面与工作节点之间的 API Server、kubelet、节点网络插件和 DNS 所需通信没有被安全组或防火墙拦截。云服务器上,安全组规则和操作系统防火墙需要同时检查。

容器运行时:不要把 Docker 等同于 CRI

Kubernetes 通过 CRI(Container Runtime Interface)与容器运行时交互。Docker Engine 本身不直接实现 CRI;如果坚持使用 Docker,需要额外部署 cri-dockerd 并让 kubelet、kubeadm 指向对应的 Unix socket。更直接的路径通常是选择兼容 CRI 的运行时,并统一 kubelet 与运行时的 cgroup driver。

这也是很多旧教程失败的原因:它们把 Docker 安装成功当成 Kubernetes 已经具备运行条件。实际验收应至少包括:

systemctl status <runtime-service>
crictl info
systemctl status kubelet

如果使用 Docker + cri-dockerd,初始化或加入节点时显式指定 CRI socket,避免机器上同时存在多个运行时导致自动探测结果不符合预期。Kubernetes 官方文档也明确说明,Docker Engine 需要通过 cri-dockerd 接入,而不是直接作为 CRI 端点使用。

kubeadm 部署主线:初始化、网络、扩容

1. 安装 kubelet、kubeadm 和 kubectl

三者职责不同:kubeadm 负责创建和加入集群,kubelet 负责节点上的 Pod 生命周期,kubectl 是管理命令行工具。版本应锁定在同一支持范围内,并使用 Kubernetes 官方软件源,不要混用多套仓库。

2. 初始化控制平面

在控制平面执行初始化时,明确 Pod 网段、API Server 地址和 CRI socket。初始化成功后,将管理员 kubeconfig 放到当前用户目录,并立即执行:

kubectl get nodes
kubectl get pods -A

此时节点可能仍显示 NotReady,因为网络插件尚未安装,这是正常的中间状态。不要在网络插件未就绪前急着部署业务。

3. 安装 CNI 网络插件

Flannel 等 CNI 插件负责 Pod 网络连通。安装前确认它使用的 Pod 网段与初始化参数一致;如果两者不一致,常见表现是 CoreDNS 一直无法运行、Pod 跨节点通信失败或 Service 访问异常。

验收时观察:

kubectl get pods -A
kubectl get nodes -o wide
kubectl describe node <node-name>

4. 加入工作节点

使用初始化输出的 kubeadm join 命令加入工作节点。生产环境不要把 join token 长期暴露在工单、聊天记录或脚本仓库中;如果 token 泄露,应重新生成并限制节点间的网络访问。

Harbor 与镜像供应链

自建 Harbor 的意义不只是“存镜像”,还包括版本留存、访问控制、漏洞扫描和内网拉取。建议按环境划分项目,例如 dev、staging 和 prod,并为节点配置可信证书或明确的 TLS 策略。

业务发布前先验证完整链路:开发机推送镜像、Harbor 保存镜像、工作节点拉取镜像、Pod 成功启动。仅在控制平面上 docker pull 成功,不能证明工作节点能够拉取;每类节点都要检查 DNS、证书、凭据和出站网络。

生产化前必须补上的检查

这套部署流程可以作为学习和初始搭建框架,但要进入生产,还需要补齐:

  • 高可用:多个控制平面节点、稳定的 API Server 入口和可靠的 etcd 拓扑;
  • 备份恢复:定期备份 etcd,并在备用环境演练恢复,而不是只保留配置文件;
  • 证书管理:定期检查 kubeadm 证书有效期,明确轮换窗口;
  • 资源与存储:为系统组件预留 CPU、内存和磁盘,规划持久卷及快照;
  • 可观测性:接入日志、指标和告警,至少能定位节点、Pod、网络和镜像四类故障;
  • 升级策略:先在非生产集群验证版本,再按控制平面、节点和应用的顺序滚动升级。

常见故障的排查顺序

遇到 Pod 启动失败时,不要一开始就重装集群。可以按下面的顺序缩小范围:

  1. kubectl describe pod 查看调度、挂载和事件;
  2. kubectl get nodes 确认节点是否 Ready、资源是否耗尽;
  3. 在目标节点查看 kubelet 和运行时日志;
  4. 检查镜像仓库连通性、证书和拉取凭据;
  5. 最后再检查 CNI、Service、DNS 和网络策略。

如果 etcd 报磁盘空间不足,应先检查数据目录、事件历史和备份状态;如果证书过期,则使用对应版本的 kubeadm 工具检查和更新,更新后再验证控制平面组件。把故障处理写成 Runbook,比临时依赖某个管理员的记忆更可靠。

裸机 Kubernetes 的正确打开方式,是把它当成一套分层系统来部署:主机层保证稳定,运行时层提供容器能力,kubeadm 负责集群引导,CNI 负责网络,Harbor 负责镜像供应链,最后再由监控、备份和升级策略把实验集群变成可维护的平台。

继续浏览

还想继续看,可以再看这些文章

适合想继续在同一主题下横向阅读、对比不同切入角度的用户。