Linux中國

使用 k3s 在 Fedora IoT 上運行 K8S

Fedora IoT 是一個即將發布的、面向物聯網的 Fedora 版本。去年 Fedora Magazine 的《如何使用 Fedora IoT 點亮 LED 燈》一文第一次介紹了它。從那以後,它與 Fedora Silverblue 一起不斷改進,以提供針對面向容器的工作流的不可變基礎操作系統。

Kubernetes 是一個頗受歡迎的容器編排系統。它可能最常用在那些能夠處理巨大負載的強勁硬體上。不過,它也能在像樹莓派 3 這樣輕量級的設備上運行。讓我們繼續閱讀,來了解如何運行它。

為什麼用 Kubernetes?

雖然 Kubernetes 在雲計算領域風靡一時,但讓它在小型單板機上運行可能並不是常見的。不過,我們有非常明確的理由來做這件事。首先,這是一個不需要昂貴硬體就可以學習並熟悉 Kubernetes 的好方法;其次,由於它的流行性,市面上有大量應用進行了預先打包,以用於在 Kubernetes 集群中運行。更不用說,當你遇到問題時,會有大規模的社區用戶為你提供幫助。

最後但同樣重要的是,即使是在家庭實驗室這樣的小規模環境中,容器編排也確實能夠使事情變得更加簡單。雖然在學習曲線方面,這一點並不明顯,但這些技能在你將來與任何集群打交道的時候都會有幫助。不管你面對的是一個單節點樹莓派集群,還是一個大規模的機器學習場,它們的操作方式都是類似的。

K3s - 輕量級的 Kubernetes

一個「正常」安裝的 Kubernetes(如果有這麼一說的話)對於物聯網來說有點沉重。K8s 的推薦內存配置,是每台機器 2GB!不過,我們也有一些替代品,其中一個新人是 k3s —— 一個輕量級的 Kubernetes 發行版。

K3s 非常特殊,因為它將 etcd 替換成了 SQLite 以滿足鍵值存儲需求。還有一點,在於整個 k3s 將使用一個二進位文件分發,而不是每個組件一個。這減少了內存佔用並簡化了安裝過程。基於上述原因,我們只需要 512MB 內存即可運行 k3s,極度適合小型單板電腦!

你需要的東西

  1. Fedora IoT 運行在虛擬機或實體設備中運行的。在這裡可以看到優秀的入門指南。一台機器就足夠了,不過兩台可以用來測試向集群添加更多節點。
  2. 配置防火牆,允許 6443 和 8372 埠的通信。或者,你也可以簡單地運行 systemctl stop firewalld 來為這次實驗關閉防火牆。

安裝 k3s

安裝 k3s 非常簡單。直接運行安裝腳本:

curl -sfL https://get.k3s.io | sh -

它會下載、安裝並啟動 k3s。安裝完成後,運行以下命令來從伺服器獲取節點列表:

kubectl get nodes

需要注意的是,有幾個選項可以通過環境變數傳遞給安裝腳本。這些選項可以在文檔中找到。當然,你也完全可以直接下載二進位文件來手動安裝 k3s。

對於實驗和學習來說,這樣已經很棒了,不過單節點的集群也不能算一個集群。幸運的是,添加另一個節點並不比設置第一個節點要難。只需要向安裝腳本傳遞兩個環境變數,它就可以找到第一個節點,而不用運行 k3s 的伺服器部分。

curl -sfL https://get.k3s.io | K3S_URL=https://example-url:6443 
  K3S_TOKEN=XXX sh -

上面的 example-url 應被替換為第一個節點的 IP 地址,或一個完全限定域名。在該節點中,(用 XXX 表示的)令牌可以在 /var/lib/rancher/k3s/server/node-token 文件中找到。

部署一些容器

現在我們有了一個 Kubernetes 集群,我們可以真正做些什麼呢?讓我們從部署一個簡單的 Web 伺服器開始吧。

kubectl create deployment my-server --image nginx

這會從名為 nginx 的容器鏡像中創建出一個名叫 my-server部署(默認使用 docker hub 註冊中心,以及 latest 標籤)。

kubectl get pods

為了訪問到 pod 中運行的 nginx 伺服器,首先通過一個 服務 來暴露該部署。以下命令將創建一個與該部署同名的服務。

kubectl expose deployment my-server --port 80

服務將作為一種負載均衡器和 Pod 的 DNS 記錄來工作。比如,當運行第二個 Pod 時,我們只需指定 my-server(服務名稱)就可以通過 curl 訪問 nginx 伺服器。有關如何操作,可以看下面的實例。

# 啟動一個 pod,在裡面以交互方式運行 bash
kubectl run debug --generator=run-pod/v1 --image=fedora -it -- bash
# 等待 bash 提示符出現
curl my-server
# 你可以看到「Welcome to nginx!」的輸出頁面

Ingress 控制器及外部 IP

默認狀態下,一個服務只能獲得一個 ClusterIP(只能從集群內部訪問),但你也可以通過把它的類型設置為 LoadBalancer 為該服務申請一個外部 IP。不過,並非所有應用都需要自己的 IP 地址。相反,通常可以通過基於 Host 請求頭部或請求路徑進行路由,從而使多個服務共享一個 IP 地址。你可以在 Kubernetes 使用 Ingress 完成此操作,而這也是我們要做的。Ingress 也提供了額外的功能,比如無需配置應用即可對流量進行 TLS 加密。

Kubernetes 需要 Ingress 控制器來使 Ingress 資源工作,k3s 包含 Traefik 正是出於此目的。它還包含了一個簡單的服務負載均衡器,可以為集群中的服務提供外部 IP。這篇文檔描述了這種服務:

k3s 包含一個使用可用主機埠的基礎服務負載均衡器。比如,如果你嘗試創建一個監聽 80 埠的負載均衡器,它會嘗試在集群中尋找一個 80 埠空閑的節點。如果沒有可用埠,那麼負載均衡器將保持在 Pending 狀態。

k3s README

Ingress 控制器已經通過這個負載均衡器暴露在外。你可以使用以下命令找到它正在使用的 IP 地址。

$ kubectl get svc --all-namespaces
NAMESPACE     NAME         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
 default       kubernetes   ClusterIP      10.43.0.1               443/TCP                      33d
 default       my-server    ClusterIP      10.43.174.38            80/TCP                       30m
 kube-system   kube-dns     ClusterIP      10.43.0.10              53/UDP,53/TCP,9153/TCP       33d
 kube-system   traefik      LoadBalancer   10.43.145.104   10.0.0.8      80:31596/TCP,443:31539/TCP   33d

找到名為 traefik 的服務。在上面的例子中,我們感興趣的 IP 是 10.0.0.8。

路由傳入的請求

讓我們創建一個 Ingress,使它通過基於 Host 頭部的路由規則將請求路由至我們的伺服器。這個例子中我們使用 xip.io 來避免必要的 DNS 記錄配置工作。它的工作原理是將 IP 地址作為子域包含,以使用 10.0.0.8.xip.io 的任何子域來達到 IP 10.0.0.8。換句話說,my-server.10.0.0.8.xip.io 被用於訪問集群中的 Ingress 控制器。你現在就可以嘗試(使用你自己的 IP,而不是 10.0.0.8)。如果沒有 Ingress,你應該會訪問到「默認後端」,只是一個寫著「404 page not found」的頁面。

我們可以使用以下 Ingress 讓 Ingress 控制器將請求路由到我們的 Web 伺服器的服務。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-server
spec:
  rules:
    - host: my-server.10.0.0.8.xip.io
      http:
        paths:
          - path: /
            backend:
              serviceName: my-server
              servicePort: 80

將以上片段保存到 my-ingress.yaml 文件中,然後運行以下命令將其加入集群:

kubectl apply -f my-ingress.yaml

你現在應該能夠在你選擇的完全限定域名中訪問到 nginx 的默認歡迎頁面了。在我的例子中,它是 my-server.10.0.0.8.xip.io。Ingress 控制器會通過 Ingress 中包含的信息來路由請求。對 my-server.10.0.0.8.xip.io 的請求將被路由到 Ingress 中定義為 backend 的服務和埠(在本例中為 my-server80)。

那麼,物聯網呢?

想像如下場景:你的家或農場周圍有很多的設備。它是一個具有各種硬體功能、感測器和執行器的物聯網設備的異構集合。也許某些設備擁有攝像頭、天氣或光線感測器。其它設備可能會被連接起來,用來控制通風、燈光、百葉窗或閃爍的 LED。

這種情況下,你想從所有感測器中收集數據,在最終使用它來制定決策和控制執行器之前,也可能會對其進行處理和分析。除此之外,你可能還想配置一個儀錶盤來可視化那些正在發生的事情。那麼 Kubernetes 如何幫助我們來管理這樣的事情呢?我們怎麼保證 Pod 在合適的設備上運行?

簡單的答案就是「標籤」。你可以根據功能來標記節點,如下所示:

kubectl label nodes <node-name> <label-key>=<label-value>
# 舉例
kubectl label nodes node2 camera=available

一旦它們被打上標籤,我們就可以輕鬆地使用 nodeSelector 為你的工作負載選擇合適的節點。拼圖的最後一塊:如果你想在所有合適的節點上運行 Pod,那應該使用 DaemonSet 而不是部署。換句話說,應為每個使用唯一感測器的數據收集應用程序創建一個 DaemonSet,並使用 nodeSelector 確保它們僅在具有適當硬體的節點上運行。

服務發現功能允許 Pod 通過服務名稱來尋找彼此,這項功能使得這類分散式系統的管理工作變得易如反掌。你不需要為應用配置 IP 地址或自定義埠,也不需要知道它們。相反,它們可以通過集群中的命名服務輕鬆找到彼此。

充分利用空閑資源

隨著集群的啟動並運行,收集數據並控制燈光和氣候,可能使你覺得你已經把它完成了。不過,集群中還有大量的計算資源可以用於其它項目。這才是 Kubernetes 真正出彩的地方。

你不必擔心這些資源的確切位置,或者去計算是否有足夠的內存來容納額外的應用程序。這正是編排系統所解決的問題!你可以輕鬆地在集群中部署更多的應用,讓 Kubernetes 來找出適合運行它們的位置(或是否適合運行它們)。

為什麼不運行一個你自己的 NextCloud 實例呢?或者運行 gitea?你還可以為你所有的物聯網容器設置一套 CI/CD 流水線。畢竟,如果你可以在集群中進行本地構建,為什麼還要在主計算機上構建並交叉編譯它們呢?

這裡的要點是,Kubernetes 可以更容易地利用那些你可能浪費掉的「隱藏」資源。Kubernetes 根據可用資源和容錯處理規則來調度 Pod,因此你也無需手動完成這些工作。但是,為了幫助 Kubernetes 做出合理的決定,你絕對應該為你的工作負載添加資源請求配置。

總結

儘管 Kuberenetes 或一般的容器編排平台通常不會與物聯網相關聯,但在管理分散式系統時,使用一個編排系統肯定是有意義的。你不僅可以使用統一的方式來處理多樣化和異構的設備,還可以簡化它們的通信方式。此外,Kubernetes 還可以更好地對閑置資源加以利用。

容器技術使構建「隨處運行」應用的想法成為可能。現在,Kubernetes 可以更輕鬆地來負責「隨處」的部分。作為構建一切的不可變基礎,我們使用 Fedora IoT。

via: https://fedoramagazine.org/kubernetes-on-fedora-iot-with-k3s/

作者:Lennart Jern 選題:lujun9972 譯者:StdioA 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國