Kubernetes應用編排神器Kustomize入門教程
將應用程序部署到 Kubernetes 上并不容易,我們需要部署 Deployment 的 Pod,并在 Service 中定義可訪問性。所有的這些資源都需要 YAML 文件才能正確定義和配置。
其中有一點很重要,應用程序可能需要與數據庫進行通信、管理 Web 內容以及設置日志記錄。此外,這些參數會由于部署環境的不同而有所不同。以上這些都可能導致 YAML 定義的代碼庫泛濫,每個代碼都有一兩行更改,以至于很難查明。
Kustomize 就是用于幫助解決這些問題的開源配置管理工具。從 Kubernetes v1.14 開始,kubectl 就完全支持 Kustomize 和 kustomization 文件。
本文將構建一個小型 Web 應用程序,然后使用 Kustomize 管理配置擴展,并使用不同的配置將應用程序部署到開發和生產環境。另外,本文還介紹了使用 Kustomize 的 Base 和 Overlay 對這些變量配置進行分層,使代碼易于閱讀,從而更易于維護。
K8sMeetup
先決條件
首先,我們需要:
- 連接 Kubernetes v1.14 以上的集群,設置 kubectl 默認值。
- 將 kubectl 安裝在本地計算機上。
K8sMeetup
第 1 步 不用 Kustomize 部署應用程序
在使用 Kustomize 部署應用程序之前,我們首先使用傳統方式進行部署。在這種情況下,我們先部署 sammy-app 開發版本,這是一個 Nginx 上 托管的靜態 Web 應用程序,再將 Web 內容作為數據存儲在 ConfigMap 中,并安裝在 Deployment 中的 Pod 上。這里每一個都需要單獨的 YAML 文件,我們接著創建該文件。
首先為應用程序及其所有配置文件創建一個文件夾。后續我們在此處運行本文的所有命令。在主目錄中創建一個新文件夾:
- $ mkdir ~/sammy-app && cd ~/sammy-app
現在,使用文本編輯器來創建并打開一個名為 configmap.yml 的文件:
- $ nano configmap.yml
添加以下內容:
~/sammy-app/configmap.yml
這將創建一個新的 ConfigMap 對象,將其命名為 sammy-app,然后在 data: 中存儲一些 HTML Web 內容。
保存并關閉文件。
創建并打開另一個 deployment.yml 文件:
- $ nano deployment.yml
添加以下內容:
~/sammy-app/deployment.yml
這將創建一個新的 Deployment 對象,添加的名稱和標簽為 sammy-app,副本數設置為 1,指定要使用的對象是 Nginx v1.17 容器鏡像。另外,容器端口設置為 80,CPU 和內存請求和限制也定義,日志記錄級別設置為 DEBUG。
保存并關閉文件。
現在這兩個文件都有部署到 Kubernetes 集群中。下面要創建多個對象,將 cat 命令通過管道傳遞給 kubectl:
- $ cat configmap.yml deployment.yml | kubectl apply -f -
稍等一下,然后使用 kubectl 來檢查應用程序的狀態:
- $ kubectl get pods -l app=sammy-app
最終,我們將在 READY 列中看到一個 Pod 和應用程序正在運行,以及 1/1 容器:
Pod 正在運行并由 Deployment 支持,但是我們仍然無法訪問應用程序。首先,我們需要添加 Service。
創建并打開第三個 YAML 文件,它是 service.yml:
- $ nano service.yml
添加以下內容:
~/sammy-app/service.yml
這創建了一個名為 sammy-app 的新 Service 對象。對于大多數云提供商,設置 spec.type 為 LoadBalancer 會預配負載均衡器。spec.ports 會把將以帶有標簽的任何Pod為目標TCP端口。
spec.ports 將把 TCP 80 端口作為任何帶有 sammy-app 標簽的 Pod 目標。
保存并關閉文件。
現在將 Service 部署到 Kubernetes 集群中:
- $ kubectl apply -f service.yml
稍等片刻,再使用 kubectl 檢查應用程序狀態:
- $ kubectl get services -w
最終,EXTERNAL-IP 列下將為 Service 顯示一個公共 IP,唯一 IP 在 your_external_ip 這里:
復制顯示的 IP 地址,并將其輸入到 Web 瀏覽器中,我們可以看到 DEVELOPMENT 應用程序的版本。
在終端上,使用 CTRL + C 可以停止觀看 Service。
在該步驟中,我們將 sammy-app 開發版本部署到 Kubernetes。在步驟 2 和 3 中,本文將使用 Kustomize 來重新部署 sammy-app 開發版本,然后部署配置略有不同的生產版本。使用這個新的工作流程,我們可以看到 Kustomize 是如何更好地管理配置更改并簡化開發工作流程的。
K8sMeetup
第 2 步 使用 Kustomize 部署應用程序
在該步驟中,我們將部署完全相同的應用程序,但以 Kustomize 而不是默認的 Kubernetes 方式進行的。
現在文件系統當前如下所示:
要使此應用程序可通過 Kustomize 進行部署,我們需要添加一個 kustomization.yml 文件:
- $ nano kustomization.yml
該文件要指定使用 kubectl -k 時管理的資源,這用于 kubectl 處理 kustomation 文件。
添加以下內容:
~/sammy-app/kustomization.yml
保存并關閉文件。
在再次部署之前,要刪除步驟 1 中現有的 Kubernetes 資源:
- $ kubectl delete deployment/sammy-app service/sammy-app configmap/sammy-app
然后再次部署它們,但是這次使用 Kustomize:
- $ kubectl apply -k .
這里不使用 kubectl -f 來指導 Kubernetes 從文件創建資源,而是使用 -k 和一個目錄(在本例中,. 表示當前目錄),這將通過 kubectl 使用 Kustomize 并檢查該目錄的 kustomization.yml。
這里會創建所有三個資源:ConfigMap、Deployment 和 Service。使用 get pods 命令檢查 Deployment:
- $ kubectl get pods -l app=sammy-app
我們將在 READY 列中再次看到一個 Pod,其中包含正在運行的應用程序和 1/1 容器。
重新運行 get services 命令,我們還將通過公開訪問的 EXTERNAL-IP 看到 Service:
- $ kubectl get services -l app=sammy-app
現在,我們已成功使用 Kustomize 管理 Kubernetes 配置。在下一步中,本文使用略有不同的配置部署 sammy-app 到生產環境,并通過 Kustomize 管理這些差異。
K8sMeetup
第 3 步 使用 Kustomize 管理應用程序
一旦開始處理多種資源類型,Kubernetes 資源的配置文件就會真正開始泛濫,尤其是當環境之間的差異很小時,例如開發與生產環境。我們可能有個 deployment-development.yml 和 deployment-production.yml 文件,但不是 deployment.yml。
想象一下,當發布新版本的 Nginx Docker 鏡像時,我們開始使用時會發生什么?也許我們在 deployment-development.yml 中測試了新版本,并想繼續,但后面忘記了使用 deployment-production.yml 進行新版本更新。因此,我們可能在開發環境中運行的 Nginx 版本與在生產中運行的版本不同。諸如此類的配置錯誤可能會破壞我們的應用程序。
Kustomize 可以大大簡化這些管理問題。現在我們有一個包含 Kubernetes 配置文件和一個 kustomization.yml 文件的文件系統:
我們現在準備部署 sammy-app 到生產環境中,另外還想讓應用程序的生產版本與開發版本在以下方面有所不同:
- replicas 從 1 增加至 3。
- 容器資源 requests 從 100m CPU 和 128M 內存增加到 250m CPU 和 256M 內存。
- 容器資源 limits 將從 100m CPU 和 256M 內存增加到 1 CPU 和 1G 內存。
- LOG_LEVEL 環境變量從 DEBUG 更改為 INFO。
- ConfigMap 數據更改為顯示不同的 Web 內容。
首先,創建新目錄以用于 Kustomize 方式組織事物:
- $ mkdir base
這將保留“默認”配置 Base。在示例中,這是 sammy-app 開發版本。
現在將當前的 sammy-app/ 配置移到該目錄中:
- $ mv configmap.yml deployment.yml service.yml kustomization.yml base/
然后為生產環境配置創建一個新目錄。Kustomize 將此稱為 Overlay。Overlay 可以視為 Base 之上的圖層,它們需要 Base 才能發揮作用:
- $ mkdir -p overlays/production
創建另一個 kustomization.yml 文件以定義生產環境 Overlay:
- $ nano overlays/production/kustomization.yml
添加以下內容:
~/sammy-app/overlays/production/kustomization.yml
該文件將為 Overlay 指定一個 Base,以及 Kubernetes 將使用哪些策略修補資源。此示例指定了一個 strategic-merge-style patch(SMP)以更新 ConfigMap 和 Deployment 資源。
保存并關閉文件。
最后,將 new deployment.yml 和 configmap.ymlfiles 添加到 overlays/production/ 目錄中。
首先創建新 deployment.yml 文件:
- $ nano overlays/production/deployment.yml
將以下內容添加到文件中:
~/sammy-app/overlays/production/deployment.yml
注意該新 deployment.yml 的內容。它僅包含 TypeMeta 標識已更改資源的字段(在本例中是應用程序的 Deployment ),剩余的字段將進入嵌套結構以指定新的字段值,例如容器資源請求和限制(request 和 limit)。
保存并關閉文件。
現在為生產環境 overlay 創建一個新的 configmap.yml:
- nano /overlays/production/configmap.yml
添加以下內容:
~/sammy-app/overlays/production/configmap.yml
這里將文本更改為顯示 PRODUCTION 而不是 DEVELOPMENT,另外還將文本顏色從紅色調 #f22 改為藍色 #22f。如果不使用 Kustomize 這樣的配置管理工具,查找和跟蹤這樣的細微變化會非常麻煩。
目錄結構現在如下所示:
下面準備使用基本配置進行部署,首先,刪除現有資源:
- $ kubectl delete deployment/sammy-app service/sammy-app configmap/sammy-app
將基本配置部署到 Kubernetes:
- $ kubectl apply -k base/
檢查 Deployment:
- $ kubectl get pods,services -l app=sammy-app
現在可以看到預期的基本配置,開發版本可以在 Service EXTERNAL-IP 上看到:
現在部署生產配置:
- $ kubectl apply -k overlays/production/
再次檢查 Deployment:
- $ kubectl get pods,services -l app=sammy-app
我們將看到預期的 production 配置,并且 Service EXTERNAL-IP 上將顯示生產版本:
請注意,在生產配置中,總共有 3 個 Pod,而不是 1 個。我們可以查看 Deployment 資源以確認小的更改也已生效:
- $ kubectl get deployments -l app=sammy-app -o yaml
在瀏覽器中訪問 your_external_ip 以查看網站的生產版本。
現在我們正在使用 Kustomize 管理應用程序差異。回想一下原始問題之一,如果現在想更改 Nginx 鏡像版本,則只需在 Base 中的 deployment.yml 進行修改,并且使用該 Base 的 Overlay 也將通過 Kustomize 接收該更改。這大大簡化了開發工作流程,提高了可讀性,并減少了出錯的可能性。
K8sMeetup
結論
本文構建了一個小型 Web 應用程序并將其部署到 Kubernetes 中,然后使用 Kustomize 簡化了針對不同環境的應用程序配置的管理。我們將一組幾乎重復的 YAML 文件重組為一個分層模型,這將減少錯誤,減少手動配置,并使代碼更易于識別和維護。