引言
我与Kubernetes的缘分始于2018年,那是我参与的第一个涉及容器编排的实际项目。当时我初出茅庐,虽然对这项技术充满好奇与热情,却没能抽出足够时间深入钻研。一年后,我离开了那个项目,最终没能按照最初的设想将它完成。
直到2020年,我又获得了一次接触Kubernetes的机会——这一次,我不仅拥有了更丰富的实战经验,态度也更加专注,目标也愈发清晰。
时光飞逝,如今我已成功考取两项Kubernetes认证:CKAD(认证Kubernetes应用开发者)和CKA(认证Kubernetes管理员)。其中,CKA认证更是成为我职业生涯的重要转折点。我并非出身传统的基础设施或DevOps领域,而是从软件开发起步,因此必须深入钻研Kubernetes的底层逻辑——搞清楚集群的构建方式、控制平面与工作节点的通信机制,以及网络配置和故障排查的底层原理。
为了巩固所学知识,我决定利用手头的几台树莓派,从零开始搭建一个Kubernetes集群。这些基于ARM架构的小型计算机,能让我近距离接触底层硬件,以更直观、更具体的方式理解Kubernetes的工作原理。
起初,我只是想通过这个实践备战认证考试,可后来它逐渐演变成了一个实用的项目:一个可以在家中运行、维护成本低、全天候在线的开发环境。
本文将深入探讨这段旅程。
我不会过多纠结于理论知识,而是重点讲解集群搭建的实际操作过程——从节点引导到在ARM架构上部署功能完备的Kubernetes环境。过程中,我会着重分享遇到的挑战、文档中存在的空白,以及通过反复试错积累的宝贵经验。
如果你也想搭建自己的树莓派Kubernetes实验室,或者只是想了解如何从零开始构建一个Kubernetes集群,那么这篇文章正是为你准备的。
关于本系列
这是本系列的第一篇文章,我将记录在树莓派上搭建和运行Kubernetes集群的完整过程。
在整个系列中,我将分解设置的每一层,重点关注实际实施和实际挑战:
集群创建(本文)—— 引导节点、网络和在ARM上安装Kubernetes
负载均衡和服务网格 —— 使用MetalLB实现外部访问,使用Istio进行流量管理
存储设置 —— 为ARM构建可靠的文件服务器
监控栈 —— 集成Prometheus和Grafana以实现可观测性
集群升级:将集群升级到可用的最新版本
如果你对树莓派上的Kubernetes应用感到好奇,或者想了解一个从零设计的集群的实际案例,欢迎持续关注——本系列专为你打造。
集群创建
硬件
为了简化配置,我特意使用了手头已有的硬件,具体配置如下:
1 × 树莓派4 Model B(8GB内存,128GB SD卡)——控制平面(主节点)
1 × 树莓派3 Model B(1GB内存,64GB SD卡)——工作节点
这样的硬件组合对于轻量级Kubernetes集群来说完全足够,同时也印证了一个重要观点:想要理解Kubernetes的底层工作原理,并不需要性能强大的机器。
入门
操作系统方面,我选择了Ubuntu Server 24.04 LTS(64位)。它对ARM架构提供了强大的支持,相关文档详尽,且能与各类Kubernetes工具无缝协作。
最简单的安装方法是使用树莓派镜像生成器( raspberrypi.com/software/ ),它可以让你一步完成镜像闪存和操作系统预配置,省去后续诸多麻烦。
在闪存镜像之前,我强烈建议使用高级配置选项完成以下操作:
启用SSH访问
配置你的Wi-Fi凭据
为每个节点设置主机名(例如,k8s-master、k8s-worker)
添加你的SSH公钥(可选,但推荐)
提前完成这些配置,能节省大量后续手动操作的时间,让集群搭建更高效。
首次访问
一旦镜像被闪存且树莓派通电,你就可以通过SSH连接:
ssh <node-ip>
登录后,切换到root用户以简化设置步骤:
sudo -i
从现在开始,所有命令都将以root身份执行,以避免在初始集群配置期间出现权限问题。
安装集群组件
这一步必须在两个树莓派上执行,因为控制平面和工作节点都需要核心Kubernetes组件:
• kubelet —— 在每个节点上运行和管理pod
• kubeadm —— 引导集群
• kubectl —— 与集群交互的CLI
禁用交换分区(重要)
默认情况下,如果启用了交换内存,kubelet将拒绝启动。这是首次设置集群时常见的绊脚石。
Kubernetes期望可预测的资源分配,而交换分区可能会通过引入延迟和意外的调度行为来干扰这一点。
为了避免问题,你需要完全禁用交换分区。
swapoff -ased -i '/ swap / s/^(.*)$/#1/g' /etc/fstab
内核模块和版本考虑
在继续之前,我强烈建议你查看针对你特定版本的官方Kubernetes文档,特别是关于所需内核模块和系统配置的部分。
Kubernetes设置要求随着时间的推移而演变。一些以前是强制性的配置——特别是围绕内核模块和网络的部分——在新版本中(特别是从v1.29开始)不再需要。
这很重要,因为许多教程和博客文章仍然包含过时的步骤,这可能会导致混淆或不必要的配置。参考:
https://kubernetes.io/docs/setup/production-environment/container-runtimes/#install-and-configure-prerequisites
cat <<EOF | sudo tee /etc/modules-load.d/k8s.confoverlaybr_netfilterEOFmodprobe overlaymodprobe br_netfiltercat <<EOF | sudo tee /etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-iptables = 1net.bridge.bridge-nf-call-ip6tables = 1net.ipv4.ip_forward = 1EOFsysctl --system
安装容器运行时(主节点和工作节点)
要在Pod中运行容器,Kubernetes使用容器运行时。默认情况下,Kubernetes使用容器运行时接口(CRI)与你选择的容器运行时进行交互。如果你没有指定运行时,kubeadm会自动尝试通过扫描已知端点列表来检测已安装的容器运行时。如果检测到多个或没有容器运行时,kubeadm将抛出错误并要求你指定要使用的运行时。在我的实验室中,我使用了containerd作为CRI。
Containerd
我按照cri-tools仓库中的步骤安装了containerd,下面我将列出这些步骤,但请在出现问题时查阅文档:
VERSION="v1.30.0" # check latest version in /releases pagecurl -L https://github.com/kubernetes-sigs/cri-tools/releases/download/$VERSION/crictl-${VERSION}-linux-amd64.tar.gz --output crictl-${VERSION}-linux-amd64.tar.gzsudo tar zxvf crictl-$VERSION-linux-amd64.tar.gz -C /usr/local/binrm -f crictl-$VERSION-linux-amd64.tar.gz
参考:
https://github.com/kubernetes-sigs/cri-tools/blob/master/docs/crictl.md
设置Docker的apt仓库:
# Add Docker's official GPG key:sudo apt-get updatesudo apt-get install apt-transport-https ca-certificates curl gpgsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc# Add the repository to Apt sources:echo"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu$(. /etc/os-release && echo "$VERSION_CODENAME") stable" |sudo tee /etc/apt/sources.list.d/docker.list > /dev/nullsudo apt-get update
安装containerd:
sudo apt-get install containerd.io
运行以下命令配置containerd:
sudo mkdir -p /etc/containerdsudo containerd config default | sudo tee /etc/containerd/config.toml
验证配置是否正确,特别是plugins.”io.containerd.grpc.v1.cri”部分。确保sandbox_image设置正确:
[plugins."io.containerd.grpc.v1.cri".containerd]snapshotter = "overlayfs"[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]SystemdCgroup = true
要编辑配置,请写入以下命令,然后根据需要编辑上述行:
sudo vi /etc/containerd/config.toml
重启containerd:
sudo systemctl restart containerdsudo systemctl enable containerdsystemctl status containerd
启用IP转发:
sudo sh -c "echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf"sudo sysctl -p
使用crictl验证containerd以检查containerd状态:
sudo crictl info
安装Kubernetes组件(v1.29)
安装了containerd并准备好了节点后,下一步是安装核心Kubernetes组件:kubelet、kubeadm和kubectl。
对于这个设置,我使用的是Kubernetes v1.29,我强烈建议遵循最近版本中引入的官方打包方法(使用新的pkgs.k8s.io仓库)。
添加Kubernetes仓库(v1.29)
在两个节点上运行以下命令:
apt-get updateapt-get install -y apt-transport-https ca-certificates curl gpg
添加Kubernetes签名密钥:
mkdir -p /etc/apt/keyringscurl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/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.29/deb/ /"> /etc/apt/sources.list.d/kubernetes.list
安装kubelet、kubeadm和kubectl
apt-get updateapt-get install -y kubelet kubeadm kubectl
防止自动升级(推荐用于集群稳定性):
apt-mark hold kubelet kubeadm kubectl
启用kubelet
systemctl enable kubelet
在这个阶段,kubelet可能会运行但尚未完全功能——这是预期的。一旦用kubeadm引导集群,它将正确初始化。
引导控制平面
安装了所有组件后,是时候通过初始化控制平面来使集群运行起来了。
这一步只在主节点上执行(在这个设置中是树莓派4)。
kubeadm init--pod-network-cidr=192.168.0.0/16
如果一切顺利,kubeadm将:
引导控制平面
启动kubelet
生成证书
输出一个类似于下面的kubeadm join命令:
To start using your cluster, you need to run the following as a regular user:mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/configAlternatively, if you are the root user, you can run:export KUBECONFIG=/etc/kubernetes/admin.confYou should now deploy a pod network to the cluster.Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:https://kubernetes.io/docs/concepts/cluster-administration/addons/Then you can join any number of worker nodes by running the following on each as root:kubeadm join 192.168.1.156:6443 --token token--discovery-token-ca-cert-hash sha256:hash
重要:复制kubeadm join命令——你需要它来添加工作节点。
使用Weave Net安装Pod网络(CNI)
初始化控制平面后,Kubernetes需要一个CNI插件来启用pod之间的通信。
对于这个设置,我选择了Weave Net——一个简单可靠的选择,在树莓派等ARM环境中表现良好。
在主节点上运行以下命令:
kubectl apply -f https://reweave.azurewebsites.net/k8s/v1.29/net.yaml
验证安装
kubectl get pods -n kube-system
一旦CNI安装完成,Kubernetes将完成节点网络配置。
kubectl get nodes
节点状态必须为Ready。
工作节点
控制平面运行起来后,最后一步是将你的工作节点加入集群。
在工作树莓派上,重复安装以下组件的相同步骤:
kubeadm
kubelet
kubectl
一旦节点准备就绪,使用控制平面初始化期间生成的kubeadm join命令:
kubeadm join <control-plane-ip>:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
运行加入命令后,回到控制平面节点并检查:
kubectl get nodes
你应该看到两个节点都已列出且处于Ready状态:
NAME STATUS ROLES AGE VERSIONk8s-master Ready control-plane ... v1.29.xk8s-worker Ready <none> ... v1.29.x
如果节点未就绪
工作节点需要一段时间才能变为Ready状态是很正常的,特别是在树莓派硬件上。
如果它一直处于NotReady状态,常见原因包括:
CNI插件未完全初始化(Weave仍在启动)
节点之间的网络连接问题
kubelet未正确运行
你可以使用以下命令进行调试:
kubectl describe node <worker-node-name>
合理性检查
现在集群已经运行起来了,让我们通过部署一个简单的应用程序来验证一切是否正常。
我们将使用NGINX,一个轻量级Web服务器,作为快速测试工作负载。
创建部署:
kubectl create deployment nginx --image=nginx
验证pod是否正在运行:
kubectl get pods
你应该看到类似这样的内容:
nginx-xxxxxxxxxx-xxxxx 1/1 Running ...
总结
在树莓派上搭建这个Kubernetes集群,远不止是一次简单的家庭实验室练习。起初,我只是想通过这个实践备战认证考试,可后来它逐渐演变成了一个实用、全天候在线的开发环境,我可以在其中自由实验、部署应用、积累经验,而无需担心影响生产系统。
这段搭建之旅,让我有机会深入探究Kubernetes的底层工作机制——搞清楚每个组件的具体作用、网络的建立流程,以及控制平面与工作节点在真实集群中的通信逻辑。同时,使用ARM架构设备,也让我遇到了一些在标准x86环境中不常见的问题,这些经历让这次实践变得更加宝贵,也让我对Kubernetes的理解更加深刻。
此时,集群已完全运行:
在树莓派上运行的控制平面
一个成功加入集群的工作节点
通过Weave Net配置的网络
一个为工作负载和实验准备好的基础
接下来是什么
在本系列的下一篇文章中,我将通过介绍以下内容将这个设置扩展为一个更完整的平台:
存储 —— 在ARM上为持久性工作负载设置可靠的文件服务器
监控 —— 集成Prometheus和Grafana以观察集群和应用程序指标
负载均衡和暴露 —— 使用MetalLB将服务暴露到外部
服务网格 —— 引入Istio来管理服务之间的流量
集群维护 —— 升级、稳定性考虑和长期管理
每一层都为环境增添了更多现实感,并使集群更接近你可以实际依赖它进行日常开发的东西。
如果你正在搭建自己的树莓派Kubernetes集群,或者跟随本系列进行学习,那么目标不仅仅是复制步骤——而是要足够理解系统,以便能够根据你的需求进行调整。
如果你想查阅更多内容,可以点击文章尾部的【阅读全文】。
tip:对于刚接触树莓派的新手来说,面对英文文档、零散教程和复杂配置,很容易无从下手。pidoc.cn 就是为解决这些痛点而生的树莓派中文一站式学习平台,界面清晰、内容系统、更新及时,堪称新手入门的 “保姆级” 网站,让零基础用户也能轻松上手树莓派。
官方网站:https://edatec.cn/zh/cm0
淘宝店铺:https://edatec.taobao.com/
134