kubeasz 混合架构集群部署实战:在 amd64 集群中平滑加入 arm64 节点
【免费下载链接】kubeasz使用Ansible脚本安装K8S集群,介绍组件交互原理,方便直接,不受国内网络环境影响项目地址: https://gitcode.com/GitHub_Trending/ku/kubeasz
混合架构(amd64 + arm64)集群是指同一 Kubernetes 集群中同时存在 Linux amd64 架构与 Linux arm64 架构的机器,常用于信创适配、ARM 服务器资源池纳入、异构算力统一调度等场景。kubeasz 自 3.4.1 起原生支持多 CPU 架构安装,但暂不支持自动部署混合架构集群,本文基于 kubeasz 官方混合架构说明,完整演示「先部署 amd64 集群,再用独立 arm64 部署机补充 arm64 节点」的手动操作流程,并结合 ezdown / ezctl / playbooks 源码剖析其底层原理,帮助读者理解为什么这样操作可行、以及每一步背后的机制。
1. 背景:kubeasz 的多架构支持机制
在动手之前,先理解 kubeasz 的多架构逻辑,这直接决定了混合架构部署的操作思路。
kubeasz 的多架构安装逻辑是:根据部署机器(执行 ezdown/ezctl 命令的机器)的架构,自动判断下载对应 amd64/arm64 的二进制文件和容器镜像,然后推送安装到整个集群。详见 多架构支持说明。
这一逻辑在 ezdown 脚本中有多处体现:
- 脚本通过
ARCH=$(uname -m)获取本机架构(ezdown),docker 二进制下载 URL 中携带${ARCH}变量(x86_64 / aarch64),自动拉取匹配架构的 docker-ce 静态包; - Kubernetes 核心二进制(kube-apiserver/kubelet/kube-proxy 等)通过
easzlab/kubeasz-k8s-bin多架构镜像拉取:docker run --rm -v "$BASE/bin":/tmp/out easzlab/kubeasz-k8s-bin:"$K8S_BIN_VER" sh -c "cp -f /k8s/* /tmp/out/"(ezdown),docker 会自动为当前架构选择对应层; - 额外二进制(etcdctl 等)通过
easzlab/kubeasz-ext-bin多架构镜像拉取(ezdown); - 默认容器镜像(calico、coredns、metrics-server、pause 等)与可选镜像(
ezdown -X)均为多架构镜像,按当前架构拉取; - Harbor 离线包则显式区分架构:aarch64 机器拉取
easzlab/harbor-offline:${HARBOR_VER}-aarch64(ezdown)。
由此可以推断出关键结论:/etc/kubeasz/bin与/etc/kubeasz/down这两个目录中的二进制和镜像文件是「架构相关」的,而 kubeasz 的代码、roles、playbooks、配置模板是「架构无关」的。这正是混合架构部署思路的基石——部署机与目标节点必须是同一架构,二进制才能正确推送执行。
因此混合架构的部署思路很朴素:
- 用一台 amd64 机器作为「amd64 部署机」,先部署出 amd64 三节点集群;
- 再用一台 arm64 机器作为「arm64 部署机」,复制 amd64 部署机上的 kubeasz 代码(排除架构相关的 bin 与 down 目录),在该机上重新下载 arm64 架构的二进制与镜像,随后使用
ezctl add-node把 arm64 节点加入既有集群。
注意:官方明确指出当前暂不支持自动部署混合架构集群,本文方案为手动操作,实际执行需评估风险。另外Harbor 目前仅支持 amd64 安装,混合架构集群中如需私有镜像仓库,需注意这一限制(详见 多架构支持说明)。
2. 部署前置条件与风险提示
开始前请确认以下前提:
- 已有一个正常运行的三节点 amd64 集群(本文以 master×1 + node×2 为例,实际规模不限);
- 准备一台arm64 架构的 Linux 机器(与待加入的 arm64 节点同架构,推荐系统版本与集群节点一致),内存/磁盘满足 kubeasz 运行要求(参考 快速指南,单机建议 4G 内存、30G 磁盘以上);
- 所有节点(包括待新增的 arm64 节点)之间SSH 免密互通,部署机可免密登录全部节点;
- 集群版本以实际部署为准(文档示例验证输出为 v1.33.1 / containerd://2.1.1,当前仓库 ezdown 默认 K8S_BIN_VER 为 v1.36.2,见 ezdown)。
风险提示:混合架构集群在生产环境涉及调度策略、镜像多架构可用性、节点污点与标签管理等问题;且 kubeasz 的 add-node 流程会直接修改集群清单文件并执行 ansible 安装,操作前建议做好 etcd 快照备份(可用ezctl backup default)。
3. 操作步骤详解
步骤一:在 amd64 部署机上准备可移植的 kubeasz 目录
登录 amd64 部署机(即当初部署 amd64 集群的那台机器),把架构相关的bin和down子目录移出,再将整个/etc/kubeasz复制到 arm64 部署机:
# 登录amd64部署机 cd /etc/kubeasz; mv bin down /tmp/; scp -r /etc/kubeasz root@{_ip_arm64}:/etc/ # 复制完成后找回 bin 和 down 子目录 mv /tmp/bin /etc/kubeasz/; mv /tmp/down /etc/kubeasz/要点说明:
bin目录存放 kubelet/kube-proxy/etcd/docker/cni 等已编译好的架构相关二进制;down目录存放架构相关的离线镜像 tar 包。它们不能被复制到 arm64 机器直接使用,否则会因 ELF 架构不匹配而无法执行(例如 x86_64 的 kubelet 无法在 aarch64 上运行);- 除这两个目录外,
/etc/kubeasz下的 roles、playbooks、clusters(含 default 集群清单与证书)、模板均为跨架构通用文件; - 复制完成后必须立刻把
bin、down移回原位,不影响 amd64 部署机继续使用。
步骤二:在 arm64 部署机上重新下载二进制与镜像
登录 arm64 部署机,进入/etc/kubeasz,执行与全新安装相同的下载流程(此时uname -m返回 aarch64,ezdown 会自动按 arm64 架构下载):
cd /etc/kubeasz # 下载基础部分(kubeasz代码/二进制/docker/默认镜像等) ./ezdown -D # 下载额外部分(如有,按需填写,如 dashboard/prometheus 等) ./ezdown -X ... # 运行部署容器 ./ezdown -S各命令含义(完整参数可用./ezdown查看,ezdown):
| 参数 | 作用 |
|---|---|
-D | 下载默认二进制与镜像到/etc/kubeasz(含 docker、kubeasz 容器镜像、k8s/ext 二进制、默认组件镜像),并启动本地私有仓库easzlab.io.local:5000(ezdown) |
-P <OS> | 下载对应操作系统的离线系统包(如-P ubuntu_22) |
-R | 下载 Harbor 离线安装包(注意 aarch64 会拉取 aarch64 专用包,但 Harbor 官方仅支持 amd64 安装) |
-S | 以容器方式启动 kubeasz 部署环境,并写入dk命令别名(ezdown) |
-X <opt> | 下载额外组件镜像(cilium、flannel、dashboard、prometheus、kubeblocks 等,见 ezdown) |
其中-D内部会执行get_k8s_bin/get_ext_bin,借助多架构容器镜像把 arm64 版二进制提取到/etc/kubeasz/bin,再把默认镜像下载并 push 到本地 registryeaszlab.io.local:5000(ezdown)。这正是「复制代码 + 重下架构文件」这一思路的核心所在。
步骤三:配置免密并准备 kubectl kubeconfig
# 配置机器ssh免密码登录,集群所有节点都免密,包括待新增arm64节点 ssh-copy-id xx.xx.xx.xx ssh-copy-id ... # 复制kubeconfig mkdir /root/.kube/; cp clusters/default/kubectl.kubeconfig /root/.kube/config说明:
- 免密覆盖范围包括:既有 amd64 集群全部节点 + 待新增的 arm64 节点 + 本机(arm64 部署机自身);
- kubeasz 容器通过挂载
/root/.ssh、/root/.kube与宿主机共享(ezdown),因此宿主机上的免密配置与 kubeconfig 会直接生效; - 因为复制的是
default集群的完整目录(含证书与清单),所以clusters/default/kubectl.kubeconfig已存在于该目录中,直接复制为默认 kubeconfig 即可。
步骤四:使用 ezctl add-node 添加 arm64 新节点
source ~/.bashrc # 添加新节点 x.x.x.x dk ezctl add-node default x.x.x.xdk是-S步骤写入的别名,等价于docker exec -it kubeasz,即在 kubeasz 容器内执行 ezctl(ezdown)。
关于ezctl add-node的底层行为(源码见 ezctl):
- IP 合法性校验:先校验传入 IP 是否符合 IPv4 正则;
- 重复性检查:扫描
clusters/default/hosts中[kube_master]至[harbor]区间,确认该 IP 尚未存在于[kube_node]组; - 写入清单:将新节点追加到
[kube_node]组(可附带变量,如x.x.x.x k8s_nodename='worker-arm64-01',k8s_nodename命名规范见 example/hosts.multi-node 与 example/config.yml); - 执行安装:运行
ansible-playbook playbooks/22.addnode.yml,目标主机为NODE_TO_ADD。
步骤五:验证混合架构集群
$ kubectl get node -owide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME k8s-x.x.x-19 Ready master 5d8h v1.33.1 x.x.x.19 <none> Ubuntu 20.04.4 LTS 5.4.0-122-generic containerd://2.1.1 k8s-x.x.x-90 Ready node 5d8h v1.33.1 x.x.x.90 <none> Ubuntu 22.04.5 LTS 5.15.0-134-generic containerd://2.1.1 k8s-x.x.x-91 Ready node 5d8h v1.33.1 x.x.x.91 <none> Ubuntu 22.04.5 LTS 5.15.0-134-generic containerd://2.1.1 k8s-x.x.x-93 Ready node 79s v1.33.1 x.x.x.93 <none> Ubuntu 22.04.5 LTS 5.15.0-140-generic containerd://2.1.1 $ kubectl describe node|grep beta.kubernetes.io/arch Labels: beta.kubernetes.io/arch=amd64 Labels: beta.kubernetes.io/arch=amd64 Labels: beta.kubernetes.io/arch=amd64 Labels: beta.kubernetes.io/arch=arm64验证要点:
- 新节点状态为
Ready,且 VERSION 与既有节点一致(同一 k8s 版本,由 arm64 部署机下载的 arm64 二进制安装); - 通过
beta.kubernetes.io/arch标签确认架构分布:3 个 amd64 + 1 个 arm64,混合架构集群即告建成; - 进一步可
kubectl get pod -A确认系统组件(网络插件、coredns、metrics-server 等)在新节点上正常调度运行;由于默认组件镜像均为多架构镜像,arm64 节点可直接从本地 registry 拉取到匹配架构的镜像。
4. 源码级原理:add-node 究竟在新节点上做了什么
ezctl add-node最终调用的 playbooks/22.addnode.yml 揭示了新节点安装的完整角色链:
- hosts: "{{ NODE_TO_ADD }}" roles: - { role: os-harden, when: "OS_HARDEN|bool" } - { role: chrony, when: "groups['chrony']|length > 0" } - prepare - { role: docker, when: "CONTAINER_RUNTIME == 'docker'" } - { role: containerd, when: "CONTAINER_RUNTIME == 'containerd'" } - kube-lb - kube-node - { role: calico, when: "CLUSTER_NETWORK == 'calico'" } - { role: cilium, when: "CLUSTER_NETWORK == 'cilium'" } - { role: flannel, when: "CLUSTER_NETWORK == 'flannel'" } - { role: kube-router, when: "CLUSTER_NETWORK == 'kube-router'" }也就是说,新节点会依次完成:系统准备(含内核模块、sysctl、时区等)→ 容器运行时安装(docker 或 containerd,由清单中CONTAINER_RUNTIME决定)→ kube-lb(kubelet/kube-proxy 访问 apiserver 的本地负载均衡)→ kube-node(kubelet + kube-proxy 安装与启动)→ 按CLUSTER_NETWORK选择对应网络插件。
其中与架构强相关的环节是kube-node 角色:roles/kube-node/tasks/main.yml 通过copy: src={{ base_dir }}/bin/{{ item }}把部署机/etc/kubeasz/bin下的 kubelet、kube-proxy、kubectl 以及 cni 插件二进制分发到目标节点的/opt/kube/bin与/opt/cni/bin。
这正是混合架构方案能成立、同时又必须「按架构准备部署机」的根本原因:二进制来自部署机的bin目录,若用 amd64 部署机去装 arm64 节点,推送过去的将是 x86_64 二进制,必然执行失败;而通过「复制代码 + 在 arm64 机器上重新ezdown -D」重新生成 arm64 版bin与镜像,add-node 即可把正确架构的组件装到 arm64 节点上。其余 role(prepare、containerd、网络插件等)或为纯配置、或使用多架构镜像,天然跨架构兼容。
此外,新节点加入后,roles/kube-node/tasks/main.yml 还会轮询等待节点 Ready,并打上kubernetes.io/role=node等标签。如需进一步为 arm64 节点打自定义标签/污点(例如仅将数据库类工作负载调度到 amd64 节点),可在验证通过后手工执行kubectl label/kubectl taint,或将k8s_nodename变量写入清单便于区分(详见 example/config.yml 中K8S_NODENAME的命名规则)。
5. 补充与限制说明
- 依赖既有集群文件:混合架构方案要求先有正常工作的 amd64 集群,且其
clusters/default清单、证书、kubeconfig 会随目录复制到 arm64 部署机,务必确认default是目标集群名(如不同,将add-node default替换为实际集群名); - 镜像架构匹配:集群内组件(coredns、网络插件、metrics-server、dashboard 等)一般均提供多架构镜像,可直接拉取(多架构支持说明);但第三方业务镜像是否提供 arm64 版本需自行确认,否则可能调度到 arm64 节点后无法启动,可通过 nodeSelector / 亲和性约束规避;
- Harbor 限制:Harbor 目前仅支持 amd64 安装,混合架构集群中的镜像仓库需另行规划;
- 运行时限制:若集群版本 >= 1.24,容器运行时须使用 containerd(docker 不再支持,见 example/hosts.multi-node);
- 故障自愈与幂等:整个 add-node 过程是 ansible 幂等执行,输出近乎白盒,出错时可依据详细日志定位,并可随时修改脚本后重跑修复;
- 扩展阅读:单节点删除与批量添加可参考
ezctl del-node/ezctl add-nodes(用法见 ezctl),节点运维专题见 节点运维文档。
6. 小结
通过「amd64 部署机建集群 → 复制架构无关代码 → arm64 部署机重建架构相关文件 → add-node 并入」四步,即可在 kubeasz 上成功构建 amd64 + arm64 混合架构集群。整个过程充分体现了 kubeasz 部署的灵活性与可配置性:二进制按部署机架构自动匹配、镜像多为多架构、ansible 幂等可重跑、执行过程白盒可见,出错时借助详细输出即可快速定位修复。Hack it, and have fun!
【免费下载链接】kubeasz使用Ansible脚本安装K8S集群,介绍组件交互原理,方便直接,不受国内网络环境影响项目地址: https://gitcode.com/GitHub_Trending/ku/kubeasz
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考