8月XNUMX日 會議
按照傳統,我們很高興向您展示
K8s 中的核心和附加功能
Kubernetes 正在改變產業和早已建立的管理方法:
- 感謝他 抽象,我們不再使用設定配置或執行命令(Chef、Ansible...)等概念進行操作,而是使用容器、服務等分組。
- 我們可以在不考慮細微差別的情況下準備申請 具體站點,它將在其上啟動:裸機、提供者之一的雲端等。
- 有了 K8s,您變得前所未有的方便 最佳實踐 關於組織基礎設施:擴展技術、自我修復、容錯等。
然而,當然,一切並不是那麼順利:Kubernetes也帶來了自己的新挑戰。
Kubernetes 沒有 是一個解決所有用戶所有問題的組合。 核心 Kubernetes 只負責一組最低限度的必要功能,這些功能存在於 每 簇:
Kubernetes 核心定義了一組基本原語,用於對容器進行分組、管理流量等。 我們在中更詳細地討論了它們
另一方面,K8s 提供了擴展可用功能的絕佳機會,這有助於關閉其他功能 - 具體的 ——用戶需求。 Kubernetes 的新增是叢集管理員的責任,他們必須安裝和配置一切必要的東西,以使叢集「處於正確的狀態」[以解決他們的特定問題]。 這些都是什麼樣的補充呢? 讓我們來看一些例子。
附加元件範例
安裝 Kubernetes 後,我們可能會感到驚訝,節點內和節點之間的 Pod 互動所必需的網路無法自行運作。 Kubernetes 核心不保證必要的連接;相反,它決定網絡 接口 (
一個很接近的例子是資料儲存解決方案(本機磁碟、網路區塊設備、Ceph...)。 最初它們位於核心,但隨著出現
其他範例包括:
- 入口-控制器 (請參閱他們的評論
我們最近的文章 ). -
證書經理 : -
運營商 是一整類附加元件(其中包括提到的憑證管理員),它們定義原語和控制器。 他們的工作邏輯僅受我們想像的限制,並允許我們將現成的基礎設施元件(例如 DBMS)轉換為原語,這比使用一組容器及其設定更容易使用。 已經編寫了大量的運算符 - 即使其中許多尚未準備好用於生產,但這只是時間問題: - 指標 - Kubernetes 如何將介面(Metrics API)與實作(第三方附加元件,如 Prometheus 適配器、Datadog 叢集代理...)分離的另一個例子。
- 為 監測與統計,在實踐中不僅需要
普羅米修斯和格拉法納 ,還有 kube-state-metrics、node-exporter 等。
這不是完整的添加清單...例如,在 Flant 公司,我們目前安裝 29 補充 (所有這些總共創建了 249 個 Kubernetes 物件)。 簡而言之,如果沒有添加,我們就無法看到叢集的生命週期。
自動化
Operator 旨在自動化我們每天遇到的日常操作。 以下是現實生活中的範例,編寫運算子將是一個很好的解決方案:
- 有一個私有(即需要登入)註冊表,其中包含應用程式的映像。 假設每個 pod 都分配有一個特殊的秘密,允許在註冊表中進行身份驗證。 我們的任務是確保在命名空間中找到這個秘密,以便 Pod 可以下載映像。 可能有很多應用程式(每個應用程式都需要一個秘密),並且定期更新秘密本身很有用,因此消除了手動佈置秘密的選項。 這就是操作員發揮作用的地方:我們創建一個控制器,它將等待命名空間出現,並根據此事件為命名空間添加一個秘密。
- 預設情況下,禁止從 pod 存取網際網路。 但有時可能需要:存取權限機制簡單地工作是合乎邏輯的,不需要特定的技能,例如,透過命名空間中存在某個標籤。 運營商可以如何幫助我們? 建立一個控制器,等待標籤出現在命名空間中,並新增適當的 Internet 存取策略。
- 類似的情況:假設我們需要添加某個
污點 ,如果它有類似的標籤(帶有某種前綴)。 操作員的動作是顯而易見的...
在任何集群中,必須解決日常任務,並且 正確地 這可以使用運算子來完成。
總結所有描述的故事,我們得出的結論是 為了在 Kubernetes 中舒適地工作,您需要: A) 安裝附加元件, b) 發展經營者 (用於解決日常管理任務)。
如何為 Kubernetes 撰寫聲明?
一般來說,該方案很簡單:
……但事實證明:
- Kubernetes API 是一個相當重要的東西,需要花費大量時間才能掌握;
- 程式設計也不適合所有人(選擇 Go 語言作為首選語言是因為它有一個特殊的框架 -
營運商SDK ); - 框架本身的情況類似。
底線: 編寫一個控制器 (操作員)必須 花費大量資源 研究材料。 這對於「大型」營運商來說是合理的——例如,對於 MySQL DBMS。 但是,如果我們還記得上面描述的示例(揭開秘密、將Pod 訪問互聯網......),我們也希望正確執行這些示例,那麼我們就會明白,所付出的努力將超過我們現在需要的結果:
一般來說,會出現一個兩難的困境:花費大量資源並找到合適的工具來編寫語句,或以老式的方式(但速度很快)進行編寫。 為了解決這個問題 - 在這些極端之間找到折衷方案 - 我們創建了自己的專案:
Shell 運算符
他如何工作? 該叢集有一個 pod,其中包含帶有 shell 操作符的 Go 二進位。 他旁邊有一套 掛鉤 (有關它們的更多詳細資訊 - 請參閱下文)。 shell 運算子本身訂閱了某些 事件 在 Kubernetes API 中,一旦發生就會啟動對應的鉤子。
shell 操作符如何知道要針對哪些事件呼叫哪些鉤子? 這些資訊由鉤子本身傳送到 shell 操作符,而且它們做得非常簡單。
鉤子是 Bash 腳本或任何其他接受單一參數的可執行文件 --config
並以 JSON 回應。 後者確定它感興趣的對像以及應該回應哪些事件(對於這些對象):
我將說明我們範例之一的 shell 運算子的實作 - 分解用於使用應用程式映像存取私有註冊表的秘密。 它由兩個階段組成。
練習:1.寫一個hook
首先,在hook中我們將處理 --config
,表明我們對命名空間感興趣,特別是它們的創建時刻:
[[ $1 == "--config" ]] ; then
cat << EOF
{
"onKubernetesEvent": [
{
"kind": "namespace",
"event": ["add"]
}
]
}
EOF
…
邏輯會是什麼樣的呢? 也很簡單:
…
else
createdNamespace=$(jq -r '.[0].resourceName' $BINDING_CONTEXT_PATH)
kubectl create -n ${createdNamespace} -f - << EOF
Kind: Secret
...
EOF
fi
第一步是找出創建了哪個命名空間,第二步是使用以下命令創建它 kubectl
此名稱空間的秘密。
練習:2. 組裝影像
剩下的就是將創建的鉤子傳遞給 shell 操作符 - 如何做到這一點? shell-operator 本身就是一個 Docker 映像,所以我們的任務是將鉤子新增到該映像中的特殊目錄:
FROM flant/shell-operator:v1.0.0-beta.1
ADD my-handler.sh /hooks
剩下的就是組裝它並推動它:
$ docker build -t registry.example.com/my-operator:v1 .
$ docker push registry.example.com/my-operator:v1
最後一步是將映像部署到叢集。 為此,我們要寫 部署:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-operator
spec:
template:
spec:
containers:
- name: my-operator
image: registry.example.com/my-operator:v1 # 1
serviceAccountName: my-operator # 2
有兩點要注意:
- 新創建的圖像的指示;
- 這是一個系統元件(至少)需要訂閱 Kubernetes 中的事件並向命名空間分配機密的權限,因此我們為該鉤子建立一個 ServiceAccount(和一組規則)。
結果——我們解決了問題 親戚們 對於 Kubernetes,以建立分解秘密的操作符的方式。
其他 shell 操作符功能
要限制鉤子將使用的所選類型的對象, 它們可以被過濾,根據某些標籤進行選擇(或使用 matchExpressions
):
"onKubernetesEvent": [
{
"selector": {
"matchLabels": {
"foo": "bar",
},
"matchExpressions": [
{
"key": "allow",
"operation": "In",
"values": ["wan", "warehouse"],
},
],
}
…
}
]
假如 重複資料刪除機制,它 - 使用 jq 過濾器 - 允許您將大型 JSON 物件轉換為小型對象,其中僅保留我們想要監視更改的參數。
當呼叫鉤子時,shell 操作符會傳遞它 對象資料,可用於任何需要。
觸發鉤子的事件不限於 Kubernetes 事件:shell-operator 提供支持 按時間調用鉤子 (類似於傳統調度程式中的 crontab),以及特殊事件 啟動時。 所有這些事件都可以組合併分配給同一個鉤子。
shell 運算子的另外兩個功能:
- 有用 非同步地。 由於接收到 Kubernetes 事件(例如正在建立的物件),叢集中可能會發生其他事件(例如正在刪除相同物件),而鉤子需要考慮到這一點。 如果鉤子執行時出錯,那麼預設情況下它將是 記起 直到成功完成(可以更改此行為)。
- 它出口 指標 對於 Prometheus,您可以透過它來了解 shell 運算元是否正常運作,找出每個鉤子的錯誤數和目前佇列大小。
總結報告的這一部分:
安裝附加元件
為了舒適地使用 Kubernetes,也提到需要安裝附加元件。 我將用我們公司現在的做法為例來向您介紹這一點。
我們開始使用具有多個叢集的 Kubernetes,唯一新增的是 Ingress。 它需要在每個叢集中進行不同的安裝,我們為不同的環境做了幾種YAML配置:裸機、AWS…
由於叢集越多,配置也就越多。 此外,我們也改進了這些配置本身,因此它們變得非常異質:
為了讓一切井井有條,我們從一個腳本開始(install-ingress.sh
),它將我們將部署到的叢集類型作為參數,產生必要的 YAML 配置並將其推廣到 Kubernetes。
簡而言之,我們的進一步路徑以及與之相關的推理如下:
- 要使用 YAML 配置,需要一個模板引擎(在第一階段,這是簡單的 sed);
- 隨著叢集數量的增加,自動更新的需求來了(最早的解決方案是將腳本放在Git中,使用cron更新並運行);
- Prometheus 需要類似的腳本(
install-prometheus.sh
),然而,值得注意的是,它需要更多的輸入資料及其儲存(以一種好的方式 - 集中式和叢集中),並且可以自動產生一些資料(密碼): - 向越來越多的叢集推出錯誤的風險不斷增加,因此我們意識到安裝程式 (即兩個腳本:Ingress 和 Prometheus) 需要暫存(Git 中的多個分支,幾個 cron 來在相應的穩定或測試叢集中更新它們);
- с
kubectl apply
它變得很難使用,因為它不是聲明性的,只能創建對象,但不能決定它們的狀態/刪除它們; - 我們缺少一些當時根本沒有實現的功能:
- 完全控制叢集更新的結果,
- 根據可以從叢集取得的資料(發現)自動確定一些參數(安裝腳本的輸入),
- 它以不斷發現的形式邏輯發展。
我們在其他項目的框架內實施了所有這些累積的經驗 -
附加操作符
它基於已經提到的 shell 運算子。 整個系統如下圖所示:
以下內容被加入到 shell-operator 掛鉤中:
- 值儲存,
- 舵圖,
- 組件 監控值存儲 並且 - 如果發生任何變化 - 要求 Helm 重新滾動圖表。
因此,我們可以對 Kubernetes 中的事件做出反應,啟動一個鉤子,透過這個鉤子我們可以對儲存進行更改,之後圖表將被重新下載。 在結果圖中,我們將一組鉤子和圖表分離成一個組件,我們稱之為 模組:
可以有很多模組,我們為它們添加全域鉤子、全域值儲存以及監視該全域儲存的元件。
現在,當 Kubernetes 中發生某些情況時,我們可以使用全域鉤子對其做出反應並更改全域儲存中的某些內容。 此變更將被注意到,並將導致叢集中的所有模組被推出:
此方案符合安裝上述附加元件的所有要求:
- Helm 負責模板化和聲明性。
- 自動更新的問題是使用全域鉤子解決的,該鉤子按計劃進入註冊表,如果在那裡看到新的系統映像,則將其推出(即「自身」)。
- 在叢集中儲存設定是透過使用 配置映射表,其中包含儲存的主要資料(在啟動時它們被載入到儲存中)。
- 使用鉤子解決了密碼產生、發現和持續發現的問題。
- 分段是透過標籤實現的,Docker 開箱即用地支援標籤。
- 使用指標來監控結果,透過這些指標我們可以了解狀態。
整個系統在 Go 中以單一二進位的形式實現,稱為 addon-operator。 這使得圖表看起來更簡單:
此圖中的主要組件是一組模組 (下面以灰色突出顯示)。 現在我們可以花一點力氣為所需的附加元件編寫一個模組,並確保它將安裝在每個叢集中,將被更新並回應叢集中所需的事件。
「植物」用途
我在哪裡可以獲得 addon-operator 的模組? 發布我們的庫是我們的下一階段;我們計劃在夏天進行。
影片和幻燈片
表演影片(約 50 分鐘):
報告介紹:
聚苯乙烯
我們部落格上的其他報導:
- «
資料庫和 Kubernetes “; (Dmitry Stolyarov;8 年 2018 月 XNUMX 日,HighLoad++); - «
監控和 Kubernetes “; (德米特里·斯托利亞羅夫;28 年 2018 月 XNUMX 日在 RootConf); - «
Kubernetes 和 GitLab 的 CI/CD 最佳實踐 “; (Dmitry Stolyarov;7 年 2017 月 XNUMX 日,HighLoad++); - «
我們在小型項目中使用 Kubernetes 的經驗 “; (德米特里·斯托利亞羅夫;6 年 2017 月 XNUMX 日,RootConf).
您可能也對以下出版物感興趣:
來源: www.habr.com