Raspberry Pi部署k8s
先确定你的部署方式
你要先决定:
- 方案 A:单机 Kubernetes
- 只有一台树莓派,先搭一个单节点集群学习。
- 方案 B:多机 Kubernetes
- 比如:
- 1 台 master/control-plane
- 1~N 台 worker
- 比如:
下面是 最通用的 kubeadm 方式 ,默认:
- 系统:Raspberry Pi OS 64-bit / Ubuntu Server 64-bit
- 架构:arm64
- 容器运行时:containerd
- 网络插件:Flannel
- Kubernetes:v1.29 系列
准备工作:每台树莓派都要做
如果你以后要做多节点,这一部分所有节点都要执行。如果你只有一台,也一样执行。
第 1 步:查看系统信息
先执行:
1 | uname -m |
需要重点看:uname -m 是否是 aarch64,并记住当前树莓派 IP
第 2 步:更新系统
1 | sudo apt update |
安装常用工具:
1 | sudo apt install -y curl wget vim git net-tools htop ca-certificates gnupg lsb-release apt-transport-https |
第 3 步:设置主机名
如果你只有一台机器,可以命名为:
1 | sudo hostnamectl set-hostname rpi-master |
如果是多台:
- master:
rpi-master - worker1:
rpi-node1 - worker2:
rpi-node2
查看:
1 | hostname |
第 4 步:配置 hosts
编辑:
1 | sudo nano /etc/hosts |
如果你是单节点,至少保留本机解析。
如果是多节点,建议写成这样:
1 | 192.168.1.10 rpi-master |
把 IP 换成你自己的。
关闭 swap
Kubernetes 要求关闭 swap。先临时关闭:
1 | sudo swapoff -a |
再永久关闭:
1 | sudo sed -i '/ swap / s/^/#/' /etc/fstab |
检查:
1 | free -h |
确认 Swap 一栏是 0。
开启内核模块和网络转发
这是 Kubernetes 网络能正常工作的关键。
第 1 步:加载内核模块
执行:
1 | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
然后加载:
1 | sudo modprobe overlay |
第 2 步:设置内核参数
执行:
1 | cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf |
应用配置:
1 | sudo sysctl --system |
验证:
1 | sysctl net.ipv4.ip_forward |
应该输出:
1 | net.ipv4.ip_forward = 1 |
配置树莓派 cgroup
这一步非常重要,否则 kubelet 容易出问题。树莓派系统一般需要手工加启动参数。
第 1 步:编辑启动参数
先判断文件在哪,常见是:
1 | /boot/firmware/cmdline.txt |
也有可能是:
1 | /boot/cmdline.txt |
你可以先试:
1 | ls /boot/firmware/cmdline.txt |
编辑对应文件,例如:
1 | sudo nano /boot/firmware/cmdline.txt |
注意:这个文件通常只有一整行,不要换行。在这一行末尾追加:
1 | cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 |
例如原来是:
1 | console=serial0,115200 console=tty1 root=PARTUUID=xxxx rootfstype=ext4 fsck.repair=yes rootwait |
改成:
1 | console=serial0,115200 console=tty1 root=PARTUUID=xxxx rootfstype=ext4 fsck.repair=yes rootwait cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 |
第 2 步:重启
1 | sudo reboot |
重启后检查:
1 | cat /proc/cgroups |
安装并配置 containerd
即使你有 Docker,也建议明确配置 containerd。
第 1 步:安装 containerd
1 | sudo apt update |
第 2 步:生成默认配置
1 | sudo mkdir -p /etc/containerd |
第 3 步:修改 cgroup 驱动
编辑配置:
1 | sudo nano /etc/containerd/config.toml |
找到这一行:
1 | SystemdCgroup = false |
改成:
1 | SystemdCgroup = true |
第 4 步:重启并设置开机启动
1 | sudo systemctl restart containerd |
检查:
1 | sudo systemctl status containerd |
如果看到 active (running) 就正常。
安装 Kubernetes 组件
安装:kubelet,kubeadm,kubectl
第 1 步:添加 Kubernetes 官方仓库
安装依赖:
1 | sudo apt update |
添加 key:
1 | sudo mkdir -p /etc/apt/keyrings |
添加源:
1 | echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list |
第 2 步:安装组件
1 | sudo apt update |
查看版本:
1 | kubeadm version |
配置 Docker 与 containerd 关系
如果你只是拿 Docker 平时自己用,可以保留。但 Kubernetes 主要走 containerd。建议检查 containerd socket:
1 | ls /run/containerd/containerd.sock |
如果存在,一般就没问题。
拉取 Kubernetes 镜像
先看 kubeadm 需要哪些镜像:
1 | kubeadm config images list |
然后拉取:
1 | sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock |
如果下载慢或者失败,需要换国内镜像。对应的命令如下所示:
1 | sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock --image-repository registry.aliyuncs.com/google_containers |
初始化 Kubernetes 控制平面
如果你现在只有一台树莓派,这一步就是最关键的一步。先查看本机 IP:
1 | hostname -I |
假设你的树莓派 IP 是:
1 | 192.168.1.10 |
执行初始化:
1 | sudo kubeadm init \ |
说明:
--apiserver-advertise-address:你的 master IP--pod-network-cidr=10.244.0.0/16:给 Flannel 用--cri-socket:指定 containerd
初始化可能要几分钟。成功后你会看到类似:
1 | Your Kubernetes control-plane has initialized successfully! |
并且下面会给你一段 kubeadm join ... 命令。一定复制保存,后续 worker 节点加入要用。如果拉取失败,可以采用国内镜像,对应命令如下:
1 | sudo kubeadm init \ |
同时需要编辑配置文件:
1 | sudo nano /etc/containerd/config.toml |
将其中的sandbox_image = "..."改成sandbox_image = "registry.aliyuncs.com/google_containers/pause:3.10.2",接着重启 containerd 和 kubelet:
1 | sudo systemctl restart containerd |
检查:
1 | sudo systemctl status containerd --no-pager |
配置 kubectl
初始化成功后,执行下面命令,让当前用户能直接用 kubectl:
1 | mkdir -p $HOME/.kube |
测试:
1 | kubectl get nodes |
这时大概率会看到节点是:
1 | NotReady |
这是正常的,因为你还没装网络插件。
安装 CNI 网络插件(Flannel)
执行:
1 | kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml |
然后查看:
1 | kubectl get pods -A |
等几十秒到几分钟,再查看:
1 | kubectl get nodes |
如果正常,节点会变成:
1 | Ready |
如果你只有一台树莓派:允许 master 运行业务 Pod
默认 control-plane 节点有污点,不让普通 Pod 调度上去。单机学习环境可以去掉:
1 | kubectl taint nodes --all node-role.kubernetes.io/control-plane- |
然后再看:
1 | kubectl get nodes |
这样你的单机节点既是 master,也能跑应用。
部署一个测试应用
先部署 nginx:
1 | kubectl create deployment nginx --image=nginx |
暴露服务:
1 | kubectl expose deployment nginx --port=80 --type=NodePort |
查看 Pod:
1 | kubectl get pods -o wide |
查看 Service:
1 | kubectl get svc |
你会看到类似:
1 | nginx NodePort 10.x.x.x <none> 80:3xxxx/TCP |
然后访问:
1 | http://你的树莓派IP:3xxxx |
比如:
1 | http://192.168.1.10:31234 |
如果能打开 nginx 欢迎页,说明整个 Kubernetes 已经跑起来了。
如果你有多台树莓派:worker 加入集群
在其他树莓派上,重复前面的步骤:
- 更新系统
- 关闭 swap
- 配置 cgroup
- 安装 containerd
- 安装 kubelet kubeadm kubectl
但不要执行 kubeadm init,而是在 worker 节点执行 master 初始化后给你的 join 命令,例如:
1 | sudo kubeadm join 192.168.1.10:6443 \ |
回到 master 查看:
1 | kubectl get nodes -o wide |
如果成功,你会看到:
rpi-master Readyrpi-node1 Readyrpi-node2 Ready
常用管理命令
查看节点
1 | kubectl get nodes -o wide |
查看所有 Pod
1 | kubectl get pods -A |
查看服务
1 | kubectl get svc -A |
查看 deployment
1 | kubectl get deployment -A |
查看详细信息
1 | kubectl describe node rpi-master |
查看日志
1 | kubectl logs <pod名> |
如果 Pod 有多个容器:
1 | kubectl logs <pod名> -c <容器名> |
开机启动
一般以下服务都应自动启动:
containerd
1 | sudo systemctl enable containerd |
kubelet
1 | sudo systemctl enable kubelet |
检查:
1 | systemctl is-enabled containerd |
如果你想确认 Kubernetes 是否真的可用
执行:
1 | kubectl create deployment hello --image=nginx |
删除测试:
1 | kubectl delete svc hello |
常见问题排查
问题 1:kubeadm init 失败
看 kubelet 日志:
1 | sudo journalctl -u kubelet -f |
常见原因:
- swap 没关
- cgroup 参数没加
- containerd 没启动
SystemdCgroup = true没配
问题 2:节点一直 NotReady
通常是网络插件没装好。
查看:
1 | kubectl get pods -A |
重点看:
kube-flannelcoredns
如果 flannel 没起来,节点通常不会 Ready。
问题 3:镜像拉取失败
先看需要拉哪些镜像:
1 | kubeadm config images list |
再手工拉:
1 | sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock |
问题 4:端口访问不到 NodePort
检查:
1 | kubectl get svc |
确认:
- 服务类型是
NodePort - 防火墙没拦截
- 访问的是树莓派真实 IP
从零开始的最简命令版
如果你只想先在 一台树莓派 快速跑起来,可以按下面顺序直接做。
1)基础配置
1 | sudo apt update && sudo apt upgrade -y |
2)模块和内核参数
1 | cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf |
3)编辑 /boot/firmware/cmdline.txt 或 /boot/cmdline.txt
末尾加:
1 | cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 |
然后:
1 | sudo reboot |
4)安装 containerd
1 | sudo apt update |
5)安装 Kubernetes
1 | sudo mkdir -p /etc/apt/keyrings |
6)初始化
把下面 IP 改成你自己的:
1 | sudo kubeadm init \ |
7)配置 kubectl
1 | mkdir -p $HOME/.kube |
8)安装 flannel
1 | kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml |
9)单机允许调度
1 | kubectl taint nodes --all node-role.kubernetes.io/control-plane- |
10)验证
1 | kubectl get nodes |
