在树莓派上运行 Kubernetes/Docker

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前, 星球 内第2个项目《仿小红书(微服务架构)》正在更新中。第1个项目:全栈前后端分离博客项目已经完结,演示地址:http://116.62.199.48/。采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 255 小节,累计 39w+ 字,讲解图:1716 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 1300+ 小伙伴加入,欢迎点击围观

多亏了 Hypriot 的 Docker 盗版者 ,在 Raspberry Pi 上运行 Docker 引擎变得轻而易举,只需下载图像并将其闪存到你的 Pi 上,你就可以开始比赛了。我不打算介绍这个安装过程,它在 Hypriot 网站 上有详细的记录,我还在 Docker cookbook 中写了一个食谱。大致来说,下载 .img 文件并将其添加到您的 SD 卡,然后启动您的 PI。

在 Raspberry Pi 上安装 Docker 为爱好者和家庭设备提供了大量的可能性。这也引发了我的兴趣,因为 Kubernetes 作为 Docker 编排器之一,可以使用 Docker 容器 在单个节点上独立运行。几个月前我写了一篇关于使用 docker-compose 完成它的 帖子 。所以我决定在上周末尝试一下,使用具有 Docker 引擎的 Hypriot 镜像在 PI 上运行 Kubernetes。

etcd 运行

第一个问题是 Kubernetes 目前使用 etcd ,你需要在 ARM 上运行它。我决定直接在 PI 上获取 etcd 源并更新 Dockerfile 以直接在那里构建它。 Etcd 使用 Golang ONBUILD 图像,这让我很伤心。于是我复制了ONBUILD镜像的内容,新建了一个基于 hypriot/rpi-golang Dockerfile直接构建。你可以看到 Dockerfile 。这样你就有了一个在 ARM 上运行 etcd 的 Docker 容器。

让 Hyperkube 在 ARM 上运行

现在,我需要 hyperkube 二进制文件在 ARM 上运行。 Hyperkube 是一个单一的二进制文件,允许您启动所有 Kubernetes 组件。值得庆幸的是 ,已经有一些可用于 ARM 的二进制文件 。这很方便,因为我很难直接在 PI 上编译 Kubernetes。

有了这个 hyperkube 二进制文件,我基于 resin/rpi-raspbian:wheezy 镜像构建了一个镜像。很简单:


 FROM resin/rpi-raspbian:wheezy

RUN apt-get update RUN apt-get -yy -q install iptables ca-certificates

COPY hyperkube /hyperkube

Kubelet 系统单元

在集群中所有节点上运行的 Kubernetes 代理称为 Kubelet。 Kubelet 负责确保应该在节点上运行的所有容器确实运行。它还可以与清单一起使用,以在启动时启动一些特定的容器。 Kelsey Hightower 有一篇关于它的 好文章 。由于 Hypriot 图像使用 systemd,我直接从 Kelsey 的帖子中获取了创建 Kubelet 服务的 systemd 单元:


 FROM resin/rpi-raspbian:wheezy

RUN apt-get update RUN apt-get -yy -q install iptables ca-certificates

COPY hyperkube /hyperkube

kubelet 二进制文件直接从与 hyperkube 相同的 位置 下载。清单是一个 Kubernetes Pod 定义,它启动所有容器以使 Kubernetes 控制器运行。它启动 etcd 、API 服务器、调度程序、控制器和服务代理,所有这些都使用上面构建的 hyperkube 映像。

现在是肮脏的黑客

Kubernetes 做了一些有趣的事情。一个 Pod 中的所有容器实际上使用相同的 IP 地址。这是通过运行一个什么都不做的 容器来完成的。 Pod 中的其他容器与这个 容器共享相同的网络命名空间。这实际上称为 暂停 容器。我没有找到为 Kubernetes 中的 暂停 容器指定不同图像的方法,它似乎硬编码为 gcr.io/google_containers/pause:0.8.0 ,当然应该在 x86_64 上运行。

因此,肮脏的把戏包括从 Kubernetes 源代码中获取 暂停 Goland 代码,使用 hypriot/rpi-golang 在 PI 上编译它,并将二进制文件粘贴到 SCRATCH 图像中,并在本地标记它以显示为 gcr.io/google_containers/pause:0.8.0 并避免下载在 x86_64 上运行的真实图像。是的......对......我告诉过你肮脏但这是我能想到的最快方法。

把它们放在一起

现在您已直接在 PI 上准备好所有图像,以及一个 Kubelet 服务,您可以启动它。容器将被创建,您将在 PI 上拥有一个单节点 Kubernetes 集群。剩下的就是使用 kubectl CLI 来使用它。您可以从官方 Kubernetes 版本下载 ARM 版本 的 Kubectl。


 FROM resin/rpi-raspbian:wheezy

RUN apt-get update RUN apt-get -yy -q install iptables ca-certificates

COPY hyperkube /hyperkube

得到它

一切都在 GitHub https://github.com/runseb/k8s4pi 包括一个可怕的 bash 脚本,它完成了整个构建 :)