1. 程式人生 > 其它 >從Spring Cloud到Kubernetes的微服務遷移實踐

從Spring Cloud到Kubernetes的微服務遷移實踐

寫在前面

要出發周邊遊(以下簡稱要出發)是國內知名的主打「周邊遊」的線上旅行網站,為了降低公司內部各個業務模組的耦合度,提高開發、交付及運維效率,我們在 2017 年就基於 Spring Cloud 完成了公司內部業務微服務化的改造,並在 2019 年實現了 Spring Cloud 至 UK8S 平臺的遷移。本文從要出發的業務架構、Prometheus JVM 監控、基於 HPA 的峰值彈性伸縮、基於 Elastic 的APM鏈路跟蹤及 Istio 服務治理等方面介紹了我們基於UK8S的 Spring Cloud 改造實踐。

Why K8S & Why UK8S

Spring Cloud 作為當下主流的微服務框架,在功能層面為服務治理定義了智慧路由、熔斷機制、服務註冊與發現等一系列的標準,並提供了對應的庫和元件來實現這些標準特性,對微服務周邊環境提供了最大力度的支援。

改造前,Spring Cloud 的業務架構如下:服務發現部分採用了 Spring Cloud 的 Eureka 元件,熔斷器元件採用了 Hystrix,服務閘道器使用了Zuul 和 Spring Cloud Gateway(歷史原因),分散式配置主要採用了 Spring Cloud Config(部分小組使用了Apollo),並通過 Feign 實現了客戶服務端的負載均衡。

但 Spring Cloud 也有一些不可避免的缺點,如基於不同框架的不同元件帶來的高應用門檻及學習成本、程式碼級別對諸多元件進行控制的需求與微服務多語言協作的目標背道而馳。

在我們內部,由於歷史原因,不同小組所使用的 API 閘道器架構不統一,且存在多套 Spring Cloud,給統一管理造成了不便;Spring Cloud 無法實現灰度釋出,也給公司業務釋出帶來了一定不便。更重要的是,作為一家周邊遊網站,我們經常會舉行一些促銷活動,面臨在業務峰值期資源彈性擴縮容的需求,僅僅依靠 Spring Cloud 也無法實現資源排程來滿足業務自動擴縮容的需求。

在決定向 UK8S 轉型時,我們也考慮過使用 Kubespray 自建 K8S 叢集,並通過 Cloud Provider 實現 K8S 叢集與雲資源的對接,例如使用 Load Balance、Storage Class、Cluster Autoscaler(CA) 等,但在這種情況下,新增 Node 節點需要單獨去部署安裝 Cloud Provider,給運維工作帶來了一定的複雜性。

UK8S 實現了與內部 UHost 雲主機、ULB 負載均衡、UDisk 雲盤等產品的無縫連線,我們能夠在 UK8S 叢集內部輕鬆建立、呼叫以上產品。在峰值彈性的場景下,也能夠通過 UK8S 內部的 CA 外掛,實現 Node 級別的資源自動擴縮容,極大提升了運維效率。通過其 CNI 外掛,UK8S 與 UCloud 自身 VPC 網路相連線,無需採用其他開源網路解決方案,降低了網路複雜度;而且 UK8S 原生無封裝的特質,也給了更大的改造空間,並且能夠在出現故障時自己快速排查定位解決。

整體業務架構

從 Spring Cloud 到 UK8S 的過程,也是內部服務模組再次梳理、統一的過程,在此過程中,我們對整體業務架構做了如下改動:

1.去掉原有的 Eureka,改用 Spring Cloud Kubernetes 專案下的 Discovery。Spring Cloud 官方推出的專案 Spring Cloud Kubernetes 提供了通用的介面來呼叫Kubernetes服務,讓 Spring Cloud 和 Spring Boot 程式能夠在 Kubernetes 環境中更好執行。在 Kubernetes 環境中,ETCD 已經擁有了服務發現所必要的資訊,沒有必要再使用 Eureka,通過 Discovery 就能夠獲取 Kubernetes ETCD 中註冊的服務列表進行服務發現。

2.去掉 Feign 負載均衡,改用 Spring Cloud Kubernetes Ribbon。Ribbon 負載均衡模式有 Service / Pod 兩種,在 Service 模式下,可以使用 Kubernetes 原生負載均衡,並通過 Istio 實現服務治理。

3.閘道器邊緣化。閘道器作為原來的入口,全部去除需要對原有程式碼進行大規模的改造,我們把原有的閘道器作為微服務部署在 Kubernetes 內,並利用 Istio 來管理流量入口。同時,我們還去掉了熔斷器和智慧路由,整體基於 Istio 實現服務治理。

4.分散式配置 Config 統一為 Apollo。Apollo 能夠集中管理應用在不同環境、不同叢集的配置,修改後實時推送到應用端,並且具備規範的許可權、流程治理等特性。

5.增加 Prometheus 監控。特別是對 JVM 一些引數和一些定義指標的監控,並基於監控指標實現了 HPA 彈性伸縮。

Kubernetes 化後業務架構將控制平面和資料平面分開。Kubernetes Master天然作為控制平面,實現整套業務的控制,不部署任何實際業務。資料平面中包含了基於 Java、PHP、Swoole、.NET Core 等不同語言或架構的專案。由於不同語言對機器效能有著不同要求,我們通過 Kubernetes 中節點 Label,將各個專案部署在不同配置的 Node 節點上,做到應用間互不干擾。

基於Prometheus 的JVM監控

在 Spring Cloud 遷移到 Kubernetes 後,我們仍需要獲取 JVM 的一系列底層引數,對服務的執行狀態進行實時監控。Prometheus 是目前較為成熟的監控外掛,而 Prometheus 也提供了 Spring Cloud 外掛,可以獲取到 JVM 的底層引數,進行實時監控。

我們設定了響應時間、請求數、JVM Memory、JVM Misc、Garbage Collection 等一系列詳盡的引數,為問題解決、業務優化提供可靠的依據。

基於HPA的峰值彈性伸縮

要出發作為一家周邊遊服務訂購平臺,在業務過程中經常會涉及到景區、酒店門票賣二手手遊平臺地圖搶購等需要峰值彈性的場景。Kubernetes 的 HPA 功能為彈性伸縮場景提供了很好的實現方式。

在 Kubernetes中,HPA 通常通過 Pod 的 CPU、記憶體利用率等實現,但在 Java 中,記憶體控制通過 JVM 實現,當記憶體佔用過高時,JVM 會進行記憶體回收,但 JVM 並不會返回給主機或容器,單純基於 Pod / CPU 指標進行叢集的擴縮容並不合理。我們通過 Prometheus 獲取 Java 中 http_server_requests_seconds_count(請求數)引數,通過介面卡將其轉化成 Kubernetes API Server 能識別的引數,並基於這一指標實時動態調整 Pod 的數量。

UK8S 產品也提供了自身的叢集伸縮外掛,通過設定伸縮組,並匹配相應的伸縮條件,能夠及時建立相應的雲主機作為 Node 節點,方便我們在業務高峰時期更快速高效地拉起資源。

基於Elastic的APM鏈路跟蹤

微服務框架下,一次請求往往需要涉及到多個服務,因此服務效能監控和排查就變得複雜;不同服務可能由不同的團隊開發,甚至使用不同的程式語言來實現;服務有可能部署在幾千臺伺服器,橫跨多個不同的資料中心。

因此,就需要一些可以幫助理解系統行為、用於分析效能問題的工具,以便發生故障的時候,能夠快速定位和解決問題。

目前市面有很多開源的APM元件,Zipkin、Pinpoint、Skywalking等等。我們最終選擇了基於Elastic開源的apm-server。正是由於市面上有太多的監控開源專案,但是各專案之間無法很好的互通。而Elastic通過filebeat收集業務日誌,通過metricbeat監控應用服務效能,通過apm-server實現服務間的tracing,並把資料統一存放在es,很好的將logging、metrics、tracing整合到一起,打破了各專案之間的壁壘,能夠更快速的協助運維及開發定位故障,保障系統的穩定性。

Istio服務治理

基於應用程式安全性、可觀察性、持續部署、彈性伸縮和效能、對開源工具的整合、開源控制平面的支援、方案成熟度等考慮,我們最終選擇了 Istio 作為服務治理的方案,主要涉及以下幾個部分:1.Istio-gateway 閘道器:Ingress Gateway 在邏輯上相當於網格邊緣的一個負載均衡器,用於接收和處理網格邊緣出站和入站的網路連線,其中包含開放埠和TLS的配置等內容,實現叢集內部南北流量的治理。

2.Mesh 閘道器:Istio內部的虛擬Gateway,代表網格內部的所有Sidecar,實現所有網格內部服務之間的互相通訊,即東西流量的治理。

3.流量管理:在去除掉 Spring Cloud 原有的熔斷、智慧路由等元件後,我們通過對 Kubernetes 叢集內部一系列的配置和管理,實現了 http 流量管理的功能。包括使用 Pod籤對具體的服務程序進行分組(例如 V1/V2 版本應用)並實現流量排程,通過 Istio 內的 Destination Rule 單獨定義服務負載均衡策略,根據來源服務、URL 進行重定向實現目標路由分流等,通過 MenQuota、RedisQuota 進行限流等。

4.遙測:通過 Prometheus 獲取遙測資料,實現灰度專案成功率、東西南北流量區分、服務峰值流量、服務動態拓撲的監控。

總結

目前我們已將旗下「雲客贊」社交電商 App 全部遷移至 UK8S,開發語言包括Java、PHP-FPM、NodeJS 等等。結合CI/CD,能快速實現服務迭代以及新專案上線,大大提升了開發以及運維的工作效率;通過完善的日誌、監控、鏈路跟蹤及告警系統,能夠快速的定位故障,並且根據遙測資料提前預判峰值,通過HPA實現服務自動伸縮,科學的分配資源,大大降低了計算資源成本;通過Istio服務治理,很好的實現了流量的管理,並且基於此輕鬆的實現了灰度釋出。

接下來,我們將更加豐富CI/CD流水線,加入單元測試、程式碼掃描、效能測試等提升測試效率;引入chatops豐富運維手段;藉助Istio實現多雲管理進一步保障業務的穩定性。