與雲無關的用於 Kubernetes 的自動化 CI/CD
本文首發於:Jenkins 中文社群
在本文中,我想討論一種在雲環境中為 Kubernetes 工作負載實現自動化端到端 CI/CD 的方法。 這裡可能有其它解決方案,而像 AWS、Microsoft Azure 和 GCP 這樣的雲提供商也提供了自己的一套框架,以實現與 Kubernetes 相同的目標。
它的部署模型的核心是 Rancher,Rancher 負責為託管在不同雲環境和裸機環境中的多個 Kubernetes 叢集提供集中管理與運營的能力。 根據應用程式和業務需要,這裡提到的工具可以替換為自己選擇的工具。
在詳細介紹之前,這裡有張部署模型的快照:
持續整合元件
我們使用 JIRA、BitBucket、Bamboo 和 Nexus 作為自動化持續整合元件。 需求和使用者故事來自 JIRA ; 開發人員將他們的程式碼放進 BitBucket ; 程式碼被程式碼評審工具和靜態分析工具構建與整合,Bamboo 生成的 Docker 映象被推送到 Nexus。 這些映象會經過特定的容器安全檢查。
當你有許多微服務/應用程式需要構建時,那麼處理 Kubernetes 叢集工作負載的部署、升級和回滾可能會複雜。 版本控制是我們需要考慮的另一個挑戰。 Helm 有助於克服這些大多數挑戰,並使部署變得簡單。
如果你想知道你是否需要有一個 chart 將所有 deployments 包含在其中, 或者允許每個應用程式和微服務都有一個單獨的 chart , 那麼我們希望將這些 charts 放到特定的應用程式或微服務的倉庫中, 這樣我們就不需要有單獨的倉庫來維護 Helm 製品。 這就省去了為實際的程式碼和 Helm 模板維護兩個獨立倉庫的工作。 開發人員可以對任何應用程式程式碼更改所需的模板更改有更多的控制權。
Nexus 作為 Docker 映象和 Helm chart(使用的是 Helm Nexus 外掛)的倉庫。 每次成功構建應用程式後,映象和 chart 都是可用的並被推送到 Nexus 。
持續部署元件
為了實現與雲無關的準備,我們選擇了 Terraform ,因為它易於學習並易於部署。 我們發現對於準備後的配置管理/維護活動, Terraform 並不是非常有用,所以我們還放置了一些 Ansible 指令碼。 我們也曾考慮 Ansible 用於準備,但是使用 Terraform 可以讓我們更好地控制啟動例項, 這些例項可以作為 Rancher Server/節點,並且可以被自動的新增到自動伸縮組中。 我們使用啟動指令碼功能實現了這一點。
我們認為可以將為 AWS 編寫的大多數 Terraform 指令碼重用到 Azure 中,但事實並非如此。 我們必須做出相當大的改變。
我們部署了一個執行在三個不同例項上的高可用的 Rancher Server ,前面有一個 NGINX Server 來為這三個例項做負載均衡。 部署是使用 Terraform 和啟動指令碼完成的。 指令碼使用 RKE ( Rancher Kubenetes 引擎)和 Rancher API 呼叫來啟動叢集(高可用的 Rancher Server )。
Rancher 提供了各種選項來在不同的雲提供商上新增 Kubernetes 叢集。 您可以從選項中進行選擇,使用託管的 Kubernetes 提供商,或者使用基礎設施提供商的節點或自定義節點。 在這個場景中,我們選擇使用 AWS 和 Azure 上的自定義節點,而不是託管的 Kubernetes 提供商。 這幫助我們向自動伸縮組新增一組工作節點,並使用叢集自動伸縮器進行節點伸縮。
所有這些都是通過啟動指令碼和 Rancher API 呼叫自動完成的,因此任何通過 ASG (和自動伸縮器)新增的新節點都會自動註冊為一個 Rancher/Kubernetes 節點。 通過啟動指令碼自動執行的一些活動包括:
- 安裝和配置所需的 Docker 版本
- 在所有例項上安裝和配置 Zabbix 代理(稍後將在監控中使用)
- 安裝所需的 GlusterFS 客戶端元件
- 安裝所需的 kubectl 客戶端
- 後端資料庫叢集所需的任何其他自定義配置
- 自動掛載額外的 EBS 卷和 GlusterFS 卷
- 為 Rancher 代理/Kubernetes 節點執行 Docker 容器並附加特定的角色( etcd/controlplane/worker )
- 檢查以確保 Rancher 代理可用、啟動和執行。
GlusterFS 被考慮可以處理 EBS 和 Azure 中不可用的 ReadWriteMany 磁碟卷型別。 這對於我們部署的許多應用程式都是必需的。
一個 ELK stack ( ElasticSearch、Logstash 和 Kibana )使用 Helm charts 部署在 Kubernetes 上, 並被配置為通過 logstash 推送容器日誌、審計和其他自定義日誌。
HAProxy 和 NGINX 被用於兩個不同的目的。 NGINX 是在 Rancher Server HA 設定期間所提供的預設 ingress controller 。 這用於三個 Rancher Server 的負載均衡。 我們在 Kubernetes 叢集上部署了一個 HAProxy Ingress Controller, 這樣我們就可以通過這些特定的節點(其 IPs 對映到特定的 FQDNs)暴露應用程式的 end points 。 HAProxy ingress controller 被部署為 daemonset ,因此對於任何額外的負載,節點的數量會基於自動伸縮組和自動伸縮器自動增加。
持續監控元件
我們部署了 Prometheus、Grafana 和 Alertmanager 套件,用於容量規劃以及監控 Rancher/Kubernetes 叢集的狀態。 這再次通過 Rancher Helm Chart Provisioner 部署。 我們也可以通過常規的/穩定的 Helm charts 來部署它。 它確實有助於我們監控和收集開發環境中諸如 CPU、記憶體利用率和 IO 操作之類的指標,並據此為 staging 環境和生產環境進行容量規劃。
我們還在叢集上部署了 Zabbix Server,它用於為部署的所有節點監控各種作業系統級別的和應用程式特定的指標和警告。 這包括任何後端資料庫叢集節點、Kubernetes 節點、Rancher servers、檔案伺服器或通過 Terraform 提供的任何其他伺服器。 Zabbix Server 被配置為節點/代理自動註冊,以便通過自動縮放組或自動縮放器新增到叢集中的任何新節點都可用於監控。
結論
這是我們為 Kubernetes 工作負載構建完整的 CI/CD 工具鏈所遵循的方法之一。 這個模型幫助我們自動化所有的三個環境的準備。 通過 Rancher ,我們能夠提供一個開發環境,每個開發人員都可以使用這個專案概念。 每個開發人員都有一個節點和一個專案,它由 RBAC 控制,這樣他們就可以部署和測試他們自己的更改。 沒有人可以看到專案/節點的詳細資訊,也不會妨礙其他開發人員部署的 Kubernetes 工作負載。 由於節點自動註冊到 Rancher Server,系統重新啟動不會影響節點的可用性。 即使在最壞的情況下,如果節點丟失,也很容易在幾分鐘內開啟一個新節點。 應用程式可以使用 Helm charts 進行部署,也可以使用 Rancher 提供的內建的 Helm charts 進行部署。
這些是我們部署的來管理整個環境的一些高階元件。 我們考慮的其他方面是高可用性叢集環境,用於 Rancher servers、Kubernetes 叢集、Gluster 檔案伺服器叢集或任何其他後端叢集。 在提出此方法時,需要考慮生產級環境所需的更改和更新。 還考慮了其他方面,例如對叢集例項的安全訪問、升級、備份和恢復,以及根據行業標準提出的分層體系結構建議。
希望本文為您提供一些參考,當您計劃為多個雲提供商提供生產級環境準備時,可以考慮這些參考。