本文发布时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。

创建运行 Kubernetes 的 Raspberry Pi 集群,安装(第 2 部分)

在比利时 Devoxx 和摩洛哥 Devoxx 上,Ray Tsang 和我 (Arjen Wassink) 展示了我们在 Quintor 构建的运行 HypriotOS、Docker 和 Kubernetes 的 Raspberry Pi 集群。虽然我们收到了很多关于演讲的赞美,但最常见的问题是如何自己构建一个 Pi 集群!我们将分两个部分来完成这项工作。第一部分介绍了集群的购物清单,而第二部分将向您展示如何启动并运行 Kubernetes...

现在您已经设置好 Raspberry Pi 集群,是时候在它上面运行一些软件了。正如上一篇博客中所述,我本教程基于用于 ARM 处理器的 Hypriot Linux 发行版。主要原因是捆绑了对 Docker 的支持。我使用了此版本的 Hypriot 来进行本教程,因此如果您在使用其他版本的 Hypriot 时遇到问题,请考虑我使用的版本。

第一步是确保每个 Pi 都运行 Hypriot,如果尚未运行,请查看他们的入门指南。还将集群交换机连接到网络,以便可以访问 Internet,并且每个 Pi 都通过 DHCP 分配 IP 地址。因为我们将运行多个 Pi,所以为每个 Pi 提供唯一的主机名很实用。为了方便起见,我将我的 Pi 重命名为 rpi-master、rpi-node-1、rpi-node-2 等。请注意,在 Hypriot 上,主机名是通过编辑 /boot/occidentalis.txt 文件而不是 /etc/hostname 来设置的。您还可以使用 Hypriot 闪存工具设置主机名。

在 Pi 上运行软件最重要的是 ARM 发行版的可用性。感谢 Brendan BurnsGoogle Cloud Registry 中提供了用于 ARM 的 Kubernetes 组件。这很棒。第二个障碍是如何安装 Kubernetes。有两种方法:直接在系统上或在 Docker 容器中。尽管容器支持处于实验状态,但我选择使用它,因为它使您更容易安装 Kubernetes。Kubernetes 需要在节点上运行几个进程(etcd、flannel、kubectl 等),这些进程应该按特定顺序启动。为了简化这一点,提供了 systemd 服务以正确的方式启动必要的进程。此外,systemd 服务确保在(重新)启动节点时启动 Kubernetes。为了使安装非常容易,我为 master 节点和 worker 节点创建了一个简单的安装脚本。所有内容都可以在 GitHub 上找到。所以现在开始吧!

安装 Kubernetes master 节点

首先,我们将在 master 节点上安装 Kubernetes,稍后将 worker 节点添加到集群中。这基本上归结为获取 git 存储库内容并执行安装脚本。

$ curl -L -o k8s-on-rpi.zip https://github.com/awassink/k8s-on-rpi/archive/master.zip

$ apt-get update

$ apt-get install unzip

$ unzip k8s-on-rpi.zip

$ k8s-on-rpi-master/install-k8s-master.sh

安装脚本将安装五个服务

  • docker-bootstrap.service - 是一个单独的 Docker 守护进程,用于运行 etcd 和 flannel,因为 flannel 需要在标准 Docker 守护进程 (docker.service) 之前运行,因为网络配置。
  • k8s-etcd.service - 是用于存储 flannel 和 kubelet 数据的 etcd 服务。
  • k8s-flannel.service - 是 flannel 进程,在集群中的所有节点上提供覆盖网络。
  • docker.service - 是标准 Docker 守护进程,但以 flannel 作为网络桥。它将运行所有 Docker 容器。
  • k8s-master.service - 是提供集群功能的 Kubernetes master 服务。

此安装过程的基本详细信息也记录在 Kubernetes 的 入门指南中。请查看它以更深入地了解如何设置多节点 Kubernetes 集群。

让我们检查一下一切是否正常工作。必须有两个 docker 守护进程在运行。

$ ps -ef|grep docker
root       302     1  0 04:37 ?        00:00:14 /usr/bin/docker daemon -H unix:///var/run/docker-bootstrap.sock -p /var/run/docker-bootstrap.pid --storage-driver=overlay --storage-opt dm.basesize=10G --iptables=false --ip-masq=false --bridge=none --graph=/var/lib/docker-bootstrap

root       722     1 11 04:38 ?        00:16:11 /usr/bin/docker -d -bip=10.0.97.1/24 -mtu=1472 -H fd:// --storage-driver=overlay -D

etcd 和 flannel 容器必须启动。

$ docker -H unix:///var/run/docker-bootstrap.sock ps

CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES

4855cc1450ff        andrewpsuedonym/flanneld     "flanneld --etcd-endp"   2 hours ago         Up 2 hours                              k8s-flannel

ef410b986cb3        andrewpsuedonym/etcd:2.1.1   "/bin/etcd --addr=127"   2 hours ago         Up 2 hours                              k8s-etcd


The hyperkube kubelet, apiserver, scheduler, controller and proxy must be up.

$ docker ps

CONTAINER ID        IMAGE                                           COMMAND                  CREATED             STATUS              PORTS               NAMES

a17784253dd2        gcr.io/google\_containers/hyperkube-arm:v1.1.2   "/hyperkube controller"   2 hours ago         Up 2 hours                              k8s\_controller-manager.7042038a\_k8s-master-127.0.0.1\_default\_43160049df5e3b1c5ec7bcf23d4b97d0\_2174a7c3

a0fb6a169094        gcr.io/google\_containers/hyperkube-arm:v1.1.2   "/hyperkube scheduler"   2 hours ago         Up 2 hours                              k8s\_scheduler.d905fc61\_k8s-master-127.0.0.1\_default\_43160049df5e3b1c5ec7bcf23d4b97d0\_511945f8

d93a94a66d33        gcr.io/google\_containers/hyperkube-arm:v1.1.2   "/hyperkube apiserver"   2 hours ago         Up 2 hours                              k8s\_apiserver.f4ad1bfa\_k8s-master-127.0.0.1\_default\_43160049df5e3b1c5ec7bcf23d4b97d0\_b5b4936d

db034473b334        gcr.io/google\_containers/hyperkube-arm:v1.1.2   "/hyperkube kubelet -"   2 hours ago         Up 2 hours                              k8s-master

f017f405ff4b        gcr.io/google\_containers/hyperkube-arm:v1.1.2   "/hyperkube proxy --m"   2 hours ago         Up 2 hours                              k8s-master-proxy

在集群上部署第一个 pod 和服务

当一切正常时,我们可以使用 kubectl 访问 Kubernetes 集群的 master 节点。可以从 googleapis 存储下载用于 ARM 的 kubectl。kubectl get nodes 显示哪些集群节点已注册及其状态。主节点名为 127.0.0.1。

$ curl -fsSL -o /usr/bin/kubectl https://dl.k8s.io/release/v1.1.2/bin/linux/arm/kubectl

$ kubectl get nodes

NAME              LABELS                                   STATUS    AGE

127.0.0.1         kubernetes.io/hostname=127.0.0.1         Ready      1h


An easy way to test the cluster is by running a busybox docker image for ARM. kubectl run can be used to run the image as a container in a pod. kubectl get pods shows the pods that are registered with its status.

$ kubectl run busybox --image=hypriot/rpi-busybox-httpd

$ kubectl get pods -o wide

NAME                   READY     STATUS    RESTARTS   AGE       NODE

busybox-fry54          1/1       Running   1          1h        127.0.0.1

k8s-master-127.0.0.1   3/3       Running   6          1h        127.0.0.1

现在 pod 正在运行,但应用程序通常不可访问。可以通过创建服务来实现这一点。集群 IP 地址是服务在集群中可用的 IP 地址。使用您的 master 节点的 IP 地址作为外部 IP,该服务在集群外部变得可用(例如,在我的情况下为 http://192.168.192.161)。

$ kubectl expose rc busybox --port=90 --target-port=80 --external-ip=\<ip-address-master-node\>

$ kubectl get svc

NAME         CLUSTER\_IP   EXTERNAL\_IP       PORT(S)   SELECTOR      AGE

busybox      10.0.0.87    192.168.192.161   90/TCP    run=busybox   1h

kubernetes   10.0.0.1     \<none\>            443/TCP   \<none\>        2h

$ curl http://10.0.0.87:90/
\<html\>

\<head\>\<title\>Pi armed with Docker by Hypriot\</title\>

  \<body style="width: 100%; background-color: black;"\>

    \<div id="main" style="margin: 100px auto 0 auto; width: 800px;"\>

      \<img src="pi\_armed\_with\_docker.jpg" alt="pi armed with docker" style="width: 800px"\>

    \</div\>

  \</body\>

\</html\>

安装 Kubernetes worker 节点

下一步是在每个 worker 节点上安装 Kubernetes 并将其添加到集群中。这也基本上归结为获取 git 存储库内容并执行安装脚本。虽然在此安装中,需要事先复制 k8s.conf 文件并对其进行编辑以包含 master 节点的 IP 地址。

$ curl -L -o k8s-on-rpi.zip https://github.com/awassink/k8s-on-rpi/archive/master.zip

$ apt-get update

$ apt-get install unzip

$ unzip k8s-on-rpi.zip

$ mkdir /etc/kubernetes

$ cp k8s-on-rpi-master/rootfs/etc/kubernetes/k8s.conf /etc/kubernetes/k8s.conf

将 /etc/kubernetes/k8s.conf 中的 IP 地址更改为与 master 节点匹配

$ k8s-on-rpi-master/install-k8s-worker.sh

安装脚本将安装四个服务。这些服务与 master 节点上的服务非常相似,但不同之处在于没有 etcd 服务在运行,并且 kubelet 服务被配置为 worker 节点。

一旦 worker 节点上的所有服务都启动并运行,我们就可以在 master 节点上检查该节点是否已添加到集群中。

$ kubectl get nodes

NAME              LABELS                                   STATUS    AGE

127.0.0.1         kubernetes.io/hostname=127.0.0.1         Ready     2h

192.168.192.160   kubernetes.io/hostname=192.168.192.160   Ready     1h

$ kubectl scale --replicas=2 rc/busybox

$ kubectl get pods -o wide

NAME                   READY     STATUS    RESTARTS   AGE       NODE

busybox-fry54          1/1       Running   1          1h        127.0.0.1

busybox-j2slu          1/1       Running   0          1h        192.168.192.160

k8s-master-127.0.0.1   3/3       Running   6          2h        127.0.0.1

享受你的 Kubernetes 集群!

恭喜!您现在已运行 Kubernetes Raspberry Pi 集群,可以开始使用 Kubernetes 并开始学习。查看 Kubernetes 用户指南,了解您可以做的一切。并且不要忘记像我和 Ray 一样偶尔拔掉一些插头 :-)