一 背景
-
不必要重建:在一次應用釋出過程中可能涉及多個trait,這些trait由Operator實現都去修改workload,每次修改都會造成pod重建,實際生產過程中,pod重建應該儘量避免
-
開發成本高:新開發一個trait需要透過新建一個operator應用來實現,雖然可以利用kubebuidler開發框架簡化開發,但是仍然需要幾天才能完成,且需要開發者瞭解Operaotr的開發機制,對於開發者有一定語言能力要求
-
運維成本高:trait數量過多,一旦涉及到公共邏輯程式碼修改(如status增加欄位)時,需修改n個trait工程,同時需要升級m個叢集,帶來的維護成本將是o(n^2)的 -
資源浪費:每個trait是一個單獨的應用,而應用部署時最低配置都是1核1G且多副本,然而內部執行的是簡單轉換邏輯僅用100M左右,因此這些trait實際上帶來大量資源浪費
-
程式碼不規範:在trait共建方面,KubeNest僅規定了輸入輸出標準,使用者可定製化trait開發,這也很容易因為程式碼不規範造成bug
-
不一致問題:面對相同的輸入,在Operator程式碼邏輯不當可能會帶來輸出資料順序不同,而該不一致問題很容易導致pod重建,如toleration順序變化會導致pod重建,而這是無效的重建
二 舊的架構
1 Trait Operator化

應用資料:應用相關的資料,使用者無需關心但在Operator邏輯處理所需要的,存在metadata的annatation資料中,如workload的apiVersion和kind,在apply時需要。
-
toleration trait CR (使用者選擇底層資源)
apiVersion: apps.kubeone.alibaba-inc.com/v1
kind: TolerationInjector
metadata:
annotations:
kubeone.ali/workload-api-version: apps.kruise.io/v1alpha1 # 應用資料
kubeone.ali/workload-kind: StatefulSet # 應用資料
...
#使用者資料
spec:
parameters:
sigma.ali/is-ecs: "true"
sigma.ali/resource-pool: "example"
該CR表示使用者希望將pod佈置在打上汙點標sigma.ali/is-ecs: "true"和sigma.ali/resource-pool: "example"的node上。
-
toleration trait產生的YAML片段
toleration trait根據trait CR中使用者輸入轉化成YAML片段,然後將該YAML片段直接patch到workload上,完成該運維操作。
# YAML片段
apiVersion: apps.kruise.io/v1alpha1
kind: StatefulSet
metadata:
name: sts-example
namespace: ns-example
spec:
template:
spec:
tolerations:
- effect: NoSchedule
key: sigma.ali/resource-pool
operator: Equal
value: example
- effect: NoSchedule
key: sigma.ali/is-ecs
operator: Equal
value: 'true'
2 風險點
-
順序導致重建在原生的statefulset和Open kruise statefulset中,YAML內容的順序不同也會導致重啟。因此,在舊的架構中,trait除了要關注輸入引數的值,還需關注引數的順序問題。當引數順序不同時,trait產生的YAML片段順序也會不同,當patch到workload上時,就會引發workload重啟,從而可能帶來pod重建的故障風險。
-
多次apply導致重建一次釋出過程中可能有多個trait施加運維操作,此時會有多次apply workload而導致pod多次重建。從安全生產角度考慮,使用者希望pod重建次數越少越好。
三 trait配置化開發框架
1 Trait開發框架

Trait convert:trait實現藉助於Universal Operator透過資料+配置模版=YAML片段的方式生成YAML Fragment,該YAML Fragment會透過ConfigMap儲存。
Apply:會聚合一次釋出過程中產生的所有YAML Fragment,然後做一次patch到應用workload,從而避免了多次重建。
-
trait CR:使用者提交的運維動作,其中包括應用資料(存在metadata)和使用者資料(存在spec),可以參考toleration trait CR的示例
-
trait definition:去operator,將運維邏輯配置化,本質是一個YAML
-
name:該條資料的標示,在template中,透過name來渲染資料
-
keyRef:資料來源,值為json path的形式,會根據keyRef從spec中讀取資料
-
default:預設值,如果從spec中找不到資料則用預設值
-
required:表明此屬性是否必須
-
description:對該屬性的描述
-
params:在模版中定義了該運維邏輯所需要的使用者資料和每條使用者資料的基本屬性,每個資料屬性有name、default、keyRef、description、required -
tasks:對於配置化的切面拓展,90%的trait是可以直接轉換的,對於不能轉換需要新增複雜邏輯的,trait開發者可以透過tasks來自定義,task會在生成YAML片段前執行,目前支援的task型別有shell、job、http -
template:以go template為基礎的trait模版,結合資料render成最終的YAML片段 -
Universal Trait Controller:核心的轉換控制器,結合trait CR和trait definiton生成YAML片段
2 流程介紹
-
使用者資料處理(Merge)。trait CR中有使用者資料(user data)和應用資料(app data),params中規定了引數要求,merge過程將使用者資料和params結合輸出,記為merged data -
定製化邏輯處理(TaskRun)。tasks是配置化方案的拓展,是使用者自定義的邏輯,包括多種shell、http、job、func等多種方式。此過程會將merged data和app data作為task的輸入引數,順序執行多個task,tasks執行完會產生新的輸出資料,記為output data -
資料渲染(Render)。app data、merged data和output data作為終態資料,將這些資料與template透過go template技術渲染得到YAML片段,YAML暫存在Fragment(configMap)中
-
OrderId:每次釋出的orderId -
AppName:應用name -
WorkloadApiVersion:workload的apiVersion -
WorkloadKind:workload的Kind -
Namespace:應用的namespace -
CoreNamespace:kubeNest的namespace,值為ark-system -
Replicas:副本數
3 示例
apiVersion: core.oam.dev/v1alpha1
kind: TraitDefinition
metadata:
name: etcd-secret-injector
namespace: ns-example
spec:
...
params:
- name: END_POINT
type: "string"
description: "this is a description"
default: "https://127.0.0.1"
required: false
tasks:
- name: etcd-http
kind: http # shell / job / http / func
spec:
script: '{{.Params.END_POINT}}/etcd'
outputs:
- name: TOKEN
default: "default token"
- name: KEY
default: "default key"
template: |
apiVersion: v1
kind: secret
metadata:
name: {{ .AppName }}
namespace: {{ .Namespace }}
data:
token: {{ .Outputs.TOKEN | b64dec }}
key: {{ .Outputs.KEY | b64dec}}
四 方案對比
對比開發 | Operator開發 | 配置化開發 |
---|---|---|
開發成本
|
需掌握Operator開發知識
|
僅需知道YAML編寫知識
|
開發週期
|
前後需幾天時間
|
去Operator,僅編寫YAML,半個小時左右
|
運維成本
|
每個trait需單獨部署與穩定性保障
|
當成功地將大部分trait收斂成YAML配置,僅需部署維護一個Universal trait Operator,大大節省了運維成本
|
資源配置
|
每個trait都是單獨的Operator應用,最低配置1核1G,且需多副本部署
|
無資源消耗
(
新增trait僅增加YAML配置 )
|
標準化
|
僅輸入輸出標準化
|
不僅輸入輸出標準化,而且使開發過程標準化,能很好的避免因程式碼不規範引起的bug
|
拓展性
|
無
|
多型別task支援使用者自定義邏輯,有很好的切面拓展能力
|
穩定性
|
一次部署容易引發多次pod重建
|
避免多次重建
|
資源配置化開發去Operator,提供了通用trait的開發輸入輸出標準化管理,開發者僅需配置YAML,極大縮短了開發週期,同時將trait 應用收斂,降低運維成本和資源消耗,同時避免了多次重建保障了生產的穩定性。
五 總結
-
降本提效:該方案去operator應用能夠有效的收斂資源,同時YAML配置化開發大大的提高了開發效率和降低了運維(部署、升級)成本;
-
資料一致性:模版化保證了資料是面向終態的,使得開發無需關注資料順序,保障資料一致性,消除亂序帶來重啟的風險;
-
促進開源:該方案目前已經經過生產級的驗證,得到很好的反響,並輸出到KubeVela中,使得使用者自定義開發trait更為簡單,促進KubeVela開源生態的建設。
Spring Cloud微服務架構設計與開發實戰
本次課程涵蓋最新版本的Spring Cloud 微服務架構體系, 微服務架構模式、演算法與典型場景、框架、優缺點,Spring Cloud 2020的重大變化、擴充套件Netflix、Spring Cloud Alibaba阿里巴巴體系,Dubbo等架構選型對比,淘寶微服務架構案例。
重點講解:服務治理、註冊發現、熔斷限流、閘道器代理、鏈路追蹤、安全監控等核心問題,循序漸進,概念為輔、實戰為主,涵蓋經典面試題。讓您成為合格的微服務架構師。點選閱讀原文檢視詳情!
關鍵詞
資料
資源
開發者
邏輯
v 1