kustomize 最簡實踐

背景

備註:幾個月前寫的,內容可能已經過時或者更新。
在 Kubernetes v1.14 版本的發佈說明中,kustomize 成爲了 kubectl 內置的子命令,並說明了 kustomize 使用 Kubernetes 原生概念幫助用戶創作並複用聲明式配置。

那麼,kustomize 出現的原因是什麼?在 kustomize 的 github issue 中找到了 kustomize 啓發來自一篇 Kubernetes 聲明性應用程序管理,這篇文章內容很多,主要提出了 Kubernetes 應用的配置規範,聲明式配置的優點以及參數化定製配置的缺陷以及一些改進方案。

在 kustomize 出現之前,Kubernetes 管理應用的方式主要是通過 Helm 或者上層 Paas 來完成。這些工具通常通過特定領域配置語言(DSL,如Go template、jsonnet) 來維護並管理應用,並且需要參數化模板方式(如 helm) 來自定義配置,這需要學習複雜的 DSL 語法及容易出錯。

kustomize 是什麼?

先來看看官網的描述:

Kubernetes native configuration management

Kustomize introduces a template-free way to customize application configuration that simplifies the use of off-the-shelf applications. Now, built into kubectl as apply -k.

根據官網的描述:kustomize 是 kubernetes 原生的配置管理,以無模板方式來定製應用的配置。kustomize 使用 k8s 原生概念幫助創建並複用資源配置(YAML),允許用戶以一個應用描述文件 (YAML 文件)爲基礎(Base YAML),然後通過 Overlay 的方式生成最終部署應用所需的描述文件。

kustomize 解決了什麼痛點?

一般應用都會存在多套部署環境:開發環境、測試環境、生產環境,多套環境意味着存在多套 K8S 應用資源 YAML。而這麼多套 YAML 之間只存在微小配置差異,比如鏡像版本不同、Label 不同等,而這些不同環境下的YAML 經常會因爲人爲疏忽導致配置錯誤。再者,多套環境的 YAML 維護通常是通過把一個環境下的 YAML 拷貝出來然後對差異的地方進行修改。一些類似 Helm 等應用管理工具需要額外學習DSL 語法。總結以上,在 k8s 環境下存在多套環境的應用,經常遇到以下幾個問題:

  • 如何管理不同環境或不同團隊的應用的 Kubernetes YAML 資源
  • 如何以某種方式管理不同環境的微小差異,使得資源配置可以複用,減少 copy and change 的工作量
  • 如何簡化維護應用的流程,不需要額外學習模板語法

Kustomize 通過以下幾種方式解決了上述問題:

  • kustomize 通過 Base & Overlays 方式(下文會說明)方式維護不同環境的應用配置
  • kustomize 使用 patch 方式複用 Base 配置,並在 Overlay 描述與 Base 應用配置的差異部分來實現資源複用
  • kustomize 管理的都是 Kubernetes 原生 YAML 文件,不需要學習額外的 DSL 語法

kustomize 術語

在 kustomize 項目的文檔中,經常會出現一些專業術語,這裏總結一下常見的術語,方便後面講解

  • kustomization

術語 kustomization 指的是 kustomization.yaml 文件,或者指的是包含 kustomization.yaml 文件的目錄以及它裏面引用的所有相關文件路徑

  • base

base 指的是一個 kustomization , 任何的 kustomization 包括 overlay (後面提到),都可以作爲另一個 kustomization 的 base (簡單理解爲基礎目錄)。base 中描述了共享的內容,如資源和常見的資源配置

  • overlay

overlay 是一個 kustomization, 它修改(並因此依賴於)另外一個 kustomization. overlay 中的 kustomization指的是一些其它的 kustomization, 稱爲其 base. 沒有 base, overlay 無法使用,並且一個 overlay 可以用作 另一個 overlay 的 base(基礎)。簡而言之,overlay 聲明瞭與 base 之間的差異。通過 overlay 來維護基於 base 的不同 variants(變體),例如開發、QA 和生產環境的不同 variants

  • variant

variant 是在集羣中將 overlay 應用於 base 的結果。例如開發和生產環境都修改了一些共同 base 以創建不同的 variant。這些 variant 使用相同的總體資源,並與簡單的方式變化,例如 deployment 的副本數、ConfigMap使用的數據源等。簡而言之,variant 是含有同一組 base 的不同 kustomization

  • resource

在 kustomize 的上下文中,resource 是描述 k8s API 對象的 YAML 或 JSON 文件的相對路徑。即是指向一個聲明瞭 kubernetes API 對象的 YAML 文件

  • patch

修改文件的一般說明。文件路徑,指向一個聲明瞭 kubernetes API patch 的 YAML 文件

kustomize 官方示例

現在通過官方的示例來演示一下 kustomize 應該怎麼用,以及相應的一些規範。如果你沒有使用 Kubernetes v1.14 版本,參考 官方安裝教程 進行安裝 kustomize,或者直接下載 v1.14 版本kubectl 二進制,通過kubectl -k 命令使用 kustomize

前提

  • 三個不同的環境(開發、演示、生產)
  • 一個 deployments 資源和 service 資源
  • 環境之間有不同的 replicas 或者 ConfigMap

最終文件結構

demo
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── production
    │   ├── deployment.yaml
    │   └── kustomization.yaml
    └── staging
        ├── kustomization.yaml
        └── map.yaml

新建一個 Base 目錄

這裏使用官網的 helloWorld 的 YAML 資源文件作爲示例,在 base 目錄下新增幾個 k8s YAML 資源文件,文件結構如下:

demo
└── base
    ├── configMap.yaml
    ├── deployment.yaml
    ├── kustomization.yaml
    └── service.yaml

接下來看看 kustomization.yaml 配置文件中包含什麼內容:

commonLabels:
  app: hello

resources:
- deployment.yaml
- service.yaml
- configMap.yaml

這個文件聲明瞭這些 YAML 資源(deployments、services、configmap 等)以及要應用於它們的一些自定義,如添加一個通用的標籤。kustomization 還提供了namePrefix、commonAnnoations、images 等配置項,全部配置在github 的示例 kustomization.yaml 中。

這時候,可以通過 kustomize build 命令來看完整的配置:

$ kustomize build demo/base  # build 出來的 YAML 太長就不貼處理了
$ kustomize build demo/base | kubectl apply -f -  # 這種方式直接部署在集羣中
$ kubectl apply -k # 1.14 版本可以直接使用該命令部署應用於集羣中

build 出來的 YAML 每個資源對象上都會存在通用的標籤 app: hello

創建 Overlays

創建一個 staging 和 production overlay,目錄樹結構如下所示:

demo
├── base
│   ├── configMap.yaml
│   ├── deployment.yaml
│   ├── kustomization.yaml
│   └── service.yaml
└── overlays
    ├── production
    └── staging
演示環境 kustomization

在 staging kustomization 文件中,定義一個新的名稱前輟以及一些不同的標籤

# 文件路徑 demo/overlays/staging/kustomization.yaml
namePrefix: staging-
commonLabels:
  variant: staging
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am staging!
bases:
- ../../base
patchesStrategicMerge:
- map.yaml
演示環境 patch

添加一個 ConfigMap 自定義把 base 中的 ConfigMap 中的 “Good Morning!” 變成 “Good Night!”

# 文件路徑 demo/overlays/staging/map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Have a pineapple!"
  enableRisky: "true"
生產環境 kustoimzation

在生產環境目錄下,創建一個 kustomization.yaml 文件,定義不同的名稱及標籤

# 文件路徑 demo/overlays/production/kustomization.yaml
namePrefix: production-
commonLabels:
  variant: production
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am production!
bases:
- ../../base
patchesStrategicMerge:
- deployment.yaml
生產環境 patch

創建一個生產環境的 patch, 定義增加副本數量

# demo/overlays/production/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: the-deployment
spec:
  replicas: 10

部署不同環境

需要在生產環境部署應用,通過下面命令

$ kustomize build demo/overlays/production | kubectl apply -f -   # 或者 kubectl apply -k 

需要在演示環境部署應用,通過下面命令

$ kustomize build demo/overlays/staging | kubectl apply -f -     # 或者 kubectl apply -k

workflows 工作流

kustomize 將對 Kubernetes 應用的管理轉換成對 Kubernetes manifests YAML 文件的管理,而對應用的修改也通過 YAML 文件來修改。這種修改變更操作可以通過 Git 版本控制工具進行管理維護, 因此用戶可以使用 Git 風格的流程來管理應用。 workflows 是使用並配置應用所使用的一系列 Git 風格流程步驟。官網提供了兩種方式,一種是定製配置,另一種是現成配置。

定製配置

在這個工作流中,所有的配置(YAML 文件)都屬於用戶所有。

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YK4H3rSY-1575990237268)(https://s2.ax1x.com/2019/10/17/KEsR8f.jpg)]

# 定製工作流步驟如下:

1、創建一個目錄用於版本管理
git init ~/ldap

2、創建一個 base
mkdir -p ~/ldap/base  # 在這個目錄中創建並提交 kustomization.yaml 文件和一組資源,例如 deployment、service

3、創建 overlays
mkdir -p ~/ldap/overlays/staging
mkdir -p ~/ldap/overlays/production

4、生成 variants
kustomize build ~/ldap/overlays/staging | kubectl apply -f -
kustomize build ~/ldap/overlays/production | kubectl apply -f -

kubectl v1.14 版使用下面:
kubectl apply -k ~/ldap/overlays/staging
kubectl apply -k ~/ldap/overlays/production

現成配置

在這個工作流方式中,可從別人的 repo 中 fork kustomize 配置,並根據自己的需求來配置

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BJ4jkoF2-1575990237270)(https://github.com/kubernetes-sigs/kustomize/raw/master/docs/images/workflowOts.jpg)]

# 現成配置工作流步驟如下:

1、通過 fork 方式獲得現成配置

2、clone 作爲你的 base
mkdir ~/ldap
git clone https://github.com/$USER/ldap ~/ldap/base
cd ~/ldap/base
git remote add upstream git@github.com:$USER/ldap
  
3、創建並填充 overlays
mkdir -p ~/ldap/overlays/staging
mkdir -p ~/ldap/overlays/production

4、生成 variants
kustomize build ~/ldap/overlays/staging | kubectl apply -f -
kustomize build ~/ldap/overlays/production | kubectl apply -f -

5(可選)更新上游配置,用戶可以定期更新他的 base, 以更新上游所做的修改
cd ~/ldap/base
git fetch upstream
git rebase upstream/master

通過上面兩種工作流方式,可以實現自定義管理應用的聲明式資源文件,或者基於別人的應用聲明式資源進行自定義修改

kustomize vs Helm

通過上面對 kustomize 的講解,可能已經有人注意到它與 Helm 有一定的相似。先來看看 Helm 的定位:Kubernetes 的包管理工具,而 kustomize 的定位是:Kubernetes 原生配置管理。兩者定位領域有很大不同,Helm 通過將應用抽象成 Chart 來管理, 專注於應用的操作、複雜性管理等, 而 kustomize 關注於 k8s API 對象的管理。下面列舉了一些它們之間的區別(不是特別全面,歡迎補充或修正):

  • Helm 提供應用描述文件模板(Go template),在部署時通過字符替換方式渲染成 YAML,對應用描述文件具有侵入性。Kustomize 使用原生 k8s 對象,無需模板參數化,無需侵入應用描述文件(YAML), 通過 overlay 選擇相應 patch 生成最終 YAML
  • Helm 專注於應用的複雜性及生命週期管理(包括 install、upgrade、rollback),kustomize 通過管理應用的描述文件來間接管理應用
  • Helm 使用 Chart 來管理應用,Chart 相對固定、穩定,相當於靜態管理,更適合對外交付使用,而 kustomize 管理的是正在變更的應用,可以 fork 一個新版本,創建新的 overlay 將應用部署在新的環境,相當於動態管理,適合於 DevOps 流程
  • Helm 通過 Chart 方式打包並管理應用版本,kustomize 通過 overlay 方式管理應用不同的變體,通過 Git 來版本管理
  • Helm 在v3 版本前有 Helm 和 Tiller 兩組件,需要一定配置,而 kustomize 只有一個二進制,開箱即用

總的來說,Helm 有自己一套體系來管理應用,而 kustomize 更輕量級,融入Kubernetes 的設計理念,通過原生 k8s API 對象來管理應用

總結

Kustomize 給 Kubernetes 的用戶提供一種可以重複使用配置的聲明式應用管理,從而在配置工作中用戶只需要管理和維護 Kubernetes 的原生 API 對象,而不需要使用複雜的模版。同時,使用 kustomzie 可以僅通過 Kubernetes 聲明式 API 資源文件管理任何數量的 kubernetes 定製配置,可以通過 fork/modify/rebase 這樣的工作流來管理海量的應用描述文件。

參考

kustomize官網

kustomize github

kubectl docs

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章