news 2026/11/5 14:13:15

Kubernetes 1.26.4 集群部署实战:从环境初始化到节点加入的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Kubernetes 1.26.4 集群部署实战:从环境初始化到节点加入的完整指南

1. 环境准备与方案选择

先把话说在前头:Kubernetes 1.26.4 这个版本,不是最新版,但它是一个经过了大量生产环境验证的稳定版本。如果你正在规划内部系统的容器化改造,或者想搭建一套用于学习和测试的集群,1.26.4 是一个很合适的选择。这个版本的 kubeadm 部署流程已经非常成熟,网上资料也足够多,遇到问题基本都能查到解决方案,不会像追新版本那样踩到文档不全的坑。

我这次部署采用的是标准的 kubeadm 方式,没有用任何第三方封装工具。选择 kubeadm 的理由很简单:它是 Kubernetes 官方提供的集群引导工具,部署出来的集群最“干净”,没有额外层层的封装,后续排查问题、升级版本都更可控。而且 kubeadm 的部署逻辑非常清晰——先准备环境,再装容器运行时,然后初始化控制平面,最后加入工作节点——这个流程搞明白了,你对 Kubernetes 集群的架构理解会上升一个台阶。

在开始之前,先说一下我这次的实验环境,方便你对照:

角色主机名配置系统
控制平面节点master014核 8GBUbuntu 22.04 LTS
工作节点1worker014核 8GBUbuntu 22.04 LTS
工作节点2worker024核 8GBUbuntu 22.04 LTS

提示:如果资源有限,可以缩减到 1 台控制平面节点加 1 台工作节点,最低配置建议 2核 2GB,但运行真实负载会比较吃力。生产环境建议 4核 8GB 起步。

操作系统我选了 Ubuntu 22.04,因为它的内核版本(5.15)对容器运行时的兼容性很好,而且 containerd 的安装源在 Ubuntu 上是最省事的。当然 CentOS 7/8、Rocky Linux 也可以,流程大同小异,主要区别在防火墙配置和软件包管理命令上。

整个部署流程预计耗时 30 到 60 分钟,大部分时间花在拉取镜像和等待组件启动上。如果你对 Kubernetes 的基本概念(Pod、Node、Deployment)已经有一定了解,这个部署过程会让你把这些抽象概念具象化——原来所谓的集群,就是一堆组件各司其职,通过 TLS 证书互相通信。

2. 系统基础初始化

系统初始化这部分最容易被忽略,但恰恰是后面出问题最多的地方。我见过太多人在环境没准备好的情况下急匆匆执行 kubeadm init,结果卡在各种奇怪的报错上,最后发现是基础环境的问题。

2.1 主机名与 hosts 解析

每台机器需要设置唯一的主机名,同时要确保集群内的机器能通过主机名互相访问。这步不做好,后面 kubeadm join 的时候会报证书主机名不匹配的错误。

在所有节点上执行:

# 设置主机名(每台机器各自执行对应的) hostnamectl set-hostname master01 # 控制平面节点执行 hostnamectl set-hostname worker01 # 工作节点1执行 hostnamectl set-hostname worker02 # 工作节点2执行 # 所有节点都要配置 hosts 解析 cat >> /etc/hosts <<EOF 192.168.1.10 master01 192.168.1.11 worker01 192.168.1.12 worker02 EOF

注意这里的 IP 地址要换成你自己的实际 IP。我用的网段是 192.168.1.0/24,家庭实验环境比较常见。生产环境如果用到内部 DNS,这里配置 DNS 解析也是一样的效果。

2.2 关闭 Swap 与防火墙策略

Kubernetes 在 1.26 版本中仍然强制要求关闭 Swap。原因有两个:一是 kubelet 的 Pod 内存配额机制依赖 cgroup 控制,如果系统启用 Swap,内存限制可能被绕过;二是调度器在做资源分配决策时,不会把 Swap 计入可用内存,这会导致节点过载的风险。

# 关闭 swap swapoff -a sed -i '/swap/s/^/#/' /etc/fstab # 加载内核模块 cat <<EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter

内核模块这块有个细节:br_netfilter是保证 iptables 规则对 bridge 网络流量生效的关键模块。Kubernetes 集群的 Service 和 Pod 通信大量依赖 iptables/ipvs 规则,如果这个模块没加载,网络策略会静默失效,表现就是跨节点 Pod 通信时通时不通,非常难排查。

继续配置内核参数:

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这个参数是很多人容易漏掉的。Kubernetes 的 Pod 网络需要开启 IP 转发,否则跨节点的数据包会被内核丢弃。你可以用一个简单的方式验证:如果集群内部 DNS 解析正常,但 Pod 无法访问外部网络,大概率就是这个问题。

注意:Ubuntu 默认的 ufw 防火墙如果开着,建议先关闭以免干扰后续的网络配置。云服务器请在安全组放行 6443(API Server)、2379-2380(etcd)、10250(kubelet)等端口。我这里为了实验方便直接ufw disable了。

3. 容器运行时的安装与配置

Kubernetes 从 1.24 版本开始彻底移除了对 Docker 作为默认运行时的支持,但注意,这不影响你使用 containerd —— Docker 底层本来就是用 containerd 来做容器生命周期管理的。所以业界主流的方案是:安装 containerd 作为 Kubernetes 的容器运行时,同时不安装 Docker 全家桶。

3.1 安装 containerd

# 安装依赖 apt-get update apt-get install -y containerd # 生成默认配置文件 mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml

这里有个必须调整的地方:containerd 默认的 cgroup driver 是cgroupfs,而 Kubernetes 推荐使用systemd作为 cgroup driver,因为 systemd 在系统资源管理上更加稳定,能避免双重 cgroup 管理的问题。

编辑/etc/containerd/config.toml,找到下面两处关键配置并修改:

[plugins."io.containerd.grpc.v1.cri"] sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.6" ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true

第一处是sandbox_image,这是 Pod 的网络基础设施容器(pause 容器)的镜像地址。默认配置指向registry.k8s.io/pause:3.6,这个地址在国内网络环境下可能拉取超时,换成阿里云的镜像源会更稳定。这个镜像地址可以根据你自己的网络环境选择,不强制。

第二处是SystemdCgroup = true,这必须改。不改的话,kubelet 健康检查会一直报错,节点显示 NotReady。

修改完后重启 containerd:

systemctl restart containerd systemctl enable containerd systemctl status containerd

3.2 安装 kubeadm、kubelet、kubectl

这三件套的版本必须严格一致,否则会出现兼容性问题。我的做法是直接指定版本安装:

apt-get update apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.26/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.26/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet=1.26.4-00 kubeadm=1.26.4-00 kubectl=1.26.4-00 # 锁定版本,防止意外升级 apt-mark hold kubelet kubeadm kubectl

这里我额外提一句apt-mark hold的作用。Kubernetes 的版本演进非常快,如果哪天不小心执行了apt-get upgrade,三件套可能被自动升级到新版本,导致集群组件版本不一致。锁定版本是个好习惯,我见过不止一次因为这个问题导致的集群故障。

4. 控制平面节点初始化

所有基础环境准备好之后,最关键的一步就是执行kubeadm init。这一步会完成 API Server、etcd、Controller Manager、Scheduler 等控制平面组件的初始化,并生成集群的 TLS 证书和 kubeconfig 配置文件。

4.1 预拉取镜像与初始化参数解析

在正式初始化之前,可以先预拉取需要的镜像,这样初始化过程不会因为拉取镜像超时而中断:

# 查看需要哪些镜像 kubeadm config images list # 预拉取镜像 kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers

--image-repository参数指定了镜像仓库地址。默认的registry.k8s.io在国外,国内网络直连经常超时。替换为国内镜像源是一个稳妥的做法。这个参数在你后面的 kubeadm join 阶段同样需要保持一致。

然后是核心的初始化命令:

kubeadm init \ --apiserver-advertise-address=192.168.1.10 \ --control-plane-endpoint=192.168.1.10 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.26.4 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12

我来逐个解释这些参数:

  • --apiserver-advertise-address指定 API Server 对外通告的 IP 地址,这里填控制平面节点的 IP。
  • --control-plane-endpoint是集群的统一入口地址。单节点部署时直接填 IP 就行,如果是高可用架构,这里填负载均衡器的虚拟 IP 或域名。
  • --pod-network-cidr是 Pod 网络的 CIDR 网段。这个参数必须与后面安装的 CNI 插件要求保持一致。我这里用的 10.244.0.0/16 是 Flannel 的默认网段,如果你要装 Calico,它的默认网段是 192.168.0.0/16,两者不能混用。
  • --service-cidr是 Service 虚拟 IP 的网段,一般保持默认 10.96.0.0/12 即可,这个网段只要不与你的物理网络冲突就行。

4.2 初始化过程与配置

初始化执行后,你会看到一条明确的成功提示:Your Kubernetes control-plane has initialized successfully!。如果卡住了,大概率是镜像拉取问题或者网络问题,可以查看 kubelet 日志定位:

journalctl -u kubelet -f

成功初始化后,按照输出提示配置 kubectl:

mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config

配置好之后可以验证:

kubectl get nodes

这时候你会看到控制平面节点的状态是NotReady。这是正常的,因为还没有装 CNI 网络插件。

同时,初始化输出会给你一条kubeadm join命令,里面包含了一个 bootstrap token 和证书哈希。请一定把这条命令保存下来,后面加入工作节点要用。如果弄丢了也没关系,可以在控制平面节点上用kubeadm token create --print-join-command重新生成。

提示:关于 kubeconfig 文件,admin.conf包含了完整的集群管理员权限,一定要保护好。后续运维工具(比如 Dashboard、kubectl 远程访问)都会用到这个文件。

5. CNI 网络插件安装与节点加入

5.1 安装 Flannel 网络插件

网络插件是 Kubernetes 集群能正常工作的前提。没有 CNI,Pod 无法分配 IP,节点之间也无法通信。我这里选了 Flannel,原因是它足够简单、资源占用低,适合中小规模的集群。

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

如果服务器无法直接访问 GitHub,可以先把这份 YAML 文件下载到本地,然后kubectl apply -f kube-flannel.yml。

等 Flannel 的 Pod 全部启动后,再查看节点状态:

kubectl get nodes kubectl get pods -n kube-flannel

正常情况下,节点状态会在一两分钟内变成Ready。如果长时间处于NotReady,大概率是 Flannel 和 kubelet 的 cgroup driver 配置不一致,或者内核模块没加载。

5.2 工作节点加入集群

工作节点的环境准备和控制平面节点基本一样,需要完成第 2 节和第 3 节的所有步骤。唯一的区别是不需要安装 kubectl(可选),然后在工作节点上执行刚才保存的kubeadm join命令:

kubeadm join 192.168.1.10:6443 \ --token xxxxxx.xxxxx \ --discovery-token-ca-cert-hash sha256:xxxxxx

执行成功后,在控制平面节点上确认:

kubectl get nodes

可以看到所有的节点都变成 Ready 状态。

5.3 验证集群功能

到这里,一个最基础的 Kubernetes 集群已经搭好了。我习惯跑一个完整的测试来确认集群真的在工作:

# 部署一个测试应用 kubectl create deployment nginx --image=nginx:alpine kubectl expose deployment nginx --port=80 --type=NodePort # 查看状态 kubectl get pods -o wide kubectl get svc nginx

如果 Pod 正常运行,Service 也分配到了 NodePort 端口,用浏览器访问http://任意节点IP:NodePort端口,能看到 Nginx 的欢迎页,说明集群完全正常。

6. 部署过程中的典型问题与排查思路

我在部署和维护 Kubernetes 集群的过程中,积累了不少踩坑经验。这里记录几个出现频率最高的问题,你在部署时大概率也会遇到。

6.1 节点一直 NotReady 的排查路径

这是最常见的故障,原因可能有好几种。

先看 kubelet 日志定位:

journalctl -u kubelet -f

常见的报错包括:

  • failed to get sandbox image "registry.aliyuncs.com/google_containers/pause:3.6":说明 pause 镜像拉取失败而没有配置 sandbox_image。检查 containerd 配置文件里的镜像地址是否修改正确。
  • kubelet is misconfigured: kubelet cgroup driver: "systemd" is different from docker cgroup driver: "cgroupfs":说明 containerd 和 kubelet 的 cgroup driver 不一致,回去检查 containerd 配置里 SystemdCgroup 是否已设置为 true。
  • node not found或证书相关的错误:说明初始化时使用的主机名和节点实际主机名不匹配,检查 hosts 配置和 kubeadm init 参数。

6.2 镜像拉取超时问题

国内部署 K8s 集群,镜像拉取超时是最大的拦路虎。除了前面提到的替换镜像仓库外,还有两种情况:

第一种是 containerd 默认使用registry.k8s.io作为 sandbox 镜像地址,如果你的网络环境无法访问,需要在 containerd 配置文件里全局替换。我用的是阿里云的镜像源,这一步在第三部分已经说过。

第二种是当你使用某些私有镜像仓库时,containerd 默认使用 HTTPS 连接。如果你的私有仓库只支持 HTTP,需要在 containerd 配置里添加[plugins."io.containerd.grpc.v1.cri".registry.mirrors."my.registry.com"]的配置,并设置endpoint。

6.3 Token 过期与重新生成

kubeadm 默认生成的 token 有效期是 24 小时。如果你隔了很久才把工作节点加入集群,token 已经失效,执行 join 会报token is invalid的错误。

解决方法是在控制平面节点上重新生成:

# 重新生成 token,默认有效期 24 小时 kubeadm token create --print-join-command # 如果你希望 token 永不过期(需要谨慎使用) kubeadm token create --ttl 0 --print-join-command

同时还需要生成新的 discovery token CA 哈希:

openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

把哈希值拼到 join 命令中,格式为--discovery-token-ca-cert-hash sha256:<哈希值>。

6.4 Pod 跨节点通信异常的排查思路

这类问题的隐蔽性比较强,表面现象是集群状态正常,但 Pod 之间无法通信。我建议按下面的顺序排查:

# 1. 查看 CNI 插件 Pod 是否正常运行 kubectl get pods -n kube-flannel # 2. 检查节点路由表,Flannel 会在每个节点上创建路由 ip route | grep flannel # 3. 检查 iptables 规则是否正常 iptables -L -n | grep FORWARD

一个常见的原因是net.bridge.bridge-nf-call-iptables没有设置为 1,导致 bridge 网络的流量没有经过 iptables 规则过滤。另外,如果某个节点的 Flannel Pod 反复重启,检查节点的 MTU 设置和内核模块,尤其是使用了多网卡或者虚拟化网络时。

7. 升级与维护的扩展思考

集群搭建完成之后,后续的升级维护也是绕不开的话题。这里分享一点我个人的经验和思路。

关于版本升级,Kubernetes 的升级路径是分步走的,不能跳跃:1.26.4 可以升级到 1.26.x 的最新补丁版本,然后按顺序升级到 1.27.x、1.28.x。具体到操作上,先升级 kubeadm 到目标版本,然后执行kubeadm upgrade plan查看升级计划,确认无误后执行kubeadm upgrade apply。这个流程我建议先在测试环境完整走一遍,再上生产。

关于证书续期,控制平面组件的证书有效期是一年。在证书到期前三个月,kubeadm 会给出警告。你可以执行kubeadm certs check-expiration查看各个证书的到期时间。1.26 版本支持证书自动续期,但前提是控制平面组件的证书是由 kubeadm 管理的。如果是手动管理的证书,需要手动处理,时间充裕,不需要焦虑。

关于集群备份,etcd 是整个集群的状态存储,是最关键的备份对象。我建议定期使用etcdctl snapshot save做快照备份。你可以把这个操作写成一个 cron 脚本,每天自动备份,同时在升级前手动做一次完整的快照——这是性价比最高的灾备手段。

最后说一句实战中最深的感受:部署 Kubernetes 集群本身并不难,难的是理解每个组件为什么这样设计、每个参数为什么这样配置。当你真正理解了 kubeadm init 背后做的那些事情,后续不管是排障还是优化,都会从容很多。希望这份指南能帮你顺利搭建起第一套属于自己的 Kubernetes 集群。

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

27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战

一、题目分析题目要求统计二叉树中满足 “节点值等于其所在子树平均值” 的节点数量。子树平均值的计算规则为&#xff1a;子树所有节点值之和 子树节点总数。示例解析以输入 root [4,8,5,0,1,null,6] 为例&#xff1a;节点 4 的子树包含 6 个节点&#xff0c;总和为 24&…

作者头像 李华
网站建设 2026/10/23 13:48:00

QCustomPlot多坐标系实战:轴的绑定、布局与联动避坑指南

简介&#xff1a;面向需要掌握 QCustomPlot 高级绘图能力的 Qt 开发者&#xff0c;这份代码工程围绕多坐标系核心机制展开&#xff0c;完整演示了如何通过 QCPAxisRect 创建多个坐标系、动态添加坐标轴区域、实现共享 X 轴联动&#xff0c;以及利用双击事件切换坐标系颜色。压缩…

作者头像 李华