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