本篇文章是個經驗分享系列文,作者探討 Kubernetes 內 15 種不被建議的部署策略與模式。
作者之前曾經撰寫過 Contianer 架構底下的部署模式探討,而本系列文(三篇)則是著重於如何將這些 containers 透過 Kubernetes 給部署到生產環境,總共會探討十五種不推薦的模式,接下來的三篇文章將會介紹各五種不好的模式。
Using containers with the latest tag in Kubernetes deployments
任何 container 的 image 都不應該使用 latest,因為 latest 本身沒有任何意義,這會使得維運人員沒有辦法掌握到底當前部署的版本是什麼,更嚴重的情況適當 latest 搭配 PullPolicy:Always 時會產生更為嚴重的問題。因為 Always 的策略導致每次 Pod 部署時都會重新抓取 image,所以一個 deployment 中,多個使用 latest tag 的 Pod 但是其實使用的 image hash 是不同的。
作者認為比較好的做法有
1. 所有 container image 都是不可修改的,一旦建立就禁止覆蓋,有任何改動就進版
2. 部署用的 image tag 使用有意義的版本名稱
補充: 實際上 pull image 也可以使用 sha256,譬如 "docker pull hwchiu/kubectl-tools@sha256:acfb56059e6d60bf4a57946663d16dda89e12bfb1f8d7556f277e2818680e4c8"
Baking the configuration inside container images
任何 contaienr image 建置的時候應該都要往通用的方向去設計,而不是參雜各種設定在裡面。著名的 12-factor app 裡面也有提到類似個概念,建置好的 image 應該要可以 build once, run everywhere,動態的方式傳入不同的設定檔案,而不是把任何跟環境有關的資訊都寫死
舉例來說,如果 image 內包含了下列設定(舉例,包含不限於)
1. 任何 IP 地址
2. 任何帳號密碼
3. 任何寫死的 URL
作者認為比較好的做法有
1. 透過動態載入的方式來設定運行時的設定,譬如Kubernetes configmaps, Hashicorp Consul, Apache Zookeeper 等
2. 根據不同程式語言與框架甚至可以做到不需要重啟容器就可以載入新的設定
Coupling applications with Kubernetes features/services for no reason
作者認為除了很明確專門針對 Kubernetes 使用,或是用來控制 Kubernetes 的應用程式外,大部分的 應用程式包裝成 Container 時就不應該假設只能運行在 Kubernetes 內。作者列舉了幾個常見的使用範例,譬如
1. 從 K8s label/annotation 取得資訊
2. 查詢當前 Pod 運行的資訊
3. 呼叫其他 Kubernetes 服務(舉例,假設環境已經存在 Vault,因此直接呼叫 vault API 來取得資訊)
作者認為這類型的綁定都會使得該應用程式無法於沒有 Kubernetes 的環境運行,譬如就沒有辦法使用 Docker-compose 來進行本地開發與測試,這樣就沒有辦法滿足 12-factor 中的精神。
對於大部分的應用程式測試,除非其中有任何依賴性的服務是跟外部 Kubernetes 綁定,否則這些測試應該都要可以用 docker-compose 來叫起整個服務進行測試與處理。
服務需要使用的資訊應該是運行期間透過設定檔案,環境變數等塞入到 Container 內,這樣也呼應上述的不要將與環境有關的任何資訊都放入 image 內。
Mixing application deployment with infrastructure deployment (e.g. having
Terraform deploying apps with the Helm provider)
作者認為近年來伴隨者 IaC 概念的熱門,愈來愈多的團隊透過 Terraform/Pulumi 這類型的工具來部署架構,作者認為將部署架構與部署應用程式放到相同一個 Pipeline 則是一個非常不好的做法。
將基礎架構與應用程式同時放在相同 pipeline 可以降低彼此傳遞資訊的困難性,能夠一次部署就搞定全部,然而這種架構帶來的壞處有
1. 通常應用程式改動的頻率是遠大於基礎架構的改變,因此兩者綁在一起會浪費許多時間在架構上
假如部署基礎架構需要 25 分鐘而應用
https://codefresh.io/kubernete.../kubernetes-antipatterns-1/
同時也有10000部Youtube影片,追蹤數超過2,910的網紅コバにゃんチャンネル,也在其Youtube影片中提到,...
k8s deployment 介紹 在 矽谷牛的耕田筆記 Facebook 的最佳貼文
本篇文章作者認為透過 Kubernetes Operator 的設計與精神,是有辦法達到夢寐以求中的 Zero-touch Ops,甚至發展到所謂的 AIOps,維運人員盡可能地減少主動去管理應用程式的部署。
一開始探討到微服務架構與 DevOps 文化的興起,愈來愈多的叢集與資源需要管理,但是如果今天應用程式本身難以管理的話,維運人員則必須要花費大量的精力與時間來部署這些應用程式,這無疑是種本末倒置的行為。
本文一開始作者先快速地複習什麼是 Operator,基本上可以當作是 k8s controller 的延伸版本,畢竟 K8s controller 其運作原理也是透過一個無止盡的迴圈,根據使用者輸入事先定義的好的資源格式,來確保當前叢集內的運行狀態有符合需求。Operator 基於這個概念上,讓使用者可以使用 CRD 這種自定義的格式來定義自己的資源,不單純只是所謂的 deployment/pod/service 等,可以是更符合應用程式需求的抽象資源,譬如 GitRepo, Network, PrometheusService 等
文章內還有更多關於 Operator 的介紹,包含如何透過 SDK 來撰寫開發一個 Operator,有興趣瞭解的
不可錯過。
文章後半部在探討關於 AIOPs 如何達成 Zero-Touch Ops 的願景,文中先以一張圖片來解釋 AIOps 的架構,最後提到如何將 AIOPs 與 Operator 的架構整合為一,該架構中整合了不少常見服務來滿足不同面向的要求,譬如 Grafana, Prometheus, ServiceMesh/istio, Ansible 等。
https://medium.com/faun/kubernetes-operators-to-realize-the-dream-of-zero-touch-ops-5bc8c3e5e11b
k8s deployment 介紹 在 矽谷牛的耕田筆記 Facebook 的最讚貼文
今天這篇文章也是一個入門介紹文,雖說是一個入門介紹文,但是我覺得期主題滿好的,主要是針對 Ingress 這個架構來探討。我個人認為 Kubernetes 的架構加上 Yaml 安裝一切的結果很容易導致大家其實不知道 Kubernetes 做了什麼,也不知道架構到底是什麼,總之 Yaml 寫寫功能就通了。因此如果本來對於 Ingress 背後含義與架構的讀者是可以參考這篇文章重新複習一下對於 Ingress/Ingress Controller 的差異與概念。
Ingress: 其實從抽象層面來看, Ingress 就如同過往使用的 reverse proxy 一樣,根據不同的方式來轉發不同的請求封包到不同的後端服務。然而這個抽象概念於 Kubernetes 被拆分為二,分別為資訊定義端以及真正實作端。
舉例來說,假如我們採用 Nginx 作為 Ingress 的解決方案
資訊定義端(Ingress Yaml Definition): Ingress 的物件描述,也就是大家最常看到的 Ingress Yaml 資源格式,這個格式是由 kubernetes 所定義,本身沒有任何實作功能,完全是一群規則的描述。
真正實作端(Ingress Controller): 負責將 Ingress 物件轉換成 Nginx.conf,並且動態的告知 Nginx 伺服器去載入最新的設定檔案
這也是我們為什麼都要先安裝一個 deployment之類的服務到 k8s 之中,該 deployment 會扮演 Ingress Controller 的角色
接者我們根據需求部署各種 Ingress 規則到系統中,然後先前部署的 Ingress Controller 就會去抓取這些資源,並且轉換成真正可行的 nginx.conf 這種資源
本文使用的是 Kong 這套解決方案,但是整體運作邏輯跟上述提到用 Nginx 的邏輯一樣,因為這邊遵循的都是 k8s Ingress 的運作模式,因此只要搞懂其背後邏輯,未來學習任何一套解決方案的時候,都會有相同的脈絡跟模式可以參考,比較不會瞎子摸象的感覺
原文: https://medium.com/swlh/kubernetes-ingress-simplified-e0b9dc32f9fd