有没有想过创建属于你自己的云?现在你可以了!只需要一些廉价的开源硬件和开源软件。大约 200 美元,我就能够使用 Fabric8,设置四台 Raspberry Pi 2s 运行 Kubernetes 云操作系统。
Fabric8 是一个开箱即用的开源 DevOps 和集成平台,可在任何 Kubernetes 或 OpenShift 环境中运行,并提供持续交付、管理、ChatOps 和 Chaos Monkey。简而言之,它是开发和管理微服务的最佳框架。(完全公开:我在 Red Hat Fabric8 项目工作。)
软件架构与其运行的硬件之间从未有过如此完美的匹配。Pi 完全静音(无风扇),并具有相当强大的四核 CPU,而微服务架构使每个进程相对较小,因此可以在每个节点的 1GB RAM 内存限制下运行。如果需要更多计算能力,您可以简单地添加更多 Pi。最后,玩硬件就是纯粹的乐趣,而不是登录到亚马逊的远程虚拟机。
1. 必需的硬件
为了构建这个四 Pi 设置,我使用了
- 4 个 Raspberry Pi 2
- 4 张 16GB MicroSD 卡(Class 10)
- 1 个 60W 电源适配器,带 USB 接口
- 4 根短 USB 转 Micro USB 线缆(用于为 Pi 供电)
- 4 根短 Cat 5 网线
- 1 根较长的 Cat 5 网线,用于连接到您的网络
- 1 个网络集线器(我的是一个旧的五端口 10/100MBps 的,我掸了掸灰尘)
- 乐高积木(相信我,自己搭建感觉很棒!)
重要的是要购买 Class 10 MicroSD 卡,因为这是极大地影响系统速度的组件。对于四个 Pi,您可以轻松使用较小的 20W 电源适配器,但我计划稍后添加更多,所以我买了一个更大的。Pi 上的网络端口是 100MBps,所以您可以使用旧的集线器。
2. 刷写 MicroSD 卡
现在我们需要将操作系统安装到 MicroSD 卡上。我正在使用 Hypriot 镜像。我测试了很多其他镜像,包括 Pidora、Redsleeve/CentOS 和 Arch Linux,但最终得出结论,Hypriot 是目前最适合我的(主要是因为原生 Docker 支持和镜像体积小)。您可以在此处下载最新的 Hypriot 镜像。
- 将存储卡插入读卡器。请勿挂载它。如果它自动挂载,请卸载该卡。然后将镜像写入卡中。在我的 OS X 机器上,执行此操作的命令是
sudo dd bs=1m if=hypriot-rpi-20151103-224349.img of=/dev/diskn
将“n”替换为使用磁盘工具找到的磁盘编号:在 Mac OS X 10.8.x Mountain Lion 上,“验证磁盘”(在卸载之前)会将 BSD 名称显示为“/dev/disk2s1”或类似名称。请仔细检查,否则您可能会格式化您不打算格式化的磁盘! - 请等待。这可能需要 10 分钟左右。
- 对所有四张 MicroSD 卡执行此操作。在等待时,您可以制作乐高外壳。
3. 上电并添加 DNS
您现在可以为第一台 Pi 上电。默认情况下,使用 root/hypriot 登录。您需要为每个 Pi 设置 DNS。如果您不想连接显示器和键盘来找出其 IP 和 MAC 地址,那么您可以使用 nmap。如果您有 DNS 服务,请在那里配置它。否则,请在 /etc/hosts 中命名 Pi。我将我的 Pi 命名为 rpi-master、rpi-node-1、rpi-node-2 和 rpi-node-3。在快速重启每个 Pi 后,您将在 cmd 提示符中看到反映的名称。请注意,如果您跳过 DNS 步骤,您的 Kubernetes 集群将无法工作。我在所有机器的 /etc/hosts 文件中添加了以下内容
192.168.1.9 rpi-master 192.168.1.21 rpi-node-1 192.168.1.18 rpi-node-2 192.168.1.23 rpi-node-3
4. 添加交换空间(可选)
我在我的 rpi-master 上添加了 1GB 的交换空间,因为它运行了更多 Kubernetes 组件。有些人似乎担心频繁写入 MicroSD 卡会导致其快速失效。因此,我决定设置 swappiness,使其仅在万不得已时才使用交换空间。
dd if=/dev/zero of=/swap/swapfile bs=1M count=1024 mkswap /swap/swapfile swapon /swap/swapfile
现在您可以使用 top 检查您是否拥有 1GB 的交换空间。
KiB 内存 | 总共 947468, | 已用 913096, | 空闲 34372, | 缓冲区 69884 |
KiB 交换空间 | 总共 1048572, | 已用 484, | 空闲 1048088, | 缓存 667248 |
为了使交换空间在重启之间永久生效,请添加
/swap/swapfile none swap sw 0 0
到您的 /etc/fstab 文件中。最后,在 /etc/sysctl.conf 中,我将 swappiness 设置为 1
vm.swappiness = 1
“1”表示仅当 RAM 使用率超过 99% 时才会使用交换空间。
5. 安装 Kubernetes
这些说明用于安装来自 Google 的纯 vanilla Kubernetes。由于某些 64 位依赖项,我在编译 OpenShift 3 时遇到了一些问题,稍后我会再讨论这个问题。我希望同时支持两者。我正在使用的所有代码都签入在 https://github.com/Project31 下。如果您想编译自己的 Kubernetes 二进制文件,请查看我的博客文章。
5.1. 安装 Kubernetes master
Kubernetes master 运行 Kubernetes REST API、调度器、kubernetes-proxy 和复制控制器。它还使用 etcd 作为键值存储,该存储在其他 Kubernetes master 之间复制。有关更多详细信息,请参阅 Kubernetes 文档。

Kubernetes master 组件。
要将这些组件安装到 master 上,请登录到 master 节点并运行
git clone git@github.com:Project31/kubernetes-installer-rpi.git cd kubernetes-install-rpi ./build-master.sh
使用 docker ps 验证正在运行的 Docker 容器
容器 ID | 镜像 | 命令 | 创建时间 | 状态 | 名称 |
d598e486daf5 | hyperkube | "/hyperkube proxy --m" | ... | ... | k8s_kube-proxy... |
026c19a67f86 | hyperkube | "/hyperkube scheduler" | ... | ... | k8s_kube-scheduler... |
8f615b87cfda | hyperkube | "/hyperkube controlle" | ... | ... | k8s_kube-controller-manager.... |
a737d9927c03 | hyperkube | "/hyperkube apiserver" | ... | ... | k8s_kube-apiserver.... |
0207a21ce18d | etcd | "etcd --data-dir=/var" | ... | ... | k8s_etcd... |
a4174bf7cb98 | .../pause:0.8.0 | "/pause" | ... | ... | k8s_POD... |
现在设置导出 KUBERNETES_MASTER=http://rpi-master:8080,以便您的 kubectl 可以连接到 master 上的 Kubernetes REST API。现在让我们使用 kubectl get pods 查看正在运行的 pod
名称 | 就绪 | 状态 | 重启次数 | 运行时间 |
kube-controller-rpi-master | 5/5 | 正在运行 | 0 | 10 秒 |
我们可以看到 kube-controller-rpi-master pod 包含五个 Docker 容器,其中运行着上面提到的 Kubernetes 服务。
5.2. 安装 Kubernetes 节点
Kubernetes 节点仅运行 Kubernetes 代理和 pod。

Kubernetes 客户端组件。
要在节点上安装这些组件,请登录到节点并运行
git clone git@github.com:Project31/kubernetes-installer-rpi.git cd kubernetes-install-rpi
现在编辑 kube-procy.yaml 并将 --master=http://rpi-master:8080 设置为您的 Kubernetes master。然后编辑 kubelet.service 文件,并在那里设置您的 master 的 Kubernetes REST 端点(在我的例子中是 http://192.168.1.9:8080)。
现在您可以运行安装
./build-worker.sh
并使用 docker ps 验证我们的代理是否启动
容器 ID | 镜像 | 命令 | 创建时间 | 状态 | 名称 |
cf4a9a2d7f35 | hyperkube | "/hyperkube proxy --m" | 40 秒前 | 运行 37 秒 | k8s_kube-proxy... |
d9f8f937df4d | gcr.io/go... | "/pause" | 43 秒前 | 运行 40 秒 | k8s_POD.e4cc.. |
代理正在运行!设置导出 KUBERNETES_MASTER=http://rpi-master:8080,以便您的 kubectl 可以连接到 master 上的 Kubernetes REST API。现在验证所有节点都已注册
kubectl get nodes
名称 | 标签 | 状态 |
rpi-master | kubernetes.io/hostname=rpi-master | 就绪状态 |
rpi-node-1 | kubernetes.io/hostname=rpi-node-1 | 就绪状态 |
rpi-node-2 | kubernetes.io/hostname=rpi-node-2 | 就绪状态 |
rpi-node-3 | kubernetes.io/hostname=rpi-node-3 | 就绪状态 |
耶,成功了!
6. 开放 Docker 以进行远程连接
我们需要修复 master 上的 Docker 配置,以便它接受远程连接,并且我们可以将某些内容部署到它。打开 /etc/default/docker 文件进行编辑并设置 DOCKER_OPTS
DOCKER_OPTS="-H tcp://192.168.1.9:2375 -H unix:///var/run/docker.sock --storage-driver=overlay -D"
指定机器的 IP 地址,或者您可以使用“0.0.0.0”绑定到所有接口。现在我们可以远程将 Docker 镜像推送到 master。
7. 部署一个简单的服务
让我们部署一个简单的服务并扩展到两个 pod,以确保一切正常运行
kubectl -s http://localhost:8080 run httpd --image=hypriot/rpi-busybox-httpd --port=80 kubectl scale --replicas=2 rc httpd kubectl get pods -o wide
我们看到,即使我们在 master 上执行了命令,它也在 node-2 和 node-3 上启动了一个 pod
名称 | 就绪 | 状态 | 重启次数 | 运行时间 | 节点 |
httpd-4v1qw | 1/1 | 正在运行 | 0 | 9 分钟 | rpi-node-2 |
httpd-qxcxu | 0/1 | 待定 | 0 | 16 秒 | rpi-node-3 |
kube-controller-rpi-master | 5/5 | 正在运行 | 0 | 1 天 | rpi-master |
kube-system-rpi-node-1 | 1/1 | 正在运行 | 0 | 33 分钟 | rpi-node-1 |
kube-system-rpi-node-2 | 1/1 | 正在运行 | 0 | 43 分钟 | rpi-node-2 |
kube-system-rpi-node-3 | 1/1 | 正在运行 | 0 | 53 分钟 | rpi-node-3 |
8. 结论
首先,它工作了!Kubernetes master 可能没有太多内存来运行服务,但另一方面,节点几乎有整整 1GB 的内存可用于 Docker 容器。如果您需要更多计算能力,您可以简单地添加节点。这个硬件平台的极低价格,加上 Kubernetes 云操作系统和 Fabric8 DevOps 和 iPaaS 功能,使其成为真正的颠覆性技术。它真的是一个价值 200 美元的“云中盒子”。
13 条评论