4

[Rancher 系列文] - Project, IaC 以及相關議題

 2 years ago
source link: https://www.hwchiu.com/rancher-6.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

[Rancher 系列文] - Project, IaC 以及相關議題

Posted on 2021-11-30

Views: 6

Rancher 系列文第六篇,探討創建 k8s 的方式

前幾篇文章探討了如何透過 Rancher 操作與管理 Kubernetes 叢集,不論是直接抓取 Kubeconfig 或是使用網頁上的 web terminal 來操作,此外也探討了 Rancher 整合的應用程式,特別是最重要的 Monitoring 該如何使用。

有了上述的概念後,使用者已經可以順利的操作 Kubernetes 來部署各種服務。
不過 Rancher 想做的事情可沒有這麼簡單, Rancher 希望能夠強化 Kubernetes 讓其更佳適合給多位使用者共同使用了。
對於這種多租戶的概念, Kubernetes 提供了 namespace 的機制來達到資源隔離,不過 namespace 普遍上被認為是個輕量級的隔離技術,畢竟 namespace 主要是邏輯層面的隔離,底層的運算與網路資源基本上還是共用的。

就算是 RKE 也沒有辦法完全顛覆 namespace 讓其變成真正的隔離技術,畢竟 CPU/Memory/Network 等相關資源因為 Container 的關係本來就很難切割,要達到如 VM 般真正隔離還不是這麼容易。
不過 Rancher 還是有別的方向可以去發展與強化,就是如何讓 Kubernetes 變得更適合一個團隊使用,如果該團隊內有數個不同的專案,這些專案要如何共同的使用一套 Kubernetes 叢集同時又可以有一個清楚且清晰的管理方式。

Project

Rancher 提出了一個名為 project 的概念,Project 是基於 Kubernetes Namespace 的實作的抽象管理概念,每個 Project 可以包含多個 namespace,同時 project 也會與 Rancher 內部的使用者權限機制整合。

從架構層面來看

  1. Rancher 管理了多套 Kubernetes 叢集
  2. Kubernetes 叢集管理多個 Project
  3. Project 擁有多個 namespace.

如同前面探討的, Kubernetes 原生提供的 namespace 機制是個輕量級虛擬化概念,所有 kubernetes 內的機制也都是以 namespace 為基礎去設計的,這意味者如果你今天要透過 RBAC 設定權限等操作你都需要針對 namespace 去仔細設計。但是 Rancher 認為一個產品專案可能不會只使用一個 namespace,而是會使用多個 namespace 來區隔不同的應用程式。
這種情況下你就必須要要針對每個 namespace 一個一個的去重複設定,從結果來說一樣可以達到效果,但是操作起來就是不停重複相同的動作。

透過 Rancher Project 的整合,叢集管理者可以達到

  1. 整合使用者群組權限,一口氣讓特定群組/使用者的人針對多個 namespace 去設定 RBAC
  2. 針對 Project 為單位去進行資源控管,一口氣設定多個 namespace 內 CPU/Memory 的使用量
  3. 套用 Pod Security Policy 到多個 namespace 中

因此實際上管理 Kubernetes 叢集就變成有兩種方式

  1. 完全忽略 Rancher 提供的 Project 功能,直接就如同其他 Kubernetes 版本一樣去操作
  2. 使用 Rancher 所設計的 Project 來管理

Rancher 會開發 Project 勢必有其好處,但是要不要使用就是另外一回事情,因為這個技術與概念是只有 Rancher 才有的,如果今天團隊同時擁有多套不同的 Kubernetes 叢集,有些用 Rancher 管理,有些沒有。
這種情況下也許不要使用 Rancher 工具而是採用盡可能原生統一的工具來管理會更好,因為可以避免團隊中使用的工具有太多的客製化行為,造成開發與維護都不容易。相反的使用所有 Kubernetes 發行版本都有的工具與管理方式反而有機會降低工具的複雜性。
所以到底要不要使用這類型的工具反而是見仁見智,請依據每個團隊需求去思考。

接下來就來看一下到底如何使用 Rancher Project 概念。

Project 因為是用來簡化同時操作多個 namespace 的一種概念,因此管理上會跟 namespace 放在一起。
Rancher 畫面上方的 Projects/Namespaces 就是用來管理這類型概念的,點選進去會看到類似下圖的版面。

UICDWE8.png

因為 Project 包含多個 namespace,所以版面中都是以 Project 為主,列出該 Project 底下有哪些 namespace,
Rancher 內的任何 Kubernetes 叢集預設都會有兩個 Projects,System 與 Default
System 內會放置任何跟 Rancher 以及 Kubernetes 有關的 namespace,譬如 cattle-system, fleet-system, kube-system, kube-public 等

Default 是預設的 Project,預設對應到 default 這個 namespace。
任何不是透過 Rancher 創立的 namespace 都不會加入到任何已知的 project 底下,因此圖片中最上方可以看到一堆 namespace,而這些 namespace 都不屬於任何一個 project。

因此要使用 project 的話就需要把這些 namespace 給搬移到對應的 project 底下。
圖中右上方有一個按鈕可以創立新的 Project,點下去可以看到如下畫面

ydCM1So.png

創立一個 Project 有四個資訊需要輸入,分別是

  1. 使用者權限
  2. Project 資源控管
  3. Container 資源控管
  4. Labels/Annotation.

使用者權限可以控制屬於什麼樣的使用者/群組可以對這個 Project 有什麼樣的操作。
Project 與 Container 的資源控管之後會有一篇來介紹
創立完 Project 之後就可以回到最外層的介面,將已經存在的 namespace 給掛到 project 底下

Yz8IOeR.png

譬如上述範例就將 cis-operator-system, longhorn-system 這兩個 namespace 給分配到剛剛創立的 project 底下。

XZdJPCI.png

之後重新進入到該 Project 去編輯,嘗試將 QA 使用群組加入到該 Project 底下,讓其變成 Project Owner,代表擁有完整權限。

7k81z5q.png

創造完畢後,就可以透過 UI 切換到不同的 project,如上圖所示,可以看到 ithome-dev 叢集底下有三個 Project,其中有兩個是預設的,一個是剛剛前述創立的。

3nrmPQM.png

切換到該 Project 之後,觀察當前的 URL 可以觀察到兩個有趣的ID,c-xxxx/p-xxxxx 會分別對應到 clusterID 以及 project ID,因此之後只要看到任何 ID 是 c-xxx 開頭的,基本上都是 Rancher 所創立的,跟 Cluster 有關,而 p-xxxx 開頭的則是跟 Project 有關,每個 Project 都勢必屬於某個 Cluster。

有了 ProjectID 之後,仿造之前透過 kubectl 去觀察使用者權限的方式,這次繼續觀察前述加入的 QA 群組會有什麼變化。

SrZBa1F.png

從上述指令中可以看到 QA 群組對應到一個新的 ClusterRole,叫做 p-p6xrd-namespaces-edit,其中 p-p6xrd 就是對應到前述創立的 project,而 edit 代表則是擁有 owner 般的權限,能夠去編輯任何資源。

接者更詳細的去看一下該 ClusterRole 的內容

PDuNUwr.png

可以看到該 ClusterRole 針對設定的兩個 namespace 都給予了 “*” 的動詞權限,基本上就是讓該使用者能夠如管理者般去使用這兩個 namespace。

除了上述的權限外,當切換到 Project 的頁面時,就可以看到從 Rancher 中去看到該 Project 底下 namespaces 內的相關 Kubernetes 物件資源,譬如下圖

b406bS0.png

Workloads 就是最基本的運算單元,譬如 Pod, Deployment, Job, DaemonSet..等
而 Config(ConfigMap), Secrets 可以看到整個叢集內的相關資源,此外 secret 透過網頁的可以直接看到透過 base64 解密後的結果。

註: Pipelines 請忽略他, v2.5 之後 Rancher 會主推使用 GitOps 的方式來部署,因此過往 pipeline 的方式這邊就不介紹了。

以 workloads 為範例,點進去後可以更詳細的去看當前系統中有哪些 workloads。

g5QcsvM.png

每個 workloads 旁邊都有一個選項可以打開,打開後會看到如上的選擇,這邊就有很多功能可以使用,譬如

  1. Add a Sidecar,可以幫忙加入一個 sidecar contaienr 進去
  2. Rollback 到之前版本
  3. Redeploy 重新部署
  4. 取得該 Pod 的 shell (如果該 workloads 底下有多種 pod,則不建議這邊使用這個功能)

基本上這些功能都可以透過 kubectl 來達到,網頁只是把 kubectl 要用的指令給簡化,讓他更輕鬆操作。
上述的範例 test 是使用 deployment 去部署的,點進去該 deployment 可以看到更詳細 pods 的資訊,如下

b0BWhyM.png

該畫面中就可以看到每個 Pod 的資訊,包含 Pod 的名稱,部署到哪個節點,同時也可以透過 UI 去執行該 Pod 的 shell 或是觀看相關 log。

以上就介紹了關於 Project 的基本概念。 Project 是 Rancher 內的最基本單位,因此要透過 Rancher 的 UI 去管理叢集內的各種部署資源則必須要先準備好相關的 Project,並且設定好每個 Project 對應的 namespace 以及使用者權限。

當然 Rancher Project 不是一個一定要使用的功能,因為也是有團隊單純只是依賴 Rancher 去部署 Kubernetes 叢集,而繼續使用本來的方式來管理與部署 Kubernetes 叢集,畢竟現在有很多種不同的專案可以提供 Kubernetes 內的資源狀況。一切都還是以團隊需求為主。

資源控管介紹

熟悉 Kubernetes 的讀者應該都知道資源控管是一個非常困難的問題,其根本原因是 Container 本身的實作方式導致資源控管不太容器。
很多人使用資源控管最常遇到的問題有

  1. 不知道該怎麼設定 Resources Limit, CPU/Memory 到底要用哪種? 三種內建的 QoS 型態有哪些? 有哪些影響?
  2. 設定好了 Limit/Request 後結果運作不如預期,或是某些情況下應用程式效能大幅度降低等

第一點是最容易遇到的,畢竟要如何有效地去分配容器使用的 CPU/Memory 是個很困難的問題,特別是第一次踏入到容器化的團隊對於這個問題會有更大的疑惑,不確定該怎麼用。
第二個問題則是部分的 Linux Kernel 版本實作 Container 的資源控管與限制上會有一些 bug,可能會導致你的應用程式被不預期的 throttle,導致效能變得很低。

本篇文章不太探討這兩個問題,反而是探討最基本的概念,畢竟上述兩個概念跟 Rancher 沒太大關係,反而是比較進階使用與除錯的內容。

Kubernetes 中針對 CPU/Memory 等系統資源有兩種限制,稱為 Request 與 Limit。
Request 代表的是要求多少,而 Limit 代表的是最多可以使用多少。
這些資源是以 Container 為基本單位,而 Pod 本身是由多個 Container 組成的,所以 CPU/Memory 的計算上就相對繁瑣。

Kubernetes 本身有一個特別的物件稱為 ResourceQuota,透過該物件可以針對特定 namespace 去限定該 namespace 內所有 Container 的資源上限。譬如可以設定 default namespace 最多只能用 10顆 vCPU,超過的話就沒有辦法繼續部署。

Rancher 的 Project 本身就是一個管理多 namespace 的抽象概念,接下來看一下 Project 中有哪些關於 Resource 的管理。

為了方便操作,先將 default namespace 給加入到之前創立的 Project 中,加進去後當前 project 中有三個 namespace,如下圖。

ZeRon6T.png

接者編輯該 Project 去設定 Resource 相關的資訊,如下圖

dGxmeOh.png

Project 中有兩種概念要設定,第一種是 Resource Quota,第二個是 Container Default Resource Limit.
Resource Quota 是更高階層的概念,是用來控管整個 Project 能夠使用的 CPU/Memory 用量。
由於 Project 是由多個 namespaces 所組成的,所以設定上還要去設定每個 namespace 的用量,如上述範例就是設定
整個 Project 可以使用 100個 vCPU,而每個 namespace 最多可以使用 10 vCPU。
但是因為 namespace 本身就是使用 kubernetes ResourceQuota 來實作,而這個功能本身會有一個限制就是。
一但該 namespace 本身設定了 ResourceQuota,則所有部署到該 namespace 的容器都必須要明確的寫出 CPU/Memory 用量。

這個概念也滿容易理解的,畢竟你要去計算 namespace 的使用上限,那 namespace 內的每個 container 都需要有 CPU/Memory 等相關設定,否則不能計算。
如果你的容器沒有去設定的話,你的服務會沒有辦法部署,會卡到 Scheduler 那個層級,連 Pending 都不會有。
但是如果要求每個容器部署的時候都要設定 CPU/Memory 其實會有點煩人,為了讓這個操作更簡單,Project 底下還有 Container Default Resource Limit 的設定。
該設定只要打開,所有部署到該 namespace 內的 Container 都會自動的補上這些設定。
如上圖的概念就是,每個 Container 部署時就會被補上 CPU(Request): 3顆, CPU(Limit): 6顆

這邊有一個東西要特別注意,Project 設定的 Container Default Resource Limit 本身有一個使用限制,如果 namespace 是再設定 Resource Quota 前就已經加入到 Project 的話,設定的數字並不會自動地套用到所有的 namespace 上。
反過來說,設定好這些資訊後,所有新創立的 namespace 都會自動沿用這些設定,但是設定前的 namespace 需要手動設定。

所以這時候必須要回到 namespace 上去重新設定,如下圖

UqlqrmS.png

namespace 的編輯頁面就可以重新設定該 namespace 上的資訊,特別是 Container Default Resource Limit。
當這邊重新設定完畢後,就可以到系統中去看相關的物件

首先 Project 設定好 Resource Quota 後,Kubernetes 就會針對每個 namespace 都產生一個對應的 Quota 來設定,如下

SoOUiga.png

因為設定每個 namespace 的 CPU 上限是 10顆,而該 project 總共有三個 namespace,所以系統中這三個 namespace 都產生了對應的 quota,而這些 quota 的設定都是 10顆 CPU。

其中 default namespace 的標示是 5025m/10 代表目前已經用了 5.025顆 CPU,而系統上限是 10顆。

nq6X7fH.png

這時候將 default namespace 內的 pod 都清空,接者重新再看一次該 quota 物件就會發現 used 的數值從 5025m 到 0。

fiihnjl.png

由於上述 default namespace 中設定 CPU 預設補上 0.1顆 CPU (Request/Limit),所以 Kubernetes 會創造相關的物件 Limits

xUGhx8X.png
Jg7JvKb.png

從上述物件可以觀察到該 LimitRange 設定了 100m 的 CPU。

最後嘗試部署一個簡單的 deployment 來測試此功能看看,使用一個完全沒有標示任何 Resource 的 deployment,內容如下。

Ln1SnNw.png
OOsDiOY.png

該物件部署到叢集後,透過 kubectl describe 去查看一下這些 Pod 的狀態,可以看到其 Resource 被自動的補上 Limits/Requests: 100m。

5drPVJM.png

Resource 的管理一直以來都不容易, Rancher 透過 Project 的管理方式讓團隊可以更容易的去管理多 namespace 之間的資源用量,同時也可以透過這個機制要求所有要部署的 container 都要去設定資源用量來確保不會有容器使用過多的資源。

其他注意事項

之前文章探討過三種不同安裝 Kubernetes 的方式,其中一種方式是運行 docker command 在現有的節點上將該節點加入到 RKE 叢集中。

但是如果今天有需求想將該節點從 RKE 中移除該怎麼辦?

K9JI1WS.png

Cluster Manager 中可以直接到 Cluster 頁面將該節點從 RKE 中移除,但是要注意的是,這邊的移除代表的只是將該節點從 RKE 移除,該節點上可能會有一些因為加入 RKE 而產生的檔案依然存在節點上。

假設今天有需求又要將該節點重新加入回到 RKE 中的話,如果上次移除時沒有妥善地去刪除那些檔案的話,第二次運行 docker command 去加入 RKE 叢集有非常大的機率會失敗,因為節點中有太多之前的產物存在。

官網有特別撰寫一篇文章探討如果要清除這些產物的話,有哪些資源要處理,詳細版本可以參閱 Removing Kubernetes Components from Nodes

這邊列舉一下一個清除節點正確步驟

  1. 從 Rancher UI 移除該節點
  2. 重啟該節點,確保所有放到暫存資料夾的檔案都會消失
  3. Docker 相關資料
  4. Mount 相關資訊都要 umount
  5. 移除資料夾
  6. 移除多的網卡
  7. 移除多的 iptables 規則
  8. 再次重開機

第三點移除 docker 相關資料,官方列出三個指令,分別移除 container, volume 以及 image。

docker rm -f $(docker ps -qa)
docker rmi -f $(docker images -q)
docker volume rm $(docker volume ls -q)

如果該節點接下來又要重新加入到 Rancher 中,建議不需要執行 docker rmi 的步驟,之前的 image 可以重新使用不需要重新抓取,這樣可以省一些時間。

第四點的 mount 部分要注意的是,官文文件沒有特別使用 sudo 的指令於範例中,代表其假設你會使用 root 身份執行,因此如果不是使用 root 的話記得要在 umount 指令中補上 sudo

for mount in $(mount | grep tmpfs | grep '/var/lib/kubelet' | awk '{ print $3 }') /var/lib/kubelet /var/lib/rancher; do sudo umount $mount; done

第五點跟第四點一樣,但是第五點非常重要,因為系統上有太多的資料夾都含有過往 RKE 叢集的資料,所以第五步一定要確保需要執行才可以將資料清除。

sudo rm -rf /etc/ceph \
/etc/cni \
/etc/kubernetes \
/opt/cni \
/opt/rke \
/run/secrets/kubernetes.io \
/run/calico \
/run/flannel \
/var/lib/calico \
/var/lib/etcd \
/var/lib/cni \
/var/lib/kubelet \
/var/lib/rancher/rke/log \
/var/log/containers \
/var/log/kube-audit \
/var/log/pods \
/var/run/calico

第六跟第七這兩步驟並不一定要處理,因為這些資訊都是節點加入到 Kubernetes 後被動態創建的,基本上重開機就不會有這些資訊,只要確保節點重新開機後沒有繼續成為 Kubernetes 的節點,那相關的虛擬網卡跟 iptables 規則也就不會被產生。

要注意的是官方文件中的所有步驟不一定都會有東西可以刪除,主要會取決於叢集內的設定,不同的設定可能會有不同的結果,譬如採用不同的 CNI,其產生的 iptables 規則與虛擬網卡就會有所不同。

雖然雲端環境方便存取,但是很多產業與環境可能會需要於一個沒有對外網路的環境下去安裝 Kubernetes 叢集,這種情況下如果想要使用 Rancher 的話就要探討如何達到離線安裝。

Rancher 講到離線安裝有兩種含義,一種是

  1. Rancher 本身的離線安裝
  2. Rancher 以離線安裝的方式幫忙創建 RKE 叢集

上述兩種方式其實都還是仰賴各式各樣的 container image 來處理,所以處理的方法一致,就是要安裝一個 container registry 並且將會需要使用的 container image 都事先匯入到該 container registry 中,接者安裝時要讓系統知道去哪下載相關的 container image 即可。

官網有數篇文章探討這種類型下的安裝該怎麼處理,有興趣的也可以參考 Air Gapped Helm CLI Install

由於安裝 Rancher 本身有很多方式,譬如多節點的 RKE 或是單節的 Docker 安裝,以下簡述一下如何用 Docker 達成單節點的離線安裝。

  1. 架設一個 Private Container Registry
  2. 透過 Rancher 準備好的腳本去下載並打包 Rancher 會用到的所有 Container Image
  3. 把第二步驟產生 Container Image 檔案給匯入到 Private Container Registry
  4. 運行修改過後的 Docker 來安裝 Rancher.

第一點這邊有幾點要注意
a. 可以使用 container registry v2 或是使用 harbor
b. 一定要幫該 container registry 準備好一個憑證,這樣使用上會比較方便,不用太多地方要去處理 invalid certificate 的用法。憑證的部分可以自簽 CA 或是由一個已知信任 CA 簽署的。
c. image 的容量大概需要 28 GB 左右,因此準備環境時要注意空間

第二跟第三點直接參閱官網的方式,先到 GitHub 的 Release Page 找到目標版本,接者下載下列三個檔案

  1. rancher-images.txt
  2. rancher-save.images.sh
  3. rancher-load-images.sh

第二個腳本會負責去下載 rancher-images.txt 中描述的檔案並且打包成一個 tar 檔案,系統中會同時存放 container image 以及 tar 檔,所以最好確保空間有 60GB 以上的足夠空間。
第三個腳本會將該 tar 檔案的內容上傳到目標 container registry。

這一切都準備完畢後,就可以執行 docker 指令,可以參閱Docker Install Commands

一個範例如下

docker run -d --restart=unless-stopped \
-p 80:80 -p 443:443 \
-v /mysite/fullchain.pem:/etc/rancher/ssl/cert.pem \
-v /mysite/previkey.pem>:/etc/rancher/ssl/key.pem \
-e CATTLE_SYSTEM_DEFAULT_REGISTRY=test.hwchiu.com \ # Set a default private registry to be used in Rancher
-e CATTLE_SYSTEM_CATALOG=bundled \ # Use the packaged Rancher system charts
--privileged
registry.hwchiu.com/rancher/rancher:v2.5.9 \
--no-cacerts

請特別注意上述的參數,不同的憑證方式會傳入的資訊不同,自簽的方式還要額外把 CA_CERTS 給丟進去。

試想下列情境,是否會覺得某些情況還是有點卡?

  1. 公司想要有針對不同環境有不同的 Rancher 叢集,譬如 Production 跟其他要分開
  2. 希望能夠減少管理員透過 UI 管理的頻率,畢竟透過 UI 點選創建有時並不會有太完善的稽核性
  3. 有快速重複部署 RKE 叢集的需求,某些情況還需要刪除重建

上述這些要求全部都可以用之前分享的方式慢慢處理,不過會不會有更好的方式處理?
這幾年流行的 IaC 架構, Infrastructure as Code 的概念能不能套用到 Rancher 身上?
試想一下如果可以透過程式碼的方式定義 Rancher,對於開發者與管理者來說可以達到什麼樣的好處

  1. 當 Rancher 整個損毀,需要重新安裝或是需要部署類似環境時,可以非常快的部署,不需要重新透過手動的方式去重新設定所有細節
  2. 所有重大操作都以程式碼為基礎去設定,減少任何人為操作的可能性,同時有任何出錯時可以基於程式碼重新部署來修復環境。
  3. 複製程式碼就可以複製環境,修改一些變數就可以創建出類似的叢集

更重要的是,如果將這些 IaC 的概念與 CI/CD 流程整合,還可以透過 Code Review 的方式來合作檢視所有 Rancher 上的修改,同時透過自動化的方式去維護 Rancher 服務。
有任何不適當的修改想要復原也可以透過 Git Revert 的方式來回復到之前的狀態。
這種狀況下 Rancher 會變得更加容易維護與管理。

IaC 的工具非常的多,當人們講到跟 Cloud Infrastructure 有關時,大部分人都會提到 Terraform 這套解決方案,而近年 Pulumi 的聲勢也漸漸提昇,愈來愈多人嘗試使用 Pulumi 來取代 Terraform,兩者最大的差別在於撰寫方式。
Terraform 有自己設計一套語法,意味使用 Terraform 就要使用該語法,而 Pulumi 則是基於不同的程式語言提供不同的 API 來使用ㄓ,所以開發者可以使用自己習慣的程式語言去撰寫。

接下來將介紹如何透過 Terraform 來管理我們的 Rancher,之後的章節有機會的話也會順便展示一下使用 Terraform 的寫法。

Terraform

由於重點是 Rancher,因此就不會探討太多 Terraform 的基本概念與使用方式,會更加專注於如何透過 Terraform 來管理 Rancher。

Terraform 官網中有非常詳細的資訊探討 Rancher 所有 API 的使用方式,有興趣可以參閱Rancher2 Provider

為了要能夠跟 Rancher 溝通,必須要先獲得一組 Access/Secrey Key 來存取 Rancher,這組 Key 可以從 Rancher 的使用者帳號去取得。

首先用一個可以管理 Rancher 的帳號登入到 Rancher UI,接者於右上方使用者那邊去點選 API & Keys,如下圖。

KgJ6v60.png

進去之後可以看到系統預設有一些 Key,這些忽略即可。
要注意的是,每組 Key 產生後都會得到一組對應的 Secret Key,該 Key 是沒有辦法透過 UI 找回來的,這意味如果你當下忘了儲存或是之後不見了,那這把 secret key 就再也沒有辦法找回。

點選右上方的 Add Key 可以看到如下的畫面,該畫面可以先設定該 Key 會不會自動過期的時間,以及使用範圍。

Xip7yz6.png

設定名稱後就會看到如下圖的畫面,畫面中有四種相關不同的資訊,分別是

  1. Access Endpoint: 存取的 API 位置
  2. Access Key
  3. Secret Key(只有這邊會出現,一但按下 Close 就再也拿不回來了)
  4. 針對 HTTP 需求譬如 kubectl 是有機會直接使用最後一個 Bearer Token 使用

gBJ7sKJ.png

這次的 Terraform 要使用前三組資訊,這邊不考慮任何 Terraform 的撰寫技巧與 Style,單純用最簡單的風格來介紹如何將 Terraform 與 Rancher 整合。

以下示範是基於 Terraform 1.0 與 Rancher Provider 1.17.0 的版本

首先準備一個 main.tf 的檔案,內容如下

╰─$ cat main.tf
terraform {
required_providers {
rancher2 = {
source = "rancher/rancher2"
version = "1.17.0"
}
}
}

provider "rancher2" {
api_url = "https://rancher.hwchiu.com"
access_key = "token-ng6df"
secret_key = "l8kjh7w5mdb5s5nzmp56c5rctpt59p9bcq9wbw2g8b66wsdchrkdv2"
}

接者透過 Terraform init 先初始化相關模組

╰─$ terraform init
Initializing the backend...

Initializing provider plugins...
- Finding rancher/rancher2 versions matching "1.17.0"...
- Installing rancher/rancher2 v1.17.0...
- Installed rancher/rancher2 v1.17.0 (signed by a HashiCorp partner, key ID 2EEB0F9AD44A135C)

Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

一切都準備完畢後,接下來示範一下如何透過 Rancher 來創造一些 Rancher 的資源,譬如說來創造一個 RKE Template

這邊直接參考範例將下列內容寫入到 main.tf 中
該範例會創建一個 RKE Template 並且針對 etcd 以及一些更新策略進行設定。

$ cat main.tf
terraform {
required_providers {
rancher2 = {
source = "rancher/rancher2"
version = "1.17.0"
}
}
}

provider "rancher2" {
api_url = "https://rancher.hwchiu.com"
access_key = "token-ng6df"
secret_key = "l8kjh7w5mdb5s5nzmp56c5rctpt59p9bcq9wbw2g8b66wsdchrkdv2"
}

resource "rancher2_cluster_template" "foo" {
name = "ithome_terraforn"
template_revisions {
name = "V1"
cluster_config {
rke_config {
network {
plugin = "canal"
}
services {
etcd {
creation = "6h"
retention = "24h"
}
}
upgrade_strategy {
drain = true
max_unavailable_worker = "20%"
}
}
}
default = true
}
description = "Terraform cluster template foo"
}

接者透過 terraform apply 去更新

$ terraform apply
...
+ rke_config {
+ addon_job_timeout = 0
+ ignore_docker_version = true
+ kubernetes_version = (known after apply)
+ prefix_path = (known after apply)
+ ssh_agent_auth = false
+ ssh_cert_path = (known after apply)
+ ssh_key_path = (known after apply)
+ win_prefix_path = (known after apply)

+ network {
+ mtu = 0
+ options = (known after apply)
+ plugin = "canal"
}

+ services {
+ etcd {
+ ca_cert = (known after apply)
+ cert = (sensitive value)
+ creation = "6h"
+ extra_args = (known after apply)
+ gid = 0
+ image = (known after apply)
+ key = (sensitive value)
+ path = (known after apply)
+ retention = "24h"
+ snapshot = false
+ uid = 0
}
}

+ upgrade_strategy {
+ drain = true
+ max_unavailable_controlplane = "1"
+ max_unavailable_worker = "20%"
}
}
}
}
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.

Enter a value: yes

rancher2_cluster_template.foo: Creating...
rancher2_cluster_template.foo: Creation complete after 2s [id=cattle-global-data:ct-rtd4f]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

一切創造完畢後就可以移動到 Rancher UI 中,從 RKE Template 可以看到多出了一個新的 RKE Template,名稱為 ithome_terraform,與我們前述 main.tf 中描述的一樣。

VISDJn9.png

點進去該 RKE Template 就可以看到詳細的設定,這邊要補充一下, Rancher 大部分的物件都提供兩種閱覽模式,一種是友善的 UI 介面另一種則是純 YAML 的描述檔案。
按照下方的方式點選 View as a Form 來看看基於 YAML 的內容。

o8W7jBz.png

從 YAML 內就可以看到 Terraform 描述的設定都有正確的寫進來。

LUrbVVN.png

透過這樣簡單的方式,就可以使用程式碼的方式來管理 Rancher,除了 RKE Template 之外, Cloud Credential, Node Template, Cluster 也都可以透過 Terraform 的方式來管理,這樣有另外一個好處就是系統管理員只要撰寫好這些資源後,接下來的使用者就不需要接觸到這些太細節的機密資訊,能夠專心的目標資源與邏輯去描述與創造即可。

最後這邊要再補充一個使用 API 溝通 Rancher 的好處,事實上, Rancher UI 沒有辦法展現 Rancher 100% 的能力, RKE 內有非常多的設定可以處理,但是有些處理實際上沒有辦法透過 UI 去設定,譬如說想要針對 Kubelet 給一些額外參數的話,這些設定是沒有辦法從 Rancher UI 完成的,但是如果是透過 Rancher API 來設定的話就沒有問題。

Rancher API 有很多方式可以處理,不論是直接撰寫應用程式溝通 Rancher 或是使用 Terraform/Pulumi 等工具都可以,透過這類型工具去描述 Rancher 實際上可以將 Rancher 使用的更靈活與更強大,設定的東西也更多元化。

如果團隊有意願長期使用 Rancher,會非常推薦使用 IaC 的工具來維護與管理 Rancher,期帶來得好非常的多。

我目前於 Hiskio 平台上面有開設 Kubernetes 相關課程,歡迎有興趣的人參考並分享,裡面有我從底層到實戰中對於 Kubernetes 的各種想法

詳細可以參閱
線上課程詳細資訊: https://course.hwchiu.com/

另外,歡迎按讚加入我個人的粉絲專頁,裡面會定期分享各式各樣的文章,有的是翻譯文章,也有部分是原創文章,主要會聚焦於 CNCF 領域
https://www.facebook.com/technologynoteniu

如果有使用 Telegram 的也可以訂閱下列頻道來,裡面我會定期推播通知各類文章
https://t.me/technologynote

你的捐款將給予我文章成長的動力


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK