引言
Kubernetes 已經成爲市場上事實上領先的編配工具,不僅對技術公司如此,對所有公司都是如此,因爲它允許您快速且可預測地部署應用程序、動態地伸縮應用程序、無縫地推出新特性,同時有效地利用硬件資源。
本期我們將回顧採用 Kubernetes 作爲容器編排工具的公司所面臨的複雜性和挑戰。我們希望我們提供的經驗教訓、最佳實踐和技巧將幫助您在前往 K8s 旅途中起步並繼續前進。
本期將介紹關於在 Kubernetes 生產環境的最佳實踐,包括:
爲上 K8s 容器雲準備好應用程序
在 Kubernetes 中獲得靈活性和通用性
爲所有應用程序使用單一、可信和可靠的源
自動部署到 Kubernetes
在 Kubernetes 中構建可靠且可伸縮的環境
可見性和安全性:在 Kubernetes 中保護您的應用程序
在 Kubernetes 中記錄、監視和調試您的微服務
將應用程序部署到 Kubernetes 的生產環境中
背景
JFrog 與 Kubernetes 的旅程始於我們尋找一個合適的容器編排解決方案,以便爲內部目的創建一個功能齊全的環境。我們的開發人員需要測試我們非常複雜的環境,包括 JFrog Artifactory 和其他產品。與此同時,我們需要爲程序和產品經理提供一個完整的功能環境,以便向我們的客戶演示平臺。
爲了滿足我們的需求,每個產品都需要一個獨立的 CI/CD 開發環境,以便在測試各個分支之間的交互時獨立地測試各個分支。
隨着我們對 Kubernetes 越來越有信心,我們認識到將 JFrog 產品分發到 Kubernetes 的價值,能夠跨不同的階段、開發和生產環境運行應用程序。Kubernetes 還允許我們更好地利用我們的資源,因爲我們不再需要爲單獨部署每個產品而啓動單個 VM。下面我們將回顧落地過程中的主要挑戰(6大挑戰),同時分享我們的最佳實踐、技巧,和在將您的容器應用程序一路帶到生產環境中所獲得的經驗教訓。
Kubernetes 介紹
Kubernetes 允許您創建容器化的應用程序,並將它們並行的部署,而不必擔心各種服務和組件之間的兼容性。將應用程序容器化運行在 Kubernetes 中的好處是,您可以在一個充滿活力的社區中開發產品,從而更容易創建可伸縮的微服務應用程序。這樣做的缺點是,當整個團隊都在處理各種組件時,情況會很快變得非常複雜。此外,容器化的應用程序可以包含多種組件類型,這取決於您使用的操作系統、語言和框架。
讓我們從使用 Kubernetes 運行應用程序所需的三個基本組件開始:
容器雲集羣
Kubernetes 集羣是您的容器化應用程序運行的編排基礎設施。您需要決定是否要自己管理它,以及是否要使用雲提供商託管它。此組件不在文檔的此範圍內討論。
CI/CD 流水線
CI/CD 流水線在 Kubernetes 中運行,並使流程自動化,從源代碼和外部依賴包開始,一直到將應用程序部署到 Kubernetes 集羣中。Kubernetes 流水線是“應用程序感知的”(面向應用),這意味着它們天生能夠動態地提供一個完整的容器化應用程序堆棧(通常由多個 service、deployments, replica sets, secrets, configmap 等組成)。對應用程序上下文的每次更改,無論是代碼、、鏡像還是配置更改,都將觸發流水線。
Kubernetes Registry
您的生產集羣應該使用一個單獨的、受管理的和可信的真實源,該源存儲和記錄應用程序和其依賴組件。使用 Kubernetes Registry,您可以在一個 pod 中並行運行多個應用程序堆棧,而不產生衝突,也不需要關心每個應用程序的內部依賴關係。這將維護正在運行的集羣、向上和向下擴容應用程序、開發新版本和調試應用程序具體問題分隔開來。
上 K8s 容器雲前準備好你的應用程序
應用程序是服務/解決方案的核心。在 Kubernetes 中運行應用程序之前,需要計劃和準備應用程序。
問卷清單:爲 K8S 準備應用程序
下表顯示了在準備 Kubernetes 應用程序之前必須詢問的與應用程序相關的任務和問題。
有關將構建軟件的基礎知識,請參見軟件12因素。https://12factor.net/
在 Kubernetes 中獲得靈活性和通用性
多語言編程和多種不同的工具和技術提供了多種可能性。您可以選擇最適合您的業務需求的技術,但是每種技術可能有不同的接口、REST API和自己的包格式。支持這些工具的唯一方法是做到在製品從創建到部署的生命週期的管理中實現通用。
部署 Artifactory 作爲您的 Kubernetes Registry
通過使用 Artifactory 作爲“Kubernetes Registry”,您可以獲得靈活性和通用性,作爲可信的單一來源,它允許您深入瞭解代碼到應用集羣的過程,同時關聯每個應用程序的每一層(layer)。Artifactory 在一個系統中支持超過25種不同的技術棧,具有一個元數據模型、一個升級流和強大的製品依賴關係。
Artifactory 允許您將容器化的微服務部署到 Kubernetes 集羣,因爲它作爲一個通用存儲庫管理平臺來滿足您的所有 CI/CD 需求,而不管它們在您的組織中何處運行。登記應用程序包後,可以繼續傳播和執行構建、測試、升級,最後部署到 Kubernetes。爲了方便地將 Artifactory (和其他JFrog產品)部署到 Kubernetes,請參考我們在helm hub 中的官方 JFrog Helm Charts(https://hub.helm.sh/charts/jfrog)。
自動化部署到Kubernetes
在 CI/CD 流水線的每個階段中不需要人工干預的情況下可靠地大規模部署應用程序是的協調的主要原因。但是如何以一種可重複、可靠的方式將代碼發佈到集羣中呢?如何確保只有正確版本的應用程序才能投入生產?
爲此,我們建議將 Artifactory 部署爲存儲庫管理平臺,通過抹平開發和操作之間的差距在CI/CD 流水線中扮演重要角色。
將 Artifactory 部署爲 Helm Charts 倉庫
Artifactory 原生支持 Helm 存儲庫,使您能夠完全控制 Kubernetes 的部署過程。它提供安全的、私有的、本地的 Helm 存儲庫,通過細粒度的訪問控制在您的組織中共享 Helm Charts。使用遠程存儲庫代理和緩存公共 Helm Charts 資源,並將本地和遠程資源聚合到單個虛擬 Helm 存儲庫下,從而從單個 URL 訪問所有 Helm Charts。
K8S 專家建議:
當使用 Artifactory 作爲您的 Helm 存儲庫時,我們建議:
分離您的穩定存儲庫和開發階段存儲庫(基於成熟度)。
在 Charts 中使用 SemVer version 2版本。
定期重新計算索引。
在 CI/CD 流水線中部署應用程序的最佳實踐
在 CI/CD 流水線中部署應用程序時,我們建議:
使用相同的 Helm Chart 進行本地、分段、測試和生產,同時每個環境使用不同的Value.yaml 文件。每個 yaml 都需要包含特定的環境配置值。例如:values-stg..yaml,,value-prod.yaml。
在 VCS 源代碼管理系統中管理應用自定義值。
默認配置值 value.yaml 應該是針對開發人員或本地的,這樣開發人員就可以輕鬆地在本地使用它。
對依賴項使用外部 charts。使用社區已經完成的工作!
出於安全目的:將您的×××從 Charts 中分離出來,並將它們作爲外部 Charts 引用。
升級發佈可靠和可伸縮的應用到Kubernetes 環境
在 Kubernetes 集羣中並行運行多個應用程序需要建立對工件(Docker 鏡像)的持續訪問,同時支持零停機的高負載服務。
在 Kubernetes 部署 Artifactory 高可用
通過在 Kubernetes 集羣中部署 Artifactory HA(高可用),在集羣中,您將體驗到零宕機服務,如果一個 pod 被回收或崩潰,或者節點意外停機,容器集羣將自動調度恢復對應服務的 Pod。
在 Kubernetes 部署 Artifactory HA 的好處是:
在不影響性能的情況下,支持更高的負載兵法。
提供水平服務器可伸縮性,允許您在組織增長時輕鬆地增加容量以滿足任何負載需求。
支持在沒有系統停機的情況下執行大多數維護任務。
通過使用零停機時間替換應用程序的各個實例,可以在實例上安裝更新版本,從而支持滾動升級。
在下例中,使用三個節點部署了一個 Artifactory HA 集羣:一個主節點和兩個成員節點。因爲負載均衡只在成員節點上執行。這使得主節點可以自由地處理作業和任務,不會被入站流量中斷。
Kubernetes 集羣的存儲和可伸縮性
Artifactory HA 允許您在 Kubernetes 中突破應用程序的限制,因爲它支持大量存儲替代方案。有關更多信息,請參見配置文件存儲庫。
(https://www.jfrog.com/confluence/display/RTF/Configuring+the+Filestore)
可見性和安全性:在 Kubernetes 中保護您的應用程序
像 Docker 和 Kubernetes 這樣的雲本地技術提供了更大的***面,爲惡意數據挖掘、勒索軟件和數據盜竊提供了更多潛在的入口點。在 Kubernetes 集羣中運行的服務並不是完全獨立的,它們可以訪問集羣中的其他區域。
正是出於這個原因,集羣的可見性非常重要,尤其是從安全性的角度來看。您需要知道容器中運行的是什麼,因爲您的應用程序很少包含單個組件,而是包含外部依賴項,如 OS 包、OSS libs 和第三方流程。這就引出了一個不可避免的問題——它們安全嗎?它們是否包含安全漏洞?他們是否遵守自由/開源軟件許可?
獲的 k8s 中容器的可見性
Artifactory 通過提供可審覈性來深入瞭解整個 CI/CD 流程,因爲它捕獲了整個 CI/CD 流程中產生的大量有價值的元數據。您可以跟蹤負責生成 Docker 鏡像層的應用層的 CI 作業。它還可以通過允許比較兩個構建來顯示構建差異,從而很容易地跟蹤 Docker 鏡像基於哪個層生成的,到哪個構建產生的,從而跟蹤到提交。
( K8 專家提示:
推薦閱讀:每個人都必須遵循9個 Kubernetes 安全最佳實踐。
(https://www.cncf.io/blog/2019/01/14/9-kubernetes-security-best-practices-everyone-must-follow/))
掃描和檢測容器中的漏洞
JFrog Xray 與 Artifactory 協作,在應用程序生命週期的任何階段執行二進制軟件工件的通用分析。它對容器中的所有層執行遞歸掃描,並通過掃描和分析工件及其元數據(遞歸地遍歷任何級別的依賴關係)來幫助識別所有層中的漏洞。可以在 Xray 中設置策略,根據 Xray 掃描發現的風險級別限制或阻止容器鏡像部署到 Kubernetes。通過這種方式,可以阻止脆弱或不兼容的應用程序運行,或者限制它們在啓動時可以做什麼。
在 K8S 中保護您的開源項目
大多數應用程序嚴重依賴於包管理器和開源存儲庫,因此很容易受到來自這些源的惡意或不安全代碼的***。作爲我們支持和貢獻開源社區計劃的一部分,JFrog 開發了 KubeXray,這是一個開源項目,它將 Xray 的安全性擴展到 Kubernetes pod 中運行(或即將運行)的應用程序。使用 Xray 通過掃描容器映像生成的元數據,KubeXray 可以對已經部署的內容執行策略。
KubeXray 監控您所有的活動 Kubernetes Pod,以幫助您:
捕獲當前在所有 Kubernetes Pod 中運行的應用程序中最新的風險或漏洞。
對正在運行的應用程序強制執行當前策略,即使您已經更改了這些策略。
對未被 Xray 掃描且風險未知的正在運行的應用程序執行策略。
使用 Helm 2 防止未經授權的訪問
Helm 2 包含一個名爲“Tiller”的服務器端組件。Tiller 是一個集羣內的服務器,它與 Helm客戶端交互,並與 Kubernetes API 服務器交互。
Tiller 絕對是很酷的,但重要的是要知道有安全問題。這是因爲 Helm 客戶端負責管理 Charts,而服務器負責管理髮布。這帶來了很大的風險,因爲 Tiller 使用 root 權限運行,有人可能會未經授權訪問您的服務器。
Rimas Mocevicius 是 JFrog 公司的一名員工,也是 Helm 公司的聯合創始人,他提出了一種創新的方法來解決這種情況,即在工作站上或 CI/CD 管道上運行 Helm 和 Tiller,而不將 Tiller 安裝到 Kubernetes 集羣中。您可以下載並安裝無 Tiller 的 Helm v2 插件。
使用用 RBAC 管理 Kubernetes
必須將 RBAC(基於角色的訪問控制)設置爲 Kubernetes 的管理功能,因爲它允許您定義哪個用戶可以管理集羣及其粒度。除了定義可以列出哪些用戶和應用程序之外,還可以獲取、創建或刪除 pods 和其他 Kubernetes 對象。一個好的實踐是通過在爲應用程序創建的服務帳戶中設置 “automountServiceAccountToken: false” 來禁用對 API 的訪問。
如果沒有指定服務帳戶,它會自動將相同名稱空間中的“默認”服務帳戶分配給 pod。我們建議不要使用名稱空間附帶的默認值。始終爲應用程序創建服務帳戶,因爲它允許您設置應用程序的限制,包括名稱空間或集羣範圍的操作,並完全禁用對 Kubernetes API 的訪問。
在 K8S 中記錄日誌、監視和調試應用程序
微服務的數量隨着複雜性的增加而增加,問題是如何跟蹤和監視它們,以及應該監視什麼。當涉及到微服務時,您需要收集以下數據微服務:
意外事件:例如,在數據庫容器中執行的所有權更改
微服務宕機。
不正確的文件選擇在生產造成混亂。
不允許使用特定的基本 OS 版本。
在 Kubernetes 中應用程序記錄日誌的最佳實踐
應用程序和系統日誌對於排除 Kubernetes 集羣活動的故障非常重要。
在 Kubernetes 中應用程序記錄日誌時,請遵循以下最佳實踐:
限制對日誌的直接訪問。
在使用 Kubernetes 儀表板(不推薦用於生產環境)時,將儀表板設置爲具有訪問權限的只讀。您可以允許其他成員執行故障排除,但不要完全訪問儀表板,因爲它可能會對 Kubernetes 集羣造成損害。
確保您的日誌是實時可訪問的,並且可以在稍後的階段進行分析。
使用 ELK/EFK 技術棧等日誌收集工具(ElasticSearch、Logstash/Fluentd和Kibana)收集和索引來自系統和應用程序的所有日誌。
考慮將日誌保存在單獨的集羣中,以便在稍後階段使用日誌。如果集羣宕機,允許您訪問日誌
持續監控 K8S 中的微服務
持續監視系統和應用程序健康狀況非常重要。
對於實時監視 Kubernetes 集羣和其中運行的應用程序,有許多免費的和商業的解決方案。其中一個流行的解決方案是 Prometheus ,Grafana 的結合,提供實時監控,可以與報警工具相結合。
將應用程序部署到 K8S 生產環境中
在 K8S 順利開始旅程的10個技巧
1. 對於初學者,我們建議從閱讀 Kubernetes 的艱難方式開始!
(https://github.com/kelseyhightower/kubernetes-the-hard-way/blob/master/README.md)
2. 從小事做起。從示例中學習,從一個小應用程序(nginx)開始,使用現有的演示,並嘗試在 Docker 的 Skin Kubernetes 中部署應用程序。
3. 在進入 K8S 之前準備好你的應用程序。
(https://docs.google.com/document/d/1YS_jICIEPZLle7KcpEoLjuKCZ_TkgNzb9LajPU4AhsI/edit#heading=h.81oh8o1kpi75)
4. 爲使應用程序在 k8s 中運行,設置一個最小的目標。
5. 使用託管的 k8S 來解放您的工作,例如:AKS、ESK 或 GKE,它們爲您抽象了許多複雜性。
6. 每個 Pod 有一個主容器。
7. 我們建嘗試 GKE 託管管理 Kubernetes。
8. 確定在 Kubernetes 集羣內或集羣外存儲數據庫的位置。這一點非常重要,因爲您需要在集羣崩潰時計劃集羣恢復。考慮以下:
當 K8S 在 prem 上運行時: 在 Kubernetes 中將現有的數據庫作爲無狀態應用程序使用。
在雲上運行 K8S 時:,選擇一個如 PostgreSQL 或 MySQL 的 operator ,其知道如何在 Kubernetes 節點宕機時恢復的持久化數據庫。
9. 部署到容器雲時,請將對應集羣分開,運行 CI/CD 流水線,以及從外部 CI/CD 流水線部署應用到 Kubernetes 集羣。
10. 與社區合作
總結
正如本篇文章所描述的,我們展示了 Kubernetes 和 JFrog Artifactory 是如何讓您可靠地、可預測地部署應用程序、動態地伸縮應用程序、無縫地推出新特性並有效地利用硬件資源的。
本篇文章旨在回顧希望採用 Kubernetes 作爲容器編排工具的公司所面臨的複雜性和挑戰。我們希望我們分享的經驗教訓、最佳實踐和技巧將幫助您在前往 K8s 的旅途中起步並繼續前進。
文章作者:劉永強,JFrog 中國解決方案架構師,服務客戶有中興通訊,宜人貸,易保科技,順豐等等,專注系統架構、軟件 CI/CD 及 Devops 領域,曾在 HPE,億瑪等公司任高級工程師,負責過多個互聯網平臺和移動應用的研發和運維工作。