新闻详情

新闻详情

首页 / 资讯中心 / 详情

K8s一键安装实战:高可用集群搭建、排错与上线优化

发布时间:2026/9/28 14:40:32来源:尧图网络
K8s一键安装实战:高可用集群搭建、排错与上线优化
简介一套采用kubeadm实现的Kubernetes v1.18.2自动安装脚本集合面向需要在Linux环境下搭建测试集群的开发者借助环境检查与分步提示机制替代繁杂手动配置用于快速部署并理解k8s运作原理作者明确说明不宜用于生产环境。压缩包共6个文件整体仅10KB内置安装脚本、kubeadm初始化模板、flannel网络配置、环境参数和阅读说明轻量但结构完整。目前已有3105人浏览学习。内置的环境检查会预先判断部署条件是否齐备不满足时提示修正方向让初次接触kubeadm的读者可以按提示逐步推进降低试错成本同时结合yaml配置和文档阅读能够对照掌握master节点初始化、网络插件部署等关键环节形成k8s安装的整体认知。作者也表示程序会持续完善若有疑问可通过私信交流便于后续优化。1. 一键安装 k8s把最容易翻车的初始化环节收进脚本k8s 一键安装听起来像偷懒实际上是把镜像准备、容器运行时、证书签发、CNI 网络、kubeadm 初始化这些容易出错的黑匣子全部收敛成一份配置和一条命令。做过 k8s 集群搭建的人都清楚kubeadm init本身不算难真正把人卡住的往往是镜像拉不下来、cgroup driver 对不上、网络插件网段不一致最后节点一直 NotReady。这个方案能解决部署教程里散落的十几个手动步骤适合刚被初始化流程折腾到怀疑人生的开发者也适合要快速交付多套同等配置集群的运维。前提是你得知道脚本替你做了什么以及它不能替你做什么。2. 从下载到 kubectl get nodes一键安装的最小流程2.1 安装前先做四项系统检查别让脚本背锅一键脚本普遍默认机器已经满足几个基础条件至少 2 核 4G、主机名可解析、swap 已关闭、时间同步正常。这四项里任何一项缺失kubelet 都可能先起来再崩溃最后排查半天才发现是系统层面的问题而不是脚本问题。常见做法是执行脚本的--check预检模式如果脚本没提供自己手动做也很快。uname -a nproc free -h df -h /var/lib/containerd timedatectl set-ntp true swapoff -a sed -i /swap/s/^/#/ /etc/fstab命令逻辑解释uname -a确认内核与架构k8s 对内核版本有底线要求nproc free -h看 CPU 和内存df -h /var/lib/containerd是为镜像和卷预留空间swapoff -a关闭当前会话的 swapsed -i注释/etc/fstab里的 swap 行保证重启后不复活。kubelet 在旧版里对 swap 的态度是直接拒绝启动虽然新版本可以容忍但多数一键安装脚本会在 init 前主动关掉避免在failSwapOn参数上纠缠。主机名检查容易被人忽略。如果机器 hostname 带下划线或者大写字母kubelet 注册节点时可能报错因为节点名要求符合 DNS 规范。常见做法是在安装前把每台机器的 hostname 统一改成小写短横线格式同时保证/etc/hosts里写清楚了本机 IP 与主机名的映射。时间不同步也是隐蔽坑apiserver 签发证书依赖时间校验节点间时间差超过 5 分钟就会出证书校验失败所以timedatectl set-ntp true这行最好每台机器都执行一次。2.2 下载脚本、确认离线包、改一份配置文件下载方式常见有两种直接 clone GitHub 仓库或者从 Release 页下载打包好的部署包再解压。Release 包通常会把所需镜像打成 tar 包一起附上这对离线部署特别有用因为 kubeadm init 阶段镜像能不能及时拉下来直接决定成败。脚本支持加载本地 tar 包的话可以先执行 load 动作再用crictl images确认镜像已经就位而不是等到 init 卡住才回头看日志。进入目录后不要急着执行先找到配置文件。常见文件名是k8s.yml或config.yaml结构大致如下cluster: name: demo mode: multi masters: - 192.168.1.11 - 192.168.1.12 - 192.168.1.13 vip: 192.168.1.10 cri: runtime: containerd cgroup_driver: systemd network: pod_subnet: 10.244.0.0/16 service_subnet: 10.96.0.0/12 plugin: flannel image: repository: pull_policy: ifNotPresent cert: auto_renew: true参数说明mode决定单机还是多 master 高可用生产环境直接用multimasters列表填写各节点内网 IPvip是高可用虚拟 IP单机部署可以忽略。pod_subnet必须和后面选用的网络插件默认网段一致flannel 固定用 10.244.0.0/16calico 常见默认是 192.168.0.0/16这个值一旦交给节点分发后期改要重置集群所以第一次就要选对。service_subnet用 10.96.0.0/12 是主流默认值前提是别跟公司机房网段重叠。image.repository留空表示走默认仓库内网环境改成自己的 registry 前缀。cert.auto_renew决定一年之后证书是否自动续期留 false 的话后面要有自己的兜底方案这个在排错章节还会展开说。配置里的cri.runtime与cgroup_driver务必一起看。如今 containerd 成为主流cgroup driver 推荐随 systemd 保持一致这也是新版 kubeadm 的默认偏好。如果机器上还装着 docker脚本生成的 containerd 配置偶尔会跟 docker 抢 socket这种冲突在踩坑章节第一条会给出处理方式。2.3 执行 init 并观察集群状态配置确认无误后在主节点执行安装./k8s.sh install --config k8s.yml # 脚本会在结束时打印 kubeconfig 路径、join 命令和证书目录 mkdir -p ~/.kube cp /etc/kubernetes/admin.conf ~/.kube/config这期间脚本做的事其实不算神秘生成 kubeadm 配置把image.repository拼到镜像名前缀上预拉关键镜像包括 pause、etcd、apiserver、controller-manager、scheduler、coredns然后执行kubeadm init。这一步耗时最久的是镜像拉取离线包方案能省掉这段时间。看到 init 成功提示不代表集群可用第一验证动作是检查节点和核心组件kubectl get nodes -o wide kubectl get pods -n kube-system -o wide期望结果所有 master 节点状态为 Readykube-system命名空间下 etcd、kube-apiserver、kube-controller-manager、kube-scheduler、coredns 全部 Running。如果 coredns 显示 Pending 或 CrashLoopBackOff基本就是网络插件没生效。多数一键脚本会在 init 之后自动部署 flannel 或 calico但也存在只生成network.plugin字段、把插件部署留给用户手动执行的版本。看到 coredns 崩溃时先检查network.plugin有没有真的填值而不是一上来就查 deployment 怎么做。2.4 脚本的幂等性和失败后的后悔药k8s.sh install二次执行时脚本会检测/etc/kubernetes目录和 kubelet 服务是否存在避免重复 init。但如果第一次执行中断在半路脚本不会自动帮你清残留需要手动做一次 kubeadm 层面的清理kubeadm reset -f rm -rf /etc/kubernetes /var/lib/etcd /var/lib/containerd/* ip link delete cni0 2/dev/null ip link delete flannel.1 2/dev/null这段是 k8s 集群搭建里最常用的后悔药。kubeadm reset -f负责重置 kubelet 和容器运行时状态删除/var/lib/etcd是为了避免旧集群数据影响新集群这个目录在多 master 场景下同时存在于每台 master最后两条删除虚拟网卡是清理网络插件残留flannel 对应flannel.1calico 还可能要删vxlan.calico不确定时先用ip link show看一下有哪些虚拟网卡再动手。一键安装的边界也在这里脚本接手的是标准 kubeadm 流程失败的中间态依然要自己处理。理解这点后面遇到莫名奇妙的报错就不会第一时间怀疑脚本坏了而是回到 kubeadm 和系统残留这个层面来找原因。3. 三台 master 高可用用同一套脚本做 k8s 集群搭建3.1 为什么三台 master 是生产的最小配置生产环境不会拿单机集群对外提供服务这不是高可用问题而是入口单点问题。kube-apiserver 是集群所有请求的入口worker 节点、kubectl、控制器都要绕不开它。apiserver 挂了整个集群对外表现为失联后面 pod 该跑还是跑但你什么都做不了。多 master 架构里有个绕不开的概念etcd 的多数派协议。etcd 按 raft 算法选主写入必须获得多数节点确认。三台 master 对应三份 etcd 副本允许挂一台还能继续选主两台的话一旦一台宕机剩下的一台永远凑不够多数派集群等于锁死。所以三台不是锦上添花是 etcd 机制倒逼出来的最小生产规模。如果你所在团队只有一台物理机能跑 master那不如不要用多 master而是在 apiserver 前面加一个外部负载均衡把后端暂时指向单台 master后续再扩容节点。3.2 内置 vip 方案还是外部负载均衡一键脚本在mode: multi下的常见做法是内置 keepalived 加 HAProxy 组成虚拟 IP。三台 master 上同时跑 HAProxy 监听 6443keepalived 负责把 VIP 绑定到其中一台 master。当前这一台宕机时VIP 会漂移到另一台对外还是同一个地址worker 和 kubectl 不用改任何配置。配置里vip: 192.168.1.10对应这套机制。这个 IP 必须是空闲地址不能和任何物理机或已有服务冲突。HAProxy 的配置一般由脚本自动生成backend 指向三台 master 的真实 IP:6443健康检查用 tcp 方式探测端口。启用后可以手动验证漂移ip addr show | grep 192.168.1.10 # 找到当前持有 VIP 的节点 # 在该节点上执行 systemctl stop haproxyVIP 应在几秒内漂移到其他节点另一种主流做法是外部负载均衡比如机房已有的 F5、nginx stream、云平台的负载均衡实例。使用这种模式时脚本配置里lb可以选 external 云 LB 形态vip字段直接填 LB 的访问地址。kubekey 这类部署工具也是这样本质都是把 kubeadm 的control-plane-endpoint指向一个永远可达的地址同时 apiserver 证书 SAN 里必须包含这个地址否则客户端校验证书会失败。脚本通常会把这个 SAN 自动加进 kubeadm 配置但如果你是自己手写 kubeadm 配置这条非常容易漏。3.3 worker 节点加入与 token 过期处理master 初始化完成后脚本会生成 worker 加入命令。常见形式是./k8s.sh join --token token --control-plane-address 192.168.1.10:6443 --node-type worker # token 默认 24 小时过期过期后在主节点重新生成 kubeadm token create --print-join-command--control-plane-address必须填 VIP 或外部 LB不能填某一台 master 的真实内网 IP。如果填了真实 IPworker 入集群后只会连向这一台 masterVIP 一旦漂移worker 到 apiserver 的链路就断了高可用也就名存实亡。token 过期是另外一个常见问题在 worker 节点上看到 unauthorized 报错时不用怀疑其他配置先回到主节点用kubeadm token create --print-join-command拿到新命令再重试。3.4 高可用装完必须做的两个验证第一把kubectl的 kubeconfig 里 server 地址改成 VIP执行kubectl get nodes确认能正常读到节点列表。第二找到当前持有 VIP 的 master直接重启这台机器然后反复执行kubectl get nodes观察中断情况。这两个动作验证的是同一件事高可用是不是只存在于配置里。脚本能帮你搭建架构但 VIP 漂移是否成功只能靠真实故障模拟来验证。生产环境里最怕的是自以为高可用半夜 master 宕机才发现 VIP 根本没漂移过去。提前做一次重启测试把这个问题留在白天解决是每个运维值得养成的习惯。4. 一键安装避坑5 条常见报错与排错记录4.1 kubelet 报 container runtime is down现象安装脚本跑完kubectl get nodes里 master 一直 NotReadyjournalctl -u kubelet连续滚 container runtime is down。原因系统里原本装过 dockerdocker 或 containerd 的 socket 冲突导致 kubelet 连不上正常 CRI。脚本默认用 containerd旧 docker 的containerd.sock路径与新配置不一致或者 containerd 状态目录里有旧数据。解决先停掉 docker 及其相关服务清掉 containerd 状态目录再重启 containerdsystemctl stop docker containerd systemctl disable docker rm -rf /var/lib/containerd systemctl start containerd提示如果你选择用 docker 作为 CRI反过来检查cgroup_driver是否和 kubelet 保持一致systemd 与 cgroupfs 不一致时 kubelet 会直接报 failed to run Kubelet排查方向完全不同。4.2 coredns 一直 CrashLoopBackOff现象master 节点正常 Ready但 kube-system 里的 coredns 反复重启pod 日志里看到 no servers found。原因网络插件没生效pod 网络没起来。最常见的直接原因是pod_subnet与网络插件默认网段不一致flannel 默认 10.244.0.0/16calico 默认 192.168.0.0/16配置文件里填了插件的网段配不上CNI 插件分发的网段没有落到 pod。解决把配置里network.pod_subnet改成网络插件的默认网段然后必须重置集群重新 init。这个参数一旦经过 kubeadm 下发到节点几乎不可能热改生效最快路径就是kubeadm reset再跑一遍 install。另外检查/etc/cni/net.d/下是不是只有一份 CNI 配置残留两份配置会导致网络插件互相覆盖。4.3 VIP 访问间歇性超时现象三台 master 高可用部署成功访问 VIP 时有时秒回有时卡到超时kubectl偶发 TLS 握手失败。原因HAProxy 健康检查没有正确指向三台 master 的 6443 端口或 keepalived 漂移后 kubeconfig 里的 server 地址没有用 VIP。解决先确认 HAProxy 配置里 backend 部分是否包含了三台 masterecho | openssl s_client -connect 192.168.1.10:6443 2/dev/null | openssl x509 -noout -text | grep -A1 Subject Alternative Name这条命令检查 apiserver 证书 SAN 里是否包含 VIP 地址。如果输出里只有各节点 IP没有 192.168.1.10说明脚本生成证书时漏了 SAN需要重新生成证书或修改 kubeadm 配置里的controlPlaneEndpoint。另外查看journalctl -u keepalived是否持续刷 state transitionVIP 反复漂移也容易造成连接不稳定。4.4 证书过期kubectl 直接报 expired现象部署满一年后访问集群报x509: certificate has expired or is not yet valid。原因kubeadm 签发的证书有效期默认一年很多一键安装脚本并没有真正实现自动续期只是配置文件里留了auto_renew字段。解决在主节点手动续期所有证书再重启 kubeletkubeadm certs renew all systemctl restart kubelet cp /etc/kubernetes/admin.conf ~/.kube/config关键点在于admin.conf里的客户端证书也参与续期所以 renew 之后必须同步 kubeconfig否则 kubectl 还是拿着旧证书去访问集群。长期维护的集群我更建议把这条写进定时任务每月跑一次过期前就续好比事后救火省心。4.5 镜像拉取一直卡住或超时现象init 阶段卡在 pulling image 超过十分钟网络正常但镜像迟迟拉不下来。原因默认镜像仓库在内网或部分地域访问不稳定或者机器 DNS 解析异常。这不一定是脚本问题更多是网络环境与默认仓库之间的连通性差异。解决在配置文件的image.repository里填内网镜像仓库地址或在 containerd 配置里调整 mirror。如果脚本已经执行过半照旧先kubeadm reset清干净再重新 init。离线包方案在这里最有效Release 包里携带镜像 tar 时优先用脚本的 load 能力提前导入避免安装时依赖公网仓库。镜像能不能拉下来是一键安装里最不可控的一环脚本只能帮你把流程串起来解决不了网络根源问题提前准备好镜像仓库才是正道。5. 进阶配置从能跑到敢上线的几处调整5.1 内网镜像仓库定制与离线安装一键安装能跑通是最低标准生产环境第一件事往往是改镜像仓库。配置里image.repository留空时kubeadm 会从默认地址拉取镜像。内网环境里这既慢又不安全更常见的是公司自建一套 registry把所需镜像全部提前镜像进去然后配置里这样改image: repository: registry.example.local:5000/k8s改完记得在每台节点上确认 containerd 能访问这个仓库。containerd 的镜像仓库认证配置在/etc/containerd/certs.d/或config.toml的 mirrors 段如果 registry 用了自签名证书还要把 CA 证书放到 containerd 信任目录里否则 init 时一样拉取失败。离线部署更彻底的做法是用 Release 包自带的镜像 tar先解压再 load 进 containerd之后再执行 installinstall 期间完全不依赖外网。5.2 证书自动续期把兜底做成定时任务上一章的证书过期问题值得专门做成一个机制。不少脚本的auto_renew只是配置项实际没实现定时续期所以不要相信字段要在部署后主动验证。验证方式很简单看系统里有没有生成相关的 systemd timer 或 cron 任务。没有的话就自己补一个每月执行一次kubeadm certs renew all /var/log/k8s-cert-renew.log 21 systemctl restart kubelet cp /etc/kubernetes/admin.conf ~/.kube/config这条命令和手动续期完全一致放到 cron 里就是兜底。续期之后如果 kubeconfig 没有同步kubectl 依然会报证书过期所以把cp放进同一个任务里。这里踩过的重坑是只 renew 不重启 kubelet证书文件换了进程还拿着旧证书现象和没续一样。记住顺序renew、restart、copy kubeconfig三步缺一不可。5.3 flannel 换 calico 的正确姿势默认 flannel 简单、部署快、无 BGP适合大多数场景。但需要 NetworkPolicy 做网络策略、或者要跨子网精细路由时calico 是更合适的选择。切换网络插件最稳妥的方式是重新搭一套集群而不是在原集群上热替换。如果环境不允许重装也能做但要注意残留清理kubectl delete -f flannel.yaml rm -rf /etc/cni/net.d/* ip link delete flannel.1 kubectl apply -f calico.yaml顺序上必须先删 flannel 再删虚拟网卡最后 apply calico。常见翻车是删了 flannel 配置但没有清理flannel.1虚拟网卡calico 起来后路由表和 CNI 配置对不上coredns 又开始 CrashLoopBackOff。切换完成后观察 coredns 和 kube-proxy 是否恢复正常同时用跑一个跨节点的 pod 验证网络连通性。calico 默认网段是 192.168.0.0/16如果配置里 pod_subnet 还是 flannel 的 10.244.0.0/16需要同步改掉。5.4 上线前必调的参数速查参数影响默认值推荐值pod_subnetpod 网段必须与 CNI 默认网段一致flannel10.244.0.0/16calico192.168.0.0/16service_subnetservice 虚拟 IP 段10.96.0.0/12避开机房网段cgroup_driverkubelet 与容器运行时一致性systemd新版 containerd 推荐cert_auto_renew证书过期修复策略false 时务必自建定时续期coredns.replicasDNS 服务可用性生产 2~3 副本配合反亲和这五组参数里前四组在 init 前定下来改起来成本最高最后一组可以在集群运行后用 deployment 滚动更新方式调整。给 coredns 多放两个副本能明显改善集群 DNS 的抖动问题这个在排障时最容易被忽略。6. 装完不等于能用三步验收 k8s 集群跑完一键安装最后要做的不是看脚本输出里的一堆 success而是自己做一次真实链路验证。第一步看节点和核心组件状态第二步起一个实际负载第三步模拟一次跨节点访问。kubectl get nodes kubectl get pods -n kube-system kubectl create deployment smoke-test --imagenginx --replicas2 kubectl expose deployment smoke-test --typeNodePort --port80 curl node-ip:node-portcurl 通了说明 CNI、kube-proxy、调度器、kubelet 整条链路都是活的。如果这一步失败先看 kube-proxy 日志常见的坑是 node-port 端口被防火墙拦截或者 kube-proxy 的 iptables 模式与服务器内核不匹配。我养成的最后一个习惯是每次安装完立刻把 init 日志归档。脚本输出的每一行警告都值得保留集群三个月后出问题时回看这些日志往往比在当时盯着更容易发现伏笔。k8s 集群搭建里很多所谓的玄学问题几乎都能在当年安装日志里找到答案。希望这个方向能帮你的 k8s 集群搭建变成可复现、可回滚、可排查的例行工作而不是每次从零开始的冒险。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Windows 11下ML307C OpenCPU开发环境搭建实战全记录 2026/9/28 17:08:16

Windows 11下ML307C OpenCPU开发环境搭建实战全记录

ML307C 这个模组,圈里搞物联网的老哥应该不陌生:中移物联 OneMO 品牌下很能打的一款 Cat.1 模组。但如果你跟我一样,手里只有一台 Windows 11 电脑,又想把 OpenCPU 开发环境跑起来,那感受就是两个字——折腾。官网文档…

阅读更多 →
CLI-Anything:面向Agent-Native的本地化智能命令行框架 2026/9/28 17:08:16

CLI-Anything:面向Agent-Native的本地化智能命令行框架

1. 项目概述:这不是又一个命令行工具,而是一次CLI范式的重新定义“CLI-Anything”这个名字乍看有点狂,但当你真正用上它,就会明白——它不是在给命令行加功能,是在给命令行装大脑。它不依赖特定语言、不绑定某个云平台…

阅读更多 →
CLI-Anything:把一切日常任务变成命令行指令的工程化实践 2026/9/28 17:08:16

CLI-Anything:把一切日常任务变成命令行指令的工程化实践

1. 项目概述:CLI-Anything 到底是什么先说结论:CLI-Anything 不是某个具体软件,而是一套“把一切日常任务都变成命令行指令”的工程化思路和工具链集合。这几年我一直在做终端自动化相关的工作,陆陆续续折腾过各种效率工具&#x…

阅读更多 →
Model-Optimizer实战:0.8GB模型压至85MB的量化压缩全攻略 2026/9/28 17:08:09

Model-Optimizer实战:0.8GB模型压至85MB的量化压缩全攻略

Model-Optimizer,一个让我从 0.8GB 压到 85MB 的模型压缩工具箱这事儿得从去年年底说起。我手上有一个客户端的视觉检测模型,原始权重 0.8GB,跑在边缘设备上又卡又烫,用户反馈加载要等半天。领导丢给我一句话:优化一下…

阅读更多 →
Substrate区块链开发实战:从模块化架构到无分叉升级 2026/9/28 17:08:09

Substrate区块链开发实战:从模块化架构到无分叉升级

如果你问一个在区块链开发圈里泡了几年的老开发,现在想自己动手做一条链,最该从什么地方下手,我的答案通常会很快落在Substrate上。不是因为它名字好听,而是因为这个框架把区块链开发里最烧时间的那几块——P2P网络、区块存储、共…

阅读更多 →
C语言中~和!的区别:按位取反与逻辑非的深度解析 2026/9/28 17:08:09

C语言中~和!的区别:按位取反与逻辑非的深度解析

1. 内容整体设计与思路拆解1.1 为什么要把这两个操作符放到一起讲标题里把~和!放在一起对比,不是随手凑对。我最早学C语言的时候,也一度觉得这俩都叫"取反",应该差不多。直到有次在项目里用~去判断一个标志位,调试了一下…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉