简介:本文系统梳理Kubernetes集群的主流部署方案,从单机开发环境到生产级高可用架构,涵盖kubeadm、二进制部署、托管容器服务等路径的选型逻辑与适用场景。同时深入剖析节点NotReady这一高频故障的根因排序、排查流程与kubelet驱逐阈值配置,帮助读者在方案设计与日常运维中兼顾部署效率与集群稳定性。
在容器化应用落地的过程中,集群如何部署往往是第一个需要决策的问题。部署方案的选择不仅影响初期的搭建效率,更决定了后续的运维复杂度、故障恢复能力和横向扩展空间。本文从部署形态、架构要素与典型故障处置三个维度,对主流部署方案进行系统梳理,并给出可落地的实践建议。
讨论”有哪些方案”之前,先明确分类的维度,否则容易陷入工具名称的罗列。通常可以从以下几个角度划分:
不同的组合对应不同的适用场景。下面按从轻到重的顺序展开。
开发者在本地快速验证编排能力时,通常不需要完整的多节点集群。此类方案的特点是安装快、资源占用低,但控制面与工作负载共享同一台机器,不具备高可用能力。
常见的实现路径包括在单机上运行轻量发行版,或使用容器内运行集群组件的方式。这类方案的核心价值在于降低学习门槛,让开发者能在几分钟内获得一个可用的 API Server 与调度器。需要注意的是,单机方案中的网络插件、存储插件往往做了简化,与生产环境的差异较大,不适合直接作为上线前的验证环境。
适用场景:本地开发、CI 中的集成测试、教学演示。
不适用场景:性能压测、多节点调度策略验证、高可用演练。
当需要一套多节点集群时,使用安装工具引导是最常见的方式。这类工具负责证书生成、组件配置下发、网络插件安装等繁琐步骤,将部署过程收敛为若干条命令。
以业界普遍采用的方式为例,流程大致分为:环境预检、初始化第一个控制面节点、加入其余控制面节点、加入工作节点、安装网络与存储插件。
# 初始化控制面(示意)kubeadm init --control-plane-endpoint "<lb-endpoint>:6443" \--pod-network-cidr=10.244.0.0/16# 工作节点加入集群(示意)kubeadm join "<lb-endpoint>:6443" --token <token> \--discovery-token-ca-cert-hash sha256:<hash>
引导式方案的优势在于标准化程度高、升级路径清晰。多数工具支持 plan 之类的预检子命令,能在真正变更前暴露版本偏差、端口占用、内核参数缺失等问题。
多控制面节点必须解决两个问题:API Server 的访问入口统一,以及数据面的一致性。
另一条路径是逐组件部署:分别安装 API Server、调度器、控制器管理器、kubelet 与容器运行时,自行编写服务单元与配置文件。这种方式对细节的掌控最强,便于针对特定内核版本、安全基线或离线环境做定制,但代价是运维成本高、升级需人工介入、出错面广。
适用场景:对组件版本、启动参数有强定制需求,或有严格合规审计要求的环境。对多数团队而言,引导式方案的投入产出比更优。
托管方案将控制面组件的运维责任转移给云平台,用户只需创建节点池并提交工作负载。其优势体现在:
需要权衡的是:控制面的可定制参数相对受限,部分高级调度特性或准入控制策略的调整空间较小;跨云或混合云场景下还需考虑网络打通与一致性管理。
选型时可从三个问题入手:团队是否具备控制面运维能力?业务对控制面参数定制的需求有多强?是否存在跨环境统一管理的诉求?
无论选择哪种方案,集群上线后都会面对同一类问题——节点状态异常。其中”节点变为 NotReady、其上工作负载被驱逐”是发生率最高的故障之一,值得在方案设计阶段就把预防措施配好。
典型现象是某个工作节点状态突然变为 NotReady,其上的 Pod 陆续出现 Evicted 或被重新调度到其他节点,业务出现短时抖动。触发机制是 kubelet 未能 在约定时间内向 API Server 上报心跳,节点被判定为不可用。
实际根因按出现频率大致排序如下:
| 根因 | 占比特征 | 识别线索 |
|---|---|---|
| 节点磁盘耗尽 | 最常见 | 镜像目录或日志目录所在分区写满 |
| kubelet 进程被 OOM 杀死 | 常见 | 内核日志中存在 OOM 记录 |
| 节点与 API Server 网络不通 | 偶发 | 健康检查端点无法访问 |
| kubelet 进程崩溃 | 较少 | 服务状态显示 failed |
登录问题节点后建议按以下顺序推进,先排除高频项:
# 第一步:服务状态与近期日志systemctl status kubeletjournalctl -u kubelet --since "1 hour ago" | tail -200# 第二步:磁盘使用率(最高频根因)df -hdu -sh /var/lib/containerd # 镜像与容器层du -sh /var/lib/kubelet # Pod 数据du -sh /var/log # 系统日志# 磁盘满时的清理动作crictl rmi --prune # 清理悬空镜像crictl rm $(crictl ps -a -q --state exited) 2>/dev/null # 清理已退出容器# 第三步:内存与 OOM 记录free -hdmesg | grep -i "oom" | tail -20# 第四步:到 API Server 的连通性curl -k https://<apiserver-ip>:6443/healthz# 根因处理完毕后重启 kubeletsystemctl restart kubelet
排查顺序的设计逻辑是:磁盘问题占比最高且清理动作相对安全,优先处理;内存与网络问题需要更多判断,放在其后;进程崩溃通常有明确日志,易于定位。
与其等节点彻底不可用再介入,不如让 kubelet 在资源紧张时主动驱逐部分 Pod,保留节点本身的可用性。这通过驱逐阈值配置实现:
# /var/lib/kubelet/config.yamlevictionHard:memory.available: "200Mi" # 可用内存低于阈值开始驱逐nodefs.available: "10%" # 节点文件系统剩余不足时驱逐nodefs.inodesFree: "5%" # inode 剩余不足时驱逐imagefs.available: "15%" # 镜像存储剩余不足时驱逐
几个配置要点:
综合来看,部署方案的决策可以归纳为一条渐进路径:
部署方案没有绝对优劣,关键在于与团队能力、业务规模和运维预算相匹配。把故障预防配置前置到部署阶段,往往比事后排查更能体现方案设计的成熟度。