本文发表时间已超过一年。较早的文章可能包含过时内容。请确认页面中的信息自发布以来没有发生变化。
创建运行 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 设置唯一的 hostname 会比较方便。我将我的 Pi 改名为 rpi-master, rpi-node-1, rpi-node-2 等,以方便我自己使用。请注意,在 Hypriot 上,hostname 是通过编辑 /boot/occidentalis.txt 文件设置的,而不是 /etc/hostname。您也可以使用 Hypriot flash 工具设置 hostname。
在 Pi 上运行软件最重要的一点是 ARM 发行版的可用性。感谢 Brendan Burns,Google 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 daemon,用于运行 etcd 和 flannel,因为 flannel 需要在标准 Docker daemon (docker.service) 之前运行,以便进行网络配置。
- k8s-etcd.service - 这是用于存储 flannel 和 kubelet 数据的 etcd 服务。
- k8s-flannel.service - 这是 flannel 进程,用于在集群所有节点上提供 Overlay 网络。
- docker.service - 这是标准的 Docker daemon,但使用 flannel 作为网络桥。它将运行所有 Docker 容器。
- k8s-master.service - 这是 kubernetes master 服务,提供集群功能。
此安装过程的基本细节也记录在 Kubernetes 的 入门指南 中。请查阅该指南以更深入地了解多节点 Kubernetes 集群的搭建方法。
让我们检查一下是否一切正常。必须有两个 Docker daemon 进程正在运行。
$ 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 和 service
确认正常后,我们就可以使用 kubectl 访问 Kubernetes 集群的 master 节点了。适用于 ARM 的 kubectl 可以从 googleapis storage 下载。kubectl get nodes 命令显示哪些集群节点已注册及其状态。master 节点被命名为 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 正在运行,但应用还无法从外部访问。通过创建 service 可以实现这一点。cluster IP-address 是 service 在集群内部可用的 IP 地址。使用 master 节点的 IP 地址作为 external IP,service 就可以在集群外部访问了(例如在我这里是 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 节点的 IP 地址
$ 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 和我一样拔掉一些电源线 :-)