本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

建立一個執行 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 和我那樣 :-)