本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。
创建一个运行 Kubernetes 的树莓派集群,安装(第 2 部分)
在比利时 Devoxx 和摩洛哥 Devoxx 大会上,Ray Tsang 和我(Arjen Wassink)展示了我们在 Quintor 搭建的运行 HypriotOS、Docker 和 Kubernetes 的树莓派集群。尽管我们的演讲收到了很多赞扬,但最常见的问题是如何自己构建一个 Pi 集群!我们将分两部分完成这个任务。第一部分介绍了集群的采购清单,第二部分将向您展示如何让 Kubernetes 运行起来。
现在您已经搭建好了树莓派集群,是时候在上面运行一些软件了。正如上一篇博客中提到的,本教程基于 ARM 处理器的 Hypriot Linux 发行版。主要原因是其捆绑支持 Docker。本教程我使用了这个版本的 Hypriot,因此如果您在使用其他版本的 Hypriot 时遇到问题,请考虑使用我提供的版本。
第一步是确保每个 Pi 都运行 Hypriot,如果还没有,请查阅他们的入门指南。另外,将集群交换机连接到网络,以便提供互联网访问,并通过 DHCP 为每个 Pi 分配 IP 地址。由于我们将运行多个 Pi,为每个 Pi 分配一个唯一的主机名会很实用。为了方便起见,我将我的 Pi 重命名为 rpi-master、rpi-node-1、rpi-node-2 等。请注意,在 Hypriot 上,主机名是通过编辑 /boot/occidentalis.txt 文件设置的,而不是 /etc/hostname。您也可以使用 Hypriot 刷机工具设置主机名。
在树莓派上运行软件最重要的方面是 ARM 发行版的可用性。感谢 Brendan Burns,Google Cloud Registry 中提供了适用于 ARM 的 Kubernetes 组件。这太棒了。第二个难点是如何安装 Kubernetes。有两种方法:直接在系统上安装或在 Docker 容器中安装。尽管容器支持仍处于实验阶段,但我选择使用它,因为它能让 Kubernetes 的安装变得更简单。Kubernetes 要求在节点上运行多个进程(etcd、flannel、kubectl 等),这些进程应按特定顺序启动。为了简化这一点,我们提供了 systemd 服务来以正确的方式启动必要的进程。systemd 服务还确保在节点(重新)启动时 Kubernetes 能够启动。为了使安装变得非常简单,我为主节点和工作节点创建了一个简单的安装脚本。所有内容都可以在 GitHub 上找到。那么,现在就开始吧!
安装 Kubernetes 主节点
首先我们将在主节点上安装 Kubernetes,稍后将工作节点添加到集群中。这基本上归结为获取 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 主服务,提供集群功能。
此安装过程的基本细节也在 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 集群的主节点了。ARM 版的 Kubectl 可以从 googleapis 存储下载。`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 地址。使用主节点的 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 工作节点
下一步是在每个工作节点上安装 Kubernetes 并将其添加到集群中。这基本上也归结为获取 git 仓库内容并执行安装脚本。尽管在此安装中,需要预先复制 k8s.conf 文件并进行编辑,使其包含主节点的 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 地址更改为与主节点匹配
$ k8s-on-rpi-master/install-k8s-worker.sh
安装脚本将安装四个服务。这些服务与主节点上的服务非常相似,但区别在于没有运行 etcd 服务,并且 kubelet 服务被配置为工作节点。
一旦工作节点上的所有服务都已启动并运行,我们就可以在主节点上检查该节点是否已添加到集群中。
$ 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 树莓派集群现在已经运行起来了,您可以开始使用 Kubernetes 并进行学习。查阅 Kubernetes 用户指南以了解您可以做的所有事情。别忘了偶尔拔掉一些插头,就像 Ray 和我那样 :-)