在容器中建立一個簡單的Web服務
首先,讓我們看如何使用Buildah建立一個包含HTTP服務的容器映像。以下是完整的步驟:
# 建立根據CentOS的工作容器
buildah from centos:latest
# 檢視建立的容器名稱
buildah containers
# 在容器中安裝HTTPD
buildah run centos-working-container yum -y install httpd
上述命令首先從CentOS基礎映像建立了一個工作容器,這是Buildah操作的基本單位。buildah from
命令類別似於Dockerfile中的FROM指令,但它直接回傳一個容器例項而非僅定義一個構建階段。buildah containers
命令列出當前所有的工作容器,幫助我們確認容器已正確建立。最後,buildah run
命令在容器內執行yum安裝命令,這相當於Dockerfile中的RUN指令,但提供了更直接的操作方式。
現在讓我們增加一個簡單的HTML頁面到容器中:
<html>
<head>
<title>GitOps CookBook example</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
將此檔案複製到容器中:
buildah copy centos-working-container index.xhtml /var/www/html/index.xhtml
設定容器的啟動入口點:
buildah config --entrypoint "/usr/sbin/httpd -DFOREGROUND" centos-working-container
最後,提交變更並建立映像:
buildah commit centos-working-container quay.io/gitops-cookbook/gitops-website
這部分操作展示了Buildah的核心功能。buildah copy
命令將本地檔案複製到容器內,類別似於Dockerfile中的COPY指令。buildah config
則用於設定容器的中繼資料,這裡我們設定了入口點,相當於Dockerfile中的ENTRYPOINT指令。最後,buildah commit
將工作容器的狀態儲存為一個新的映像,並指定了映像名稱和標籤。
使用Dockerfile與Buildah構建相同映像
Buildah也支援從Dockerfile構建映像,這提供了良好的相容性:
FROM centos:latest
RUN yum -y install httpd
COPY index.xhtml /var/www/html/index.xhtml
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
使用Buildah從Dockerfile構建:
buildah bud -f Dockerfile -t quay.io/gitops-cookbook/gitops-website
buildah bud
(build-using-dockerfile的縮寫)命令允許Buildah使用標準Dockerfile構建映像。這為現有的Docker工作流程提供了平滑的遷移路徑,同時享受Buildah的安全優勢。這裡的構建過程與Docker幾乎相同,但底層實作更注重安全性和隔離性。
執行構建好的容器
如果你安裝了Podman(Buildah的姊妹工具,專注於容器執行而非構建),可以這樣執行容器:
podman run -p 8080:80 -ti quay.io/gitops-cookbook/gitops-website
然後可以透過瀏覽器存取 http://localhost:8080 來測試服務。
Podman是Buildah生態系統的一部分,專注於容器執行。它提供了與Docker CLI相似的介面,但採用了無守護程式設計。-p 8080:80
引數將容器內的80連線埠對映到主機的8080連線埠,-ti
引數則請求一個互動式終端。
Buildah的技術優勢
使用Buildah構建容器映像有幾個關鍵優勢:
- 無需安裝Docker:Buildah完全獨立執行,不依賴Docker守護程式
- 安全設計:支援無根使用者(rootless)操作,減少許可權提升風險
- 精細控制:對映像層的建立有更精確的控制
- 從零開始構建:可以建立完全空白的映像,類別似於Dockerfile中的
FROM scratch
Buildah的一個特別強大的使用案例是建立極小的生產映像。在開發過程中,我們可能需要編譯器和開發工具,但在生產環境中,只需要執行時和應用程式包。Buildah讓這種映像縮減變得簡單明瞭。
Cloud Native Buildpacks:無Dockerfile自動構建
自動檢測與構建的革新
在大規模環境中,維護大量Dockerfile可能變得極具挑戰性。Cloud Native Buildpacks提供了一個優雅的解決方案,透過檢查應用程式原始碼自動建立容器映像,無需手寫Dockerfile。
Buildpacks的工作流程分為兩個主要階段:
- 檢測階段:工具分析原始碼,識別程式設計語言或框架(如POM檔案、NPM設定、Python依賴等),並分配適當的buildpack
- 構建階段:使用選定的buildpack編譯原始碼,建立容器映像,並設定適當的入口點和啟動指令碼
安裝Buildpacks CLI工具
要使用Buildpacks,首先需要安裝pack
CLI工具:
# 在macOS上安裝
brew install buildpacks/tap/pack
對於其他作業系統,可以從Buildpacks官方網站下載對應版本。
使用Buildpacks構建Node.js應用
讓我們嘗試使用Buildpacks為一個簡單的Node.js應用建立容器映像:
首先,我們可以讓pack工具為我們推薦合適的builder:
pack builder suggest
這將顯示可用的builder列表,包括Google、Heroku和Paketo Buildpacks提供的各種選項。每個builder都包含不同的語言和框架支援。
選擇一個合適的builder,例如Paketo的base builder:
pack build nodejs-app --builder paketobuildpacks/builder:base
在這個命令中,pack build
指示工具開始構建過程,nodejs-app
是我們為新映像指定的名稱,--builder
引數指定使用哪個builder。Paketo的base builder包含多種語言支援,包括Node.js、Java、.NET Core等。
執行此命令後,Buildpacks會:
- 下載指定的builder映像
- 分析專案錄
- 檢測到這是一個Node.js應用(透過package.json檔案)
- 選擇適當的buildpacks組合
- 構建應用並建立容器映像
構建完成後,我們可以用Docker執行它:
docker run --rm -p 3000:3000 nodejs-app
使用curl測試執行中的應用:
curl http://localhost:3000/
Buildpacks自動檢測到應用的入口點(在這個例子中是node server.js
)並設定容器執行環境。它還處理了所有依賴安裝,無需我們手動編寫這些步驟。這大簡化了容器化過程,特別是對於標準應用架構。
Buildpacks的技術優勢
在實際工作中,我發現Buildpacks在以下場景特別有價值:
- 大規模標準化:當組織需要為數百個相似結構的應用建立容器時
- 簡化開發者體驗:讓不熟悉容器技術的開發者也能輕鬆容器化應用
- 強制執行最佳實踐:透過builder封裝組織認可的構建策略與安全標準
- 降低維護成本:無需維護大量Dockerfile,減少因基礎映像或構建步驟變更帶來的工作量
選擇合適的容器構建工具
在多個容器專案的實踐中,我總結出一些選擇合適工具的準則:
何時選擇Buildah
- 當需要極高的安全標準,特別是在需要無根使用者操作的環境
- 需要對映像層有精細控制,最佳化映像大小和層結構
- 需要從頭建立極小的生產映像
- 在無法執行Docker守護程式的環境中
何時選擇Buildpacks
- 大規模標準化應用佈署,特別是在微服務架構中
- 開發團隊不熟悉容器技術或不希望維護Dockerfile
- 需要強制執行組織層面的構建標準和最佳實踐
- 使用標準框架和語言,不需要特殊的構建步驟
何時繼續使用Docker
- 團隊已經熟悉Docker生態系統並有大量現有工作流程
- 需要廣泛的社群支援和豐富的檔案
- 與現有CI/CD管道有深度整合
- 容器安全性不是首要考慮因素
實際應用案例分析
在一個金融科技專案中,我們面臨著嚴格的安全要求和大量微服務。我們採用了混合策略:
- 使用Buildpacks自動化標準微服務的容器化過程,減少開發團隊的負擔
- 對於需要特殊設定或極致效能最佳化的核心服務,使用Buildah手動構建
- 為所有映像實施嚴格的安全掃描和簽名策略
這種方法顯著提高了團隊效率,同時確保了關鍵服務的效能和安全性。
容器構建技術的未來趨勢
隨著容器技術的成熟,我觀察到幾個明確的發展趨勢:
- 更強調安全性:無根容器和精細許可權控制將成為標準
- 自動化程度提高:像Buildpacks這樣的工具將進一步簡化容器化流程
- 與CI/CD深度整合:容器構建工具將與持續整合和佈署管道無縫銜接
- 映像最佳化自動化:自動分析和最佳化容器映像大小和安全性的工具將更加普及
在容器技術快速發展的今天,掌握多種容器構建工具和策略,能夠為不同場景選擇最佳方案,將是DevOps工程師和平台團隊的核心競爭力。
現代容器構建已經遠超出了簡單編寫Dockerfile的範疇。透過Buildah和Buildpacks等工具,我們可以構建更安全、更高效的容器映像,同時簡化開發流程,提高團隊生產力。無論是追求極致安全性的Buildah,還是注重自動化和標準化的Buildpacks,都為容器技術帶來了新的可能性。
Kubernetes 容器構建的挑戰與解決方案
Kubernetes 作為容器協調平台的霸主,在容器佈署和管理方面表現出色,然而它本身卻不提供構建容器映像的內建功能。根據 Kubernetes 官方檔案說明:「Kubernetes 不負責佈署原始碼,也不會構建應用程式。持續整合、交付和佈署 (CI/CD) 工作流程取決於組織文化、偏好以及技術需求。」
在實際開發流程中,這種限制經常迫使開發團隊在 Kubernetes 環境外維護獨立的 CI/CD 系統或 Docker 環境。這不僅增加了基礎設施的複雜性,還在開發到佈署的流程中引入了額外的環節。
雲原生構建工具的崛起
近年來,隨著雲原生技術的發展,一系列針對 Kubernetes 環境的容器構建工具應運而生,其中 Shipwright 框架脫穎而出。
Shipwright 是一個擴充套件性極強的框架,專為在 Kubernetes 上構建容器映像而設計。它支援多種流行的構建工具:
- Buildah
- Cloud Native Buildpacks
- kaniko
- BuildKit
Shipwright 採用 Kubernetes 風格的 API,並使用 Tekton 執行工作負載,為開發人員提供了一種簡化的容器映像構建方法。開發者只需定義一個最小化的 YAML 檔案,無需事先了解容器或容器引擎的知識,就能完成映像構建。這種設計使 Shipwright 成為一個與具體技術無關與高度整合 Kubernetes API 生態系統的解決方案。
Shipwright:Kubernetes 原生的構建框架
在深入 kaniko 之前,我們需要先了解 Shipwright 的基本架構。Shipwright 透過擴充套件 Kubernetes API,增加了一系列自定義資源定義 (CRD),這些資源協同工作,提供了完整的容器構建能力。
Shipwright 核心元件
Shipwright 定義了三個關鍵的自定義資源:
- ClusterBuildStrategy:代表要執行的構建類別,例如 kaniko、Buildpacks 等
- Build:代表構建設定,包含一個 ClusterBuildStrategy 物件的規格
- BuildRun:代表正在執行的構建,當此物件被建立時,構建過程就會開始
這種設計遵循了 Kubernetes 的宣告式 API 模式,使得構建過程可以像管理其他 Kubernetes 資源一樣被管理和監控。
在 Kubernetes 中安裝 Shipwright
在使用 Shipwright 之前,我們需要將其安裝到 Kubernetes 叢集中。我們可以使用 kind 或 Minikube 這樣的本地叢集進行實驗。
安裝 Tekton 依賴
Shipwright 依賴 Tekton 執行管道,所以首先要安裝 Tekton:
kubectl apply -f \
https://storage.googleapis.com/tekton-releases/pipeline/previous/v0.30.0/release.yaml
安裝 Shipwright 核心元件
接著安裝 Shipwright 本身:
kubectl apply -f \
https://github.com/shipwright-io/build/releases/download/v0.7.0/release.yaml
安裝構建策略
最後,安裝 Shipwright 的構建策略:
kubectl apply -f \
https://github.com/shipwright-io/build/releases/download/v0.7.0/sample-strategies.yaml
這三個安裝步驟建立了完整的 Shipwright 環境。首先安裝 Tekton 作為底層執行引擎,然後安裝 Shipwright 核心 API 和控制器,最後安裝預定義的構建策略,讓你可以立即使用不同的構建工具。值得注意的是,這些 YAML 檔案包含了所有必要的 CRD、服務帳號、角色和其他 Kubernetes 資源,Shipwright 控制器會監控這些資源並協調構建過程。
kaniko:無 Docker 的容器映像構建工具
kaniko 是一個在容器或 Kubernetes 叢集內部直接從 Dockerfile 構建容器映像的工具,無需依賴 Docker daemon。這解決了在安全環境中執行 Docker 的特權問題,特別適合在 Kubernetes 等分享環境中使用。
當我們在研究 Kubernetes 中的容器構建方案時,我發現 kaniko 提供了一種不需要特權模式就能構建容器的方法,這在多租戶環境中特別有價值。
檢查可用的構建策略
安裝完成後,我們可以檢視所有可用的 ClusterBuildStrategy (CBS) 物件:
kubectl get cbs
應該會看到一系列可用的構建策略:
NAME AGE
buildah 26s
buildkit 26s
buildpacks-v3 26s
buildpacks-v3-heroku 26s
kaniko 26s
kaniko-trivy 26s
ko 26s
source-to-image 26s
source-to-image-redhat 26s
這個命令展示了 Shipwright 支援的所有構建策略。這些策略代表不同的容器構建工具和方法,每一個都有其特點和適用場景。例如,buildpacks-v3
適合無 Dockerfile 的應用程式構建,而 kaniko
則專注於從 Dockerfile 構建映像。kaniko-trivy
是 kaniko 的變體,整合了 Trivy 安全掃描功能。這種多樣性讓開發團隊可以根據專案需求選擇最合適的構建方法。
設定映像推播憑證
Shipwright 構建完容器映像後,需要將其推播到容器登入檔。為此,我們需要提供登入檔的認證憑證,這透過 Kubernetes Secret 實作:
REGISTRY_SERVER=quay.io
REGISTRY_USER=<your_registry_user>
REGISTRY_PASSWORD=<your_registry_password>
EMAIL=<your_email>
kubectl create secret docker-registry push-secret \
--docker-server=$REGISTRY_SERVER \
--docker-username=$REGISTRY_USER \
--docker-password=$REGISTRY_PASSWORD \
--docker-email=$EMAIL
這個命令建立了一個類別為 docker-registry
的 Kubernetes Secret,包含了推播映像到容器登入檔所需的認證資訊。Shipwright 會在構建過程中使用這個 Secret 來認證並推播映像。在生產環境中,我建議使用更安全的認證方式,比如 Quay 的加密碼或 OAuth token,而不是直接使用帳戶密碼。
使用 kaniko 構建 Node.js 應用
現在,我們可以建立一個使用 kaniko 策略的 Build 物件,來構建一個 Node.js 範例應用。
定義 Build 物件
建立一個 build-kaniko.yaml
檔案:
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: kaniko-nodejs-build
spec:
source:
url: https://github.com/shipwright-io/sample-nodejs
contextDir: docker-build
strategy:
name: kaniko
kind: ClusterBuildStrategy
output:
image: quay.io/gitops-cookbook/sample-nodejs:latest
credentials:
name: push-secret
這個 YAML 定義了一個 Shipwright Build 資源,指定了以下關鍵訊息:
source
部分指定了原始碼的來源(GitHub 倉函式庫上下文目錄strategy
選擇了kaniko
作為構建策略output
定義了構建結果的映像目標地址和推播所需的憑證
這種宣告式設定是 Kubernetes 原生的,讓構建過程變得可版本控制、可稽核與可重複執行。
建立 Build 資源
讓我們應用這個設定:
kubectl create -f build-kaniko.yaml
確認 Build 資源已註冊:
kubectl get builds
應該能看到類別似的輸出:
NAME REGISTERED REASON BUILDSTRATEGYKIND BUILDSTRATEGYNAME CREATIONTIME
kaniko-nodejs-build True Succeeded ClusterBuildStrategy kaniko 13s
這個輸出顯示 Build 已成功註冊,但尚未開始執行。在 Shipwright 的設計中,Build 資源只是定義了構建的設定,而實際執行則需要建立 BuildRun 資源。這種分離設計讓你可以定義一次 Build 設定,然後多次執行它,非常適合 CI/CD 流程。
執行構建過程
雖然 Build 資源已建立,但構建過程尚未開始。我們需要建立一個 BuildRun 資源來觸發構建:
定義 BuildRun 資源
建立一個 buildrun.yaml
檔案:
apiVersion: shipwright.io/v1alpha1
kind: BuildRun
metadata:
generateName: kaniko-nodejs-buildrun-
spec:
buildRef:
name: kaniko-nodejs-build
這個 YAML 定義了一個 BuildRun 資源,它參照了之前建立的 Build 資源。注意 generateName
欄位 - 這會為每次執行生成一個唯一名稱,這是 Kubernetes 命名的一種模式,特別適合需要多次執行的資源。
開始構建
應用 BuildRun 設定:
kubectl create -f buildrun.yaml
檢查執行中的 Pod:
kubectl get pods
應該能看到一個新的 Pod 正在初始化:
NAME READY STATUS RESTARTS AGE
kaniko-nodejs-buildrun-b9mmb-qbrgl-pod-dk7xt 0/3 PodInitializing 0 19s
當 BuildRun 被建立時,Shipwright 控制器會建立一個包含多個容器的 Pod 來執行構建過程。這個 Pod 包含三個關鍵容器,分別負責取得原始碼、執行構建和處理結果。STATUS 顯示為 “PodInitializing” 表示 Pod 正在準備初始容器,這些容器會設定構建環境。
監視構建過程
每個構建 Pod 包含三個關鍵步驟容器:
- step-source-default:負責取得原始碼
- step-build-and-push:使用 kaniko 從 Dockerfile 構建並推播映像
- step-results:處理構建結果
我們可以檢視構建階段的日誌:
kubectl logs -f kaniko-nodejs-buildrun-b9mmb-qbrgl-pod-dk7xt -c step-build-and-push
輸出將顯示 kaniko 的構建過程:
INFO[0001] Retrieving image manifest ghcr.io/shipwright-io/shipwright-samples/node:12
INFO[0001] Retrieving image ghcr.io/shipwright-io/shipwright-samples/node:12 from registry ghcr.io
INFO[0002] Built cross stage deps: map[]
INFO[0002] Retrieving image manifest ghcr.io/shipwright-io/shipwright-samples/node:12
INFO[0002] Returning cached image manifest
INFO[0002] Executing 0 build triggers
INFO[0002] Unpacking rootfs as cmd COPY . /app requires it.
INFO[0042] COPY . /app
INFO[0042] Taking snapshot of files...
INFO[0042] WORKDIR /app
INFO[0042] cmd: workdir
INFO[0042] Changed working directory to /app
INFO[0042] No files changed in this command, skipping snapshotting.
INFO[0042] RUN pwd && ls -l && npm install && npm run print-http-server-version
這些日誌展示了 kaniko 的構建過程。首先它取得基礎映像 (node:12
),然後執行 Dockerfile 中的指令 - 複製應用程式檔案、設定工作目錄、執行 npm 安裝依賴並執行指令碼。kaniko 的一個優點是它詳細記錄了每個步驟,這對於除錯構建問題非常有幫助。這種容器內構建過程不需要特權存取,使其非常適合在多租戶 Kubernetes 環境中安全執行。
理解 Shipwright 的工作流程
使用 Shipwright 構建容器映像的整個流程可以概括為:
- 安裝:佈署 Shipwright、Tekton 和相關構建策略到叢集
- 設定:建立容器登入檔憑證和 Build
Kubernetes上的容器建置與佈署策略
在現代雲原生架構中,容器技術已成為應用佈署的標準方式。然而,如何有效率地建置容器映像檔並在Kubernetes中管理佈署資源,始終是開發團隊面臨的關鍵挑戰。我在多年的容器化工作中發現,選擇合適的工具鏈可以大幅提升開發效率並確保一致性。
本文將探討兩個核心工具:用於在Kubernetes中建置容器映像檔的Shipwright,以及用於管理Kubernetes資源的Kustomize。這些工具如何協同工作,為開發團隊提供流暢的工作流程?讓我們一起來看。
Shipwright:Kubernetes原生的容器建置平台
Shipwright的核心優勢
Shipwright提供了一種在Kubernetes內部建置容器映像檔的優雅方式。它的最大特點在於策略無關性,這使得它在不同場景下都能保持穩健性和互操作性。在我設計大規模微服務架構時,這種靈活性非常寶貴,因為它允許不同團隊使用他們熟悉的建置工具,同時保持整體工作流程的一致性。
Shipwright的目標是成為Kubernetes的「建置API」,為開發者提供自動化的簡便途徑。由於底層使用Tekton執行建置,它也使從微管道(micropipeline)到更複雜的工作流程的過渡變得更加平滑。
建置過程分析
從上述的建置日誌中,我們可以看到一個完整的Shipwright建置過程:
- 首先執行一系列shell命令,檢查環境並安裝依賴項
- 安裝npm套件並驗證http-server版本
- 然後對檔案系統進行快照
- 設定暴露的連線埠(8080)和啟動命令
- 最後將映像檔推播到指定的容器倉函式庫這個過程顯示了Shipwright如何將整個建置過程封裝在Kubernetes API中,使開發者可以專注於應用邏輯。
從Kaniko轉向Buildah
在實際工作中,我經常需要根據專案需求切換不同的建置策略。使用Shipwright時,從Kaniko轉向Buildah只需要修改Build物件中的ClusterBuildStrategy即可:
apiVersion: shipwright.io/v1alpha1
kind: Build
metadata:
name: buildpack-nodejs-build
spec:
source:
url: https://github.com/shipwright-io/sample-nodejs
contextDir: source-build
strategy:
name: buildah
kind: ClusterBuildStrategy
output:
image: quay.io/gitops-cookbook/sample-nodejs:latest
credentials:
name: push-secret
這個YAML檔案定義了一個Shipwright建置工作,與前面看到的kaniko建置不同,這裡使用了Buildah作為建置策略。Buildah的一個重要優勢是它不需要Dockerfile就能建立容器映像檔,這在某些專案中可能更加靈活。source
區段指定了原始碼的位置及上下文目錄,output
定義了建置結果的目標映像檔及推播所需的憑證。
Kustomize:無範本的Kubernetes資源管理
從容器映像檔建置完成後,下一步就是將應用程式佈署到Kubernetes叢集。這裡面臨的挑戰是如何管理多個Kubernetes資源檔案,以及如何處理不同環境的設定差異。
Kustomize解決什麼問題?
在我的開發實踐中,直接修改YAML檔案進行佈署雖然可行,但存在高風險。一個錯誤的修改、一個誤刪的行、錯誤的空格,都可能導致災難性後果。特別是當應用規模擴大,環境數量增加時,這種風險指數級上升。
Kustomize採用無範本的方式解決這個問題。它允許我們定義基礎資源檔案(很少變更的部分),然後為每個環境指定特定的變更引數。這種方法避免了範本語言的複雜性,同時提供了強大的客製化能力。
Kustomize的基本佈局
Kustomize的核心是一個kustomization.yaml
檔案,它定義了要佈署的資源和如何客製化這些資源。一個典型的Kustomize專案結構如下:
pacman/
├── deployment.yaml # 基本Kubernetes佈署檔案
├── namespace.yaml # 名稱空間定義
├── service.yaml # 服務定義
└── kustomization.yaml # 定義資源列表和客製化
這種結構使得資源管理變得清晰與可維護。基礎YAML檔案是標準的Kubernetes資源定義,無需任何特殊標記或預留位置。
實作Pacman應用佈署
讓我們實際建立一個簡單的網頁應用佈署。首先,建立以下三個資源檔案:
名稱空間定義 (namespace.yaml):
apiVersion: v1
kind: Namespace
metadata:
name: pacman
佈署定義 (deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: pacman-kikd
namespace: pacman
labels:
app.kubernetes.io/name: pacman-kikd
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: pacman-kikd
template:
metadata:
labels:
app.kubernetes.io/name: pacman-kikd
spec:
containers:
- image: lordofthejars/pacman-kikd:1.0.0
imagePullPolicy: Always
name: pacman-kikd
ports:
- containerPort: 8080
name: http
protocol: TCP
服務定義 (service.yaml):
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: pacman-kikd
name: pacman-kikd
namespace: pacman
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app.kubernetes.io/name: pacman-kikd
這三個YAML檔案定義了一個完整的應用佈署:
- namespace.yaml - 建立一個名為"pacman"的隔離名稱空間
- deployment.yaml - 定義一個具有單一複本的佈署,使用lordofthejars/pacman-kikd:1.0.0映像檔
- service.yaml - 建立一個服務,將內部8080連線埠暴露出來,並使用標籤選擇器連線到佈署的Pod
然後,建立kustomization.yaml檔案,將這些資源組合在一起:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./namespace.yaml
- ./deployment.yaml
- ./service.yaml
這個kustomization.yaml檔案是Kustomize的核心,它告訴Kustomize要處理哪些資源檔案。這些資源會按照深度優先的順序處理,確保依賴關係得到正確處理(例如,名稱空間會在佈署之前建立)。
應用Kustomize設定
使用以下命令可以預覽Kustomize將產生的完整YAML:
kubectl apply --dry-run=client -o yaml -k ./
這個命令使用了-k
選項指示kubectl使用kustomization.yaml檔案,而--dry-run=client
則表示只生成YAML而不實際應用到叢集。
從我的經驗來看,這種預覽功能非常有用,特別是在進行重大變更時,它能幫助我們在實際佈署前發現潛在問題。
Kustomize進階使用技巧
雖然基本的Kustomize用法已經很強大,但真正的價值在於它的進階功能。在我的專案中,我經常使用以下技巧來增強佈署的靈活性和可維護性。
映像檔更新
在持續佈署流程中,映像檔版本的更新是最常見的操作之一。Kustomize提供了一種簡單的方式來更新映像檔版本,而無需修改基礎YAML檔案:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./namespace.yaml
- ./deployment.yaml
- ./service.yaml
images:
- name: lordofthejars/pacman-kikd
newTag: 2.0.0
這種方式使得CI/CD管道能夠輕鬆地注入新的映像檔版本,而不必擔心修改原始檔案。
環境特定設定
在多環境佈署中,管理環境特定的設定是一個常見挑戰。Kustomize透過基底和覆寫的概念優雅地解決了這個問題。我通常會設定一個基礎目錄和多個覆寫目錄:
base/
kustomization.yaml
deployment.yaml
service.yaml
overlays/
staging/
kustomization.yaml
production/
kustomization.yaml
在覆寫的kustomization.yaml中,可以參照基礎資源並應用特定的修改:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
patchesStrategicMerge:
- deployment-patch.yaml
這種方法使得環境之間的差異明確與易於管理,大減少了維護的工作量。
ConfigMap自動滾動更新
Kubernetes的一個常見痛點是ConfigMap更新不會自動觸發Pod的重新啟動。在我的實踐中,我發現Kustomize提供了一個優雅的解決方案:透過在ConfigMap名稱中嵌入內容雜湊值,強制Pod在設定變更時進行滾動更新:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: app-config
files:
- config.properties
generatorOptions:
disableNameSuffixHash: false
當config.properties檔案變更時,生成的ConfigMap名稱也會變更,這將觸發依賴該ConfigMap的Pod重新啟動。