news 2026/10/7 2:41:14

kubeadm搭建Kubernetes集群全攻略:从环境配置到排障实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
kubeadm搭建Kubernetes集群全攻略:从环境配置到排障实战

1. 动手前先把账算清楚:版本、发行版与部署方式

1.1 版本选型:为什么我推荐从 1.28+ 起步而不是盲目追新

很多人一看到 K8S 安装就想着"我要装最新版本",这是第一个坑。K8S 社区迭代非常快,每个小版本发布间隔大约三个月,1.36 这类新版本确实带来新特性,但随之而来的是生态组件兼容性问题。容器运行时、网络插件、存储驱动、监控套件的适配往往滞后于核心版本,你装一个刚出两周的最新版,很可能连 Calico 官方都还在适配通道里调试。

我做集群选型时,逻辑很简单:用新不用太新,用稳定不用刚发布。当前阶段,1.28、1.29、1.30 这类已经过了大半年淬炼的版本是稳妥之选,生态里的配套组件基本都完成了适配,社区里踩坑的帖子也攒够了,你碰到任何问题都能搜到解法。热词里提到的 Rocky 安装 K8S 1.36,我建议你装之前先做一件事:打开 K8S 官方变更日志,看看从 1.32 到 1.36 之间有没有移除某些 API 和命令行参数,否则你按旧教程写的配置清单可能直接报错。

还有一个决策点:你是在做生产集群还是学习环境?这个问题直接决定后面的所有选择。如果只是学习、考 CKA、搭一套本地实验环境,我推荐你看 Debian/Ubuntu 系,原因是 apt 源的 kubeadm 全家桶安装体验最顺,网上资料也最多。如果你的服务器跑的是 Rocky/AlmaLinux/CentOS Stream,注意防火墙策略默认是 firewalld,SELinux 默认是 enforcing,这两样东西是新手最容易忽略的"隐形炸弹"。

1.2 kubeadm、二进制还是发行版快照:三种方式的取舍

安装 K8S 集群的主流路径有三条:kubeadm、纯二进制部署、发行版自带的一键式方案(比如 RKE、K3s、MiniKube)。我在不同阶段都折腾过,说下真实感受。

kubeadm 是绝大多数人的最优解,它把控制面组件(kube-apiserver、kube-controller-manager、kube-scheduler)、etcd、kubelet 的初始化逻辑抽象成了一条命令,你不需要手动维护 systemd 单元文件和证书签发流程,但它又保留了足够的透明度——生成的静态 Pod 清单都在 /etc/kubernetes/manifests 下,想改什么直接改 YAML,kubelet 会自己检测并重启容器。

纯二进制部署是把所有组件二进制手动拷到服务器、手写 systemd 文件、手动签证书。这条路我走过一次,过程极其痛苦,大约需要两天时间才能把证书、APIServer 地址、etcd 集群成员全部理顺。它的唯一优势是企业内部极端受限环境下的可定制性,正常人没必要自己造轮子。

发行版快照(RKE2、K3s)是另一个赛道,RKE2 由 Rancher 维护,把 containerd、kubelet、kube-apiserver 等组件打包成一个可执行文件和一套目录结构,一条命令装完,升级也方便。如果你是第一次接触 K8S、希望最短时间看到集群起来,K3s 或者 RKE2 确实香,但它们的目录结构、证书路径和社区原生态有差异,你后续要依赖官方文档排查问题时,有些路径对不上号,容易产生困惑。

我的建议很简单:学习场景无脑 kubeadm,生产场景看团队运维能力——如果团队能维护好 etcd 和证书策略,kubeadm 足够;如果想省心,RKE2 值得考虑。下面所有实操我都按照 kubeadm 标准流程来写,因为它是理解 K8S 集群原理的最佳路径。

2. 环境准备:把地基夯实,后面才不返工

2.1 主机规划与硬件评估

K8S 不是一台机器能扛住的,它的最小集是 3 台节点:1 台控制平面(master)+ 2 台工作节点(worker)。如果你只有两台机器,可以把控制平面和工作负载混跑,但这是测试环境才建议干的省事方案,生产环境绝对不要这样玩——控制平面一旦因为业务流量震荡而 Carpool 失衡,整个集群的调度决策都会受影响。

硬件上的硬性指标,我直接给你一个经过实测的参考值:

节点角色CPU 要求内存要求磁盘要求备注
控制平面2 核起步,推荐 4 核4GB 起步,推荐 8GB系统盘 50GB+所有组件共用一个节点时,内存要求翻倍
工作节点2 核起步2GB 起步(跑业务另算)系统盘 50GB+节点上的 Pod 存储需要额外规划
etcd 节点4 核+8GB+SSD 盘,100GB+如果独立部署,磁盘 IOPS 直接影响集群响应

我这里重点说下内存。kubeadm 默认要求控制平面节点至少 2GB 内存,否则 kubelet 会直接报"memory pressure"甚至初始化失败。我见过太多人在这上面翻车:机器配置只有 1GB,拿过去做练习,kubeadm init 跑一半 kubelet 就挂了。内存不足时根本轮不到看镜像拉取问题,因为容器还没创建就已经 OOM 了。

磁盘方面,建议用 SSD。etcd 是集群的存储底座,它的性能取决于磁盘 fsync 耗时,机械盘在这种高频率写入场景下延迟动辄几百毫秒,K8S 集群会频繁报告 etcd leader election 超时。这个经验不是玄学,是 etcd 官方文档反复强调的硬件要求。

2.2 操作系统基线配置:内核参数、模块与 sysctl

拿到全新服务器后,别急着装 Docker,我的习惯是先做一套统一的基线配置,保证所有节点的内核行为一致。这一步能避免 80% 的后续诡异问题。

首先禁用 swap。K8S 的 kubelet 默认情况下不允许节点使用交换分区,因为 Pod 的内存隔离在 cgroup 层面依赖物理内存控制,一旦 swap 介入,内存回收节奏不可控,Pod 被 OOM Kill 的时机就变得不可预测。执行:

swapoff -a sed -i '/swap/s/^/#/' /etc/fstab

这里要留意,swapoff -a 只对当前会话有效,真正持久化必须改 /etc/fstab 或使用 systemd 挂载单元,否则重启后 swap 又回来了,kubelet 启动直接失败。

然后是内核模块和 sysctl 参数。K8S 的网络方案(无论 Calico 还是 Flannel)都要用到 iptables 和 IPVS,同时容器网络需要转发 IPv4 包,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.bridge.bridge-nf-call-iptables这个参数的作用,是把桥上流经的数据包也交给宿主机的 iptables 规则处理。容器与宿主机之间靠虚拟网桥通信,如果不开启桥接包过滤,Service 的流量转发规则在跨节点访问时会莫名失效。我遇到过一次"Pod 之间能通、Service 访问超时"的诡异故障,最后定位到这个参数没配置。

在 Rocky/AlmaLinux 系系统上,我要特别提醒 SELinux。安装完成后可以用getenforce查看状态,默认一般是 Enforcing。可以临时切到 Permissive 模式跑通流程,但最稳妥的做法是关掉它再装:

sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

完全没有贬低 SELinux 的意思,它在传统服务场景下很安全,但在 K8S 的容器网络命名空间迁移场景下,经常会拦掉一些 Pod 访问行为,排查起来非常费劲。生产严肃使用场景可以基于 SELinux 策略做精细化适配,但那是个大工程,入门阶段直接关掉是投入产出比最高的选择。

2.3 容器运行时:containerd vs Docker 的抉择

K8S 从 1.24 开始移除了对 Docker 的底层运行时支持,移除了 dockershim,但这不代表 Docker 完全不能用了——Docker 会通过 cri-dockerd 这个适配器帮 K8S 调用它的容器接口。可实操下来,没人愿意走这层多余转换,containerd 已经成为事实标准。

containerd 是 Docker 团队拆出来的独立项目,它直接实现了 K8S 需要的 CRI 接口(Container Runtime Interface),不需要适配层,镜像格式跟 Docker 兼容,命令虽然长得不太一样,但核心概念一致。装它的过程在各个发行版上有差异,Debian/Ubuntu 可以直接 apt 安装:

apt install -y containerd

Rocky 系则是:

dnf install -y containerd.io

无论哪种方式,装完之后一定要重写 containerd 的默认配置,因为默认配置里 sandbox 镜像地址(pause 镜像)仍然是 registry.k8s.io 的路径,国内网络环境大概率拉不到。具体做法:先导出默认配置,再改两个关键地方,然后重启:

mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml

编辑 config.toml 文件,找到plugins."io.containerd.grpc.v1.cri".sandbox_image这一行,把registry.k8s.io/pause:3.9改成你本地镜像仓库或镜像加速器里可用的 pause 镜像地址。如果还开启了 systemd cgroup,要把SystemdCgroup = false改成true:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true

这一项很多人漏掉,后果是节点在初始化集群时,kubelet 与 containerd 的 cgroup 驱动不一致,直接报failed to run Kubelet" err="failed to run kubelet"。

3. 核心环节:控制平面初始化与工作节点加入

3.1 kubeadm init 完整实录与参数说明

万事俱备之后,进入关键操作:在控制平面节点执行 kubeadm init。kubeadm 的工作方式是先拉镜像,生成证书,生成加密密钥和 token,然后启动 etcd 和三个控制面组件(apiserver、controller-manager、scheduler)作为静态 Pod,最终给出一段 join 命令。

执行之前先安装 kubeadm、kubelet、kubectl 三件套,注意版本要一致。Debian 系使用 apt 源时需要先把 K8S 的软件源配置到系统:

apt update && apt install -y kubelet kubeadm kubectl apt-mark hold kubelet kubeadm kubectl

apt-mark hold的含义是把这三个包锁住,禁止自动升级。K8S 集群组件版本一旦不一致,集群就会进入不可控状态,所以把版本冻结在源里是必须的。

接着执行初始化:

kubeadm init \ --apiserver-advertise-address=192.168.1.10 \ --pod-network-cidr=10.244.0.0/16 \ --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \ --kubernetes-version v1.28.2

有几个参数挑重点说:

  • --apiserver-advertise-address:指定 apiserver 对外广播的 IP,这个 IP 是节点们和 kubectl 连接的入口。别写成 eth0 上绑定的私有 IP 就开始 self-routing,会造成跨网段访问失败。
  • --pod-network-cidr:Pod 的网段。我选择 10.244.0.0/16,因为这是 Flannel 默认使用的网段,如果你后面换 Calico,可以改用 10.244.0.0/16 或 192.168.0.0/16,总之这个网段不能和你的局域网冲突。
  • --image-repository:指向可用的镜像仓库。K8S 默认仓库是 registry.k8s.io,国内拉取经常超时,这里换成阿里云的公共镜像仓库可以少碰几个坑。
  • --kubernetes-version:必须跟 kubeadm 的实际版本匹配,否则校验阶段就过不去,实际可以省略,kubeadm 默认用当前版本执行。

初始化成功后会给出类似这样的提示,这几行信息非常关键:

Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: ... kubeadm join 192.168.1.10:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxx...

这个输出很容易被忽略,因为人总是盯着屏幕等着最后那句话,但实际上你要先保存好 token 和 CA 散列,一旦窗口关闭,它们不会重新显示。我建议拿到后立刻复制到一个临时文件里。

3.2 节点加入:token、CA 散列与常见重试

工作节点加入集群,本质上是让 kubelet 通过 kubeadm join 这条命令完成三个动作:从 APIServer 获取集群证书信息、向 APIServer 发起注册请求、启动 kubelet 并等待调度。

在每台工作节点上先准备好 containers 运行时(上一节的配置都做完),然后直接执行控制平面输出的 join 命令。如果 token 过期或者你想定制节点角色,也可以自己生成:

# 在控制平面节点生成新的 token kubeadm token create --print-join-command

这里有个容易踩的坑:工作节点上执行 join 前,必须先把主机名、DNS 映射处理好。K8S 会拿节点的主机名去注册节点对象,如果两台机器的主机名相同,第二台节点加入时会直接冲突。我习惯把所有节点的主机名规划成 k8s-master、k8s-node-01、k8s-node-02,并写进 /etc/hosts:

192.168.1.10 k8s-master 192.168.1.11 k8s-node-01 192.168.1.12 k8s-node-02

join 完成之后,回到控制平面节点执行:

kubectl get nodes

正常情况下会看到类似输出:

NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 2m v1.28.2 k8s-node-01 NotReady <none> 35s v1.28.2

这里 STATUS 是 NotReady 很正常,因为集群还没有安装网络插件,Pod 之间的网络通路还没建立,节点心跳也不健康。这是下一个环节要处理的事情。

3.3 网络插件部署:Calico 与 Flannel 的选择

K8S 本身不实现 Pod 间网络互通,它只定义了一个 CNI(Container Network Interface)规范,具体通信用什么方案,是插件的事。安装网络插件是集群进入 Ready 状态的临门一脚,这个环节我踩过不少坑,重点展开说。

Flannel是最轻量的方案,基于 VXLAN 隧道封装,配置简单到一条命令:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

使用 Flannel 时,Pod 网段必须符合它的默认网段10.244.0.0/16,所以我在 init 阶段就把--pod-network-cidr设置成了这个地址。如果你之前顺手填了别的网段,后面 Flannel 的分配规则就会和 kubelet 要求对不上,典型的报错是Failed to create pod sandbox: ... failed to setup network for pod"。

Calico是功能更丰富的选择,支持网络策略、BGP 路由模式,性能比 VXLAN 更好一些,同时它不需要指定固定网段。Calico 的安装方式让新手犯迷糊,官方文档给的是一张清单文件,但里面包含数百个对象,直接 apply 有点不负责任。我的做法是先下载到本地,检查里面的 IP 池配置段:

curl -O https://raw.githubusercontent.com/projectcalico/calico/master/manifests/calico.yaml vim calico.yaml # 搜索 CALICO_IPV4POOL_CIDR

在文件中设置CALICO_IPV4POOL_CIDR为你 init 时声明的网段,然后 apply。Calico 对内核模块有一点额外要求,需要确认__ip_tables等模块存在,在主流发行版内核里一般都带着。

我个人的经验是:如果只是想快速跑通集群,Flannel 是首选;如果是为了生产、需要网络策略精细管控,上 Calico。换网络插件时需要先把原先插件的所有 DaemonSet 和资源清掉,再重新 apply 新的清单,否则网卡上残留的配置会导致 Pod 网络冲突。我一度以为先 apply Calico 再删 Flannel 也没事,结果数据路径全乱了,最后只能把所有节点上的 CNI 配置目录清空重来。

4. 集群落地后的验证与补完

4.1 集群健康检查的几条命脉命令

安装完不等于装好了,一套完整的验收动作是必须的。我的习惯是依次检查三个维度:节点状态、核心组件状态、工作负载实际通信。

第一,节点状态确认:

kubectl get nodes

如果所有节点都是 Ready,第一关过了。

第二,控制面组件状态:

kubectl get pods -n kube-system

named space 一长串 kube-* pod,重点看 coredns 和 kube-proxy。CoreDNS 至少要有两个副本处于 Running 状态,否则集群内 Service 域名解析不可用,你会发现 Pod 内请求对端服务名永远超时。

第三,做一个最朴素的连通性测试:

kubectl run nginx-test --image=nginx kubectl expose pod nginx-test --port=80 --name=nginx-service kubectl get service nginx-service

Service 创建后,在集群内任意节点上用curl http://nginx-service:80试试能否访问。这一步覆盖了 DNS 解析、Service 负载均衡、Pod 网络三层通路。如果通了,说明整个集群的核心数据链路没问题,后面部署业务基本不会因为网络层出怪问题。

很多时候新手在这一步会发现 Service 能创建成功,但 curl 超时,这时十有八九是 kube-proxy 的 iptables 模式与内核参数配合不准。检查这台机器上 iptables 规则是否存在:

iptables -t nat -L -n | grep nginx-service

如果没有任何规则输出,说明 kube-proxy 的准入失败了,典型的诱因是节点上安装了旧版 iptables 或者 kube-proxy 使用的 mode 与主机不匹配。

4.2 存储、负载均衡与应用市场的补全

K8S 集群装好只是起点,真正要让业务跑起来,还需要三样配套:存储方案、负载均衡方案、应用分发方案。

存储方面,从零搭建一套持久化存储可以说是第二个大坑,因为 K8S 的 PVC(PersistentVolumeClaim)不会自动创建存储后端。生产环境通常接云厂商的块存储、NAS,或者自建 NFS、Ceph RBD、Longhorn。作为入门,我建议先接 NFS。NFS 的部署非常简单,在整个集群里找一台机器开启 NFS 服务,然后装一个 nfs-subdir-external-provisioner 组件,让 PV 可以自动按 PVC 动态创建:

helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ helm install nfs-client nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ --set nfs.server=192.168.1.100 \ --set nfs.path=/data/nfs

别看这条命令短,它背后解决的问题是:以后你声明 PVC,不再需要手动建 PV 等管理员来分配存储,provisioner 会自动在 NFS 目录下创建子目录并在集群里匹配 PVC。我接触过的项目里,至少有一半的麻烦来自"PVC 一直 Pending",原因就是存储后端没搭或者 StorageClass 没设置默认。

负载均衡层面,如果你的集群是裸机环境,Service 的 LoadBalancer 类型并不会自动生效——因为它本质上是调用云厂商的 API 来创建云上的负载均衡实例。裸机上这个操作需要额外安装 MetalLB,它用 ARP/BGP 协议把一组 IP 伪装成外部 IP,将 Service 流量引入节点。实现方式:

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.10/config/manifests/metallb-native.yaml

然后声明一个 IP 地址池。这一步在公网环境(比如云服务器)上要特别小心,ARP 广播只能在同一二层网络内生效,跨网段还是得靠真实的负载均衡器。

应用分发方面,现在大家基本都用 Helm 来管理应用清单,把几十个 YAML 打包成一个 Chart,用一条命令部署和升级。K8S 生态里没有 Helm 寸步难行,装 Helm 本身只花三分钟:

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh

后面装 Prometheus、Grafana、Ingress Controller、Nginx,都会用到 helm install 这种形式,省心得多。

4.3 Namespace 与多租户的基础认知

很多新手装好集群后,默认把所有东西一股脑全丢到 default 命名空间,等到有第二个项目进来才发现乱了套。Namespace(命名空间)是 K8S 内置的资源隔离机制,它在集群内部创建出逻辑分区,不同分区里的资源重名也没关系,配合 RBAC 还能做权限隔离。

创建命名空间的常用方式:

kubectl create namespace dev kubectl create namespace prod kubectl create namespace middleware

建议从第一天开始就按环境或者按团队划分命名空间,比如 dev / staging / prod,再叠加 ResourceQuota 限制每个命名空间的 CPU、内存上限,防止某个测试任务把集群资源吃光影响到生产环境:

kubectl apply -f - <<EOF apiVersion: v1 kind: ResourceQuota metadata: name: dev-quota namespace: dev spec: hard: requests.cpu: 10 requests.memory: 16Gi limits.cpu: 20 limits.memory: 32Gi EOF

ResourceQuota 这个对象不设置的话,集群就是一个"公共食堂":谁都能来吃,谁都能吃撑。在共享的测试集群里,一个死循环的 Pod 就能整垮全集群,这也是"集群拥塞器"类问题频发的根源。要限流只有两个手段:节点亲和调度 + 命名空间资源配额。

5. 故障记录与排障速查

5.1 我踩过的坑:镜像拉取、cgroup 不匹配、kubelet 起不来

这里把我这些年碰到的高频问题无保留地列一下,每一条都是真实踩过坑后的总结。

坑一:镜像拉取超时。国内网络环境下,registry.k8s.io 的连接经常处于"超时—重试—超时"的死循环。除了用--image-repository指定阿里云镜像仓库外,还可以预先把需要的镜像从 阿里云同步到本地,再标记成 K8S 期望的镜像名。操作方式如下:

# 先拉镜像并打 tag docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.28.2 docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.28.2 registry.k8s.io/kube-apiserver:v1.28.2 # 所有控制平面镜像都 pull 完 tag 完,再执行 kubeadm init

注意,如果用的容器运行时是 containerd 而不是 Docker,那 ctr 命令也可以做 tag,但更直观的做法是直接把 containerd 的 sandbox_image 配置改成可访问的地址,避免改标签这种笨方法。

坑二:cgroup 驱动不匹配。这是新手期最容易出现的错误之一。kubelet 默认使用 systemd 作为 cgroup 驱动,而 containerd 默认配置可能还是 cgroupfs,两者一对比直接报错。在配置 containerd 时,把 SystemdCgroup 设为 true,同时在 kubelet 的配置里保持默认。检查是否一致可以用一条命令:

kubectl get nodes -o jsonpath='{.items[*].status.conditions}'

坑三:kubelet 起不来,systemctl status kubelet 直接红。这个现象比较普遍,原因是多方面的,但大多数可以归因于节点上没有配置好 kubelet 所需的内核参数、cgroup 驱动不一致或 swap 未关闭。排查套路是:先看 kubelet 日志:

journalctl -u kubelet --since now --reverse

日志一行一行盯着看,大概率能看到ERROR级别的提示,例如failed to run kubelet" err="failed to run kubelet"或者failed to set cgroup。顺着提示改完配置再重启 kubelet。

坑四:节点加入失败,报错信息里有Connection refused。检查控制平面的 APIServer 服务是否正常:kubectl get pods -n kube-system,如果 kube-apiserver 的 Pod 不是 Running,再看看它的日志:

kubectl logs -n kube-system $(kubectl get pods -n kube-system | grep apiserver | awk '{print $1}')

常见原因是 etcd 存储的 PVC 没有挂载好,或者证书失效。

5.2 排障速查表

做一张速查表,方便遇到问题时快速定位。

故障现象可能原因排查命令 / 操作
节点一直 NotReady网络插件未安装;cgroup 不匹配;CNI 配置残留kubectl get pods -n kube-system;清理 /etc/cni/net.d
kubelet 日志报 cgroup 错误containerd SystemdCgroup 未打开修改 config.toml 后重启 containerd
PVC 一直 PendingStorageClass 不存在或默认未设置kubectl get storageclass;确认 provisioner
Service 访问超时kube-proxy 未生效;iptables 规则缺失iptables -t nat -L -n;kubectl get pods -n kube-system
Pod 一直 ContainerCreating镜像拉取失败;存储卷挂载失败kubectl describe pod <pod>看事件
解析 Service 域名失败CoreDNS 异常;集群 DNS 配置错误kubectl get pods -n kube-system;kubectl get configmap -n kube-system
token 过期token 默认有效期 24 小时kubeadm token create --print-join-command重新生成
控制平面 Pod 崩溃循环etcd 磁盘性能差;存储异常kubectl logs -n kube-system <etcd-pod>

这个表没法覆盖所有异常,但能解决 90% 的新手问题。真是剩下那 10%,我的建议还是那句话:要会看日志,kubectl describe 和 logs 是两个最有用的命令,任何一个 Pod 出问题,都先跑这两条,再判断。

5.3 关于集群调度与故障转移的一些认知补充

热词里提到集群调度和集群故障转移,这两块是 K8S 安装后必然会接触到的概念,提前说一下能让你少走弯路。

集群调度就是 kube-scheduler 组件在为新创建的 Pod 选节点,默认的调度策略会考虑节点资源余量、污点容忍、亲和性等。你可以通过给节点打标签、设置亲和性规则、调整资源请求值来影响调度决策。但有一点必须明确:调度不是一个你装上就能自动做好的模块,它需要你用 requests 和 limits 两个字段把应用资源画像描绘清楚,调度器才有数据可算。如果你的 Pod 都没有写 requests,那么调度器只会认为它零开销,于是所有 Pod 全堆在一台机器上,集群负载完全倾斜,这是典型的"集群拥塞"现象,根源还是当初没做好资源规划。

故障转移也是一个常被误解的概念。K8S 默认的故障转移能力其实很有限:节点宕机后,Node Controller 最多等待pod-eviction-timeout(默认 5 分钟)之后,才开始给有状态副本或无主控的 Pod 重新调度。而且并没有"自动把数据迁走"的能力,数据还得靠云盘、分布式块存储做跨节点随挂随用。集群层面要做得更好,可以装 descheduler 来重新平衡负载,可以开 PodDisruptionBudget 来保证业务不中断,但这些都在安装之后,属于集群治理层面的进阶话题,入门阶段能跑通集群、理解基本架构就够了。

写在最后

K8S 集群安装这件事,说难,其实每一步都有模板可循;说不难,中间却藏了太多"状态不一致"的问题。我的经验是,把每个环节的"为什么"想清楚——为什么禁用 swap,因为 kubelet 要精确控制内存;为什么改 SystemdCgroup,因为 kubelet 和 runc 要采用同一套 cgroup 管理方式;为什么 Pod 网段不能跟局域网冲突,因为路由表会打架。把这些逻辑想通了,下次面对一个陌生发行版、一个全新版本时的慌乱就能少大半。

最后再给小建议:装好集群后,务必做一次完整备份,包括 etcd 快照和关键配置文件。K8S 集群最大的噩梦不是装不上去,而是运行到一半数据坏了,没有做事后恢复的方案。我自己的工作流里,每周都会跑一次 etcd 快照脚本,这个习惯救过我至少两次,真心推荐你也养成。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 2:37:39

WeChatMsg 完整上手指南:Mac 微信聊天记录导出 4 种格式 + 年度报告

WeChatMsg 完整上手指南&#xff1a;Mac 微信聊天记录导出 4 种格式 年度报告 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trend…

作者头像 李华
网站建设 2026/10/7 2:36:57

会展经济与管理论文怎么写?2026年热门AI工具推荐⚡这个写会展专业论文的AI工具一定要收藏✨

会展经济与管理专业的毕业论文&#xff0c;写起来比很多同学预想的要复杂。选题要贴合展览策划、节事活动、会议管理、场馆运营等方向&#xff0c;理论框架得从GETS模型、AIPA模型、利益相关者理论、体验经济理论里挑合适的来套&#xff0c;数据收集要涉及参展商满意度调研、观…

作者头像 李华
网站建设 2026/10/7 2:36:37

Ubuntu挂载硬盘全攻略:从lsblk到fstab,解决权限与NTFS问题

能折腾到挂载硬盘这一步的&#xff0c;多半已经不是第一次装Ubuntu了。我见过太多人卡在这一关&#xff1a;系统装好了&#xff0c;数据盘认不出来&#xff0c;插上U盘没反应&#xff0c;重启之后挂载又丢了&#xff0c;fstab写错直接开机进维护模式。这几个场景&#xff0c;基…

作者头像 李华
网站建设 2026/10/7 2:35:35

Codex生态插件怎么选?GitHub万星5款AI编程工具实战对比

最近我把 GitHub 上跟 Codex 生态相关的插件翻了个底朝天&#xff0c;从几十星的小工具到几万星的大项目都试着跑了一遍&#xff0c;这篇直接给你划重点&#xff1a;5 个万星级的 Codex 类插件和周边工具&#xff0c;装完把日常编码体验拉满。所谓“装完拉满”&#xff0c;不是…

作者头像 李华
网站建设 2026/10/7 2:35:34

Codex插件实测:从聊天助手到自动改代码的智能体

最近我把 Codex 新出的插件功能翻来覆去用了两天&#xff0c;用完第一反应不是“哇好强”&#xff0c;而是实实在在有点慌。不是怕失业那种矫情的慌&#xff0c;是发现自己的开发习惯、代码审查流程、甚至整个提 PR 之前的“肌肉记忆”&#xff0c;全都被这个插件按在地上摩擦了…

作者头像 李华