接收程序員的技術早餐
作為一名軟件工程師或者系統(tǒng)架構師,當我們在構造大型應用系統(tǒng)時,常常需要畫出一個體系架構圖,來表現要開發(fā)的應用系統(tǒng)的軟件架構。
我想很多軟件開發(fā)人員都有這樣的疑問:這幾年業(yè)界都在談微服務,容器化,這樣的技術變化的原因是什么?新的或者原有的軟件系統(tǒng)到底該用什么樣的技術架構體系?如果需要改造,應該怎么做?
希望通過閱讀本文給您一些啟發(fā)。
應用服務器是近十幾年來應用開發(fā)的主流部署環(huán)境。以 Java 語言社區(qū)為例,Java EE 應用服務器是軟件中間件開發(fā)領域的主要產品,包括以 Weblogic, Websphere 商業(yè)產品, JBoss AS(Wildfly), Glassfish 開源產品,還有 Tomcat, Jetty 等 Servlet 容器服務器,Spring Framework 應用框架等,這些共同組成商業(yè)業(yè)務軟件最重要的部分。
容器 Docker,容器編排 Kubernetes 等帶來了容器化微服務軟件技術浪潮,互聯網公司作為先行者,并在國內外引領軟件設計的方法變革,Cloud Native 已經成為當前軟件設計中必須考慮的要素。
那么,“傳統(tǒng)”的應用服務器和 Kubernetes 之間是否有技術關聯性?如果有,它們的內在聯系是什么?
我在專業(yè)技術網站找到了兩幅圖片,分別是完整的 JavaEE 實現 Wildfly 應用服務器域模式和 kubernetes 架構體系圖。
圖片出處:
https://kb.novaordis.com/index.php/Wildfly_Domain_Mode_Concepts
圖片出處:
https://x-team.com/blog/introduction-kubernetes-architecture/
以上兩幅圖,并不能表現這兩個產品所有技術架構細節(jié),但已經能夠充分表現它們的架構特點和組件之間的關系。
我們發(fā)現,兩者的架構有很多一致的地方:
都有一個主控節(jié)點。Kubernetes 稱為 Master Node,Wildfly 中含有 domain controller 的 host1,也是作為主控節(jié)點。
通過主控節(jié)點管理多個工作節(jié)點。Kubernetes 有兩個 Worker Node,Wildfly 圖中也有兩個工作節(jié)點 host2 和 host3。
管理員通過管理接口 (Rest API) 來對整個系統(tǒng)進行管理,Kubernetes 是通過 kubectl 訪問 API server,Wildfly 是通過 jboss-cli 工具訪問管理接口,服務器處理組件是 domain controller。當然,它們也都提供圖形管理工具。
工作節(jié)點上都有控制進程,Kubernetes 是 kubelet 和 kube-proxy,Wildfly 為 host controller 和 process controller,其中 kubelet 和 host controller 作用類似,都是起到工作節(jié)點和主控節(jié)點通信和管理節(jié)點工作進程的作用。
每個工作節(jié)點上都有多個工作進程,只不過 Kubernetes 是由容器管理 Pod,而 Wildfly 是 JVM 進程管理工作線程。
另外在圖示中沒有表示出來,在邏輯上概念相似的還有:
Kubenetes 中的 controller-manager 包括各類功能的控制器模塊。Wildlfy 中有類似的功能模塊,也在 domain controller 中,它們都具備可擴展能力。
Rest API 對外接口采用簡單易懂的 Json 格式。而各個節(jié)點間為了高效率,通信方式為二進制數據流,可以配置加密方式。
盡管在工作進程中,Pod 和線程是不同的。但它們邏輯上也有相似之處:都是獨立的工作主體;都有完整的生命周期;Pod 間共享網絡,存儲等信息,線程間可以傳遞上下文。我個人更愿意把 Pod 看作是高一個或者半個維度的,隔離性更好的“工作線程池”。
不同的節(jié)點或者進程中的服務工作單元,可以動態(tài)組成服務群組。Wildfly 中有 Server Group 概念,一個應用可以被同時部署到 Server Group 的所有工作單元;Kubernetes 的 Pod 可以通過定義的 Label 來 Selector,即可以篩選出具有某些標記的 Pod,而作為服務群組對外提供服務。
Kubernetes 有 Service 來提供服務,對于服務消費者,后面的 Pod 服務提供者的信息都是透明的,而且還有 Ingress 對外部應用進一步暴露服務能力。Wildfly 提供了 Wildfly-cluster 作為服務組件的反向代理,雖然做不到像 Service 那樣直接通過 iptables 底層機制去映射網絡訪問端口,但同樣也有強大的根據負載能力調節(jié)轉發(fā)請求量的特性,更多起到 Ingress 的作用。
Kubernetes 對有狀態(tài)的組件支持,是通過 StatefulSet,掛接 Persistent Volumes,啟動時重新構建相同狀態(tài)的工作容器。而 Wildfly 中對狀態(tài)的管理,包含 Stateful SessionBean, Servlet session 等等,都是通過 Infinispan 的分布式機制,復制狀態(tài)到多個節(jié)點。而且還有一種遠程 Infinispan 的配置方法,和 Kubernates 對狀態(tài)的管理在邏輯上完全一致了。
對于 Master 主控節(jié)點的安全性管理,兩者都有完備 RBAC 用戶管理認證授權機制,以及完備的加密方式,密鑰配置管理等功能。
Java EE 技術一直是一個完整的開發(fā)生態(tài),同樣,Kubernetes 也快速形成了更加龐大的生態(tài)體系,我們從其中一些對開發(fā)很重要的方面進行分析。
JavaEE 有一套標準的打包方式,如構建 jar,組合成應用 war,進而打包成企業(yè)完整應用 ear。Kubernetes 是利用容器鏡像,即 docker 的打包機制來管理容器。在 docker 之上,Kubernetes 提出 Pod 概念。對于整體的應用部署,目前 Kubernetes 社區(qū)提供了 helm 工具和 chart 包格式。當然也類似 yum 工具管理的 rpm 格式。
Kubernetes 動態(tài)擴容,即 ReplicaSets 定義的創(chuàng)建特定數目的實例,可以說是 Kubernetes 最重要的特性之一。JavaEE 定義的 Stateless SessionBean,在應用服務器實現中,會創(chuàng)建一個池來實例化多個,雖然實例個數控制粒度沒有那么細,但也是可以通過控制臺來定義其實例數量的,實例池由容器來保證其可用實例數目。
Kubernetes 用 ConfigMap 來定義配置信息,用 Secrets 來定義安全方面的配置信息。JavaEE 也有類似的定義,比如 Resource 和 Securtiy 方面的 annotation。在應用服務器擴展方面,Wildfly 可以自行定義 xml schema,提供友好可讀的 xml 配置信息,以及 Security Domain/Realm 來定義安全方面的配置信息。
原 Coreos(后被紅帽收購)定義的 Operator Framework(運維框架),基于 Kubernetes CRD(Custom Resource Definitions),定義了完整的一套打包,部署,管理應用的方法,有了這樣的工具,第三方軟件產品,可以用一種相對“標準”的方式提供容器化的產品。Custom Resource Definitions 是 Kubernetes 的擴展機制,可以預見 Kubernetes 三方擴展將會如雨后春筍般出現。對應的,Wildfly 有子系統(tǒng)(subsystem 擴展機制),可以在 Wildfly 服務器內核之上,開發(fā)子系統(tǒng)來擴展功能,Wildfly 所有的 Java EE 都是通過子系統(tǒng)方式實現的。它們都是通過擴展 Controller 的功能,把管理命令掛接到 API server 之上,設計思路驚人的一致!
Wildfly 工作節(jié)點的管理,可以通過暴露信息發(fā)給主控節(jié)點,也可以利用 JMX,Java agent,Interceper 等方式來發(fā)送數據到分布式數據中心上(比如可以加載 jolokia),再用獨立的或者統(tǒng)一的控制臺來管理。同樣的,Istio 項目,也是利用 sidecar 模式,在 pod 工作進程上,掛接一個 envoy 模塊,由其完成流量分配,安全管理,policy 設置等功能,再由控制臺統(tǒng)一管理。
Kubernetes 被成為容器編排產品,所謂編排 (orchestration),就是把不同的應用運行組件,按照實現定義好的規(guī)則,根據其依賴性能夠啟動運行,并保證其運行健壯的能力。Java EE 各個規(guī)范間也有依賴性,比如 Webservice 依賴于 Servlet,Wildfly 有一個組件成為 DeploymentFramework,也是處理組件之間的依賴關系的,服務器會按照應用定義好的最終狀態(tài)聲明,按照自己的依賴性原則,逐個啟動各個服務,保證應用最后可用。
畢竟 Kubernetes 是演進后技術,具有大量新的特性:
存儲方面的特性,Kubernetes 可以掛載各種存儲,包括普通的文件系統(tǒng),NFS,云端的 S3,開源存儲方案 Ceph 等應有盡有。Wildfly 還是使用標準的操作系統(tǒng)的文件和目錄。利用容器,Kubernetes 能更方便的對文件限額,資源使用量等進行定義和限制操作。
網絡方面的特性,Wildfly 定義了網絡接口配置屬性,可以對網絡 IP,端口,偏移值等進行設置。但這些和 Kubernetes 相比就是九牛一毛,Kubernetes 在 Service 層,就利用 iptables 等方法做網絡請求的路由映射,而且商業(yè) Kubernetes 產品都會加入 SDN(軟件定義網絡)的方案,網絡管理成為應用體系重要的一部分。
Kubernetes 中非常重要的組件是 scheduler 調度器,這個在 Wildfly 中沒有功能完全一致的組件,因為企業(yè)應用的集群部署是按組整體部署的。Wildfly 提供了控制臺工具來部署到不同的節(jié)點上,盡管這個過程可以自動化,甚至可以引入一些智能的成分來“調度”,但還是和 Kubernetes 提供的調度能力相差甚遠。
對工作節(jié)點的管理的規(guī)模不同。企業(yè)應用服務器集群一般在數十臺左右,和互聯網動則成千上萬的服務器差了幾個數量級。對事務的一致性要求也是不同的,它們對于狀態(tài)信息的分布式分發(fā)復制方式存在差別。
企業(yè)級應用服務器,應用上下文信息包含了事務,安全等信息,在線程間進行傳遞。而應用分布化后,微服務之間也要傳遞安全,事務等信息,就要用 OIDC/Jwt,TCC/Saga 等分布式方案。業(yè)務目標是一致的,但實現方法有很大差異,也對軟件架構設計提出了非常高的要求。
毫無疑問 Kubernetes 已經贏得了容器之戰(zhàn),甚至取代 docker 成為容器技術中最重要的開源產品。開發(fā)工程師和架構師也需要適應微服務化技術的變化,部署應用到云端上,這個趨勢已經開始了。同時,Kubernetes 和其生態(tài),對于應用開發(fā)和運維也提出更高的要求。企業(yè)在開發(fā)軟件應用時,也要多方位考慮,包括應用復雜度,訪問量,事務的要求,運維能力等。再選擇技術方案和中間件產品 / 云計算平臺。軟件設計從來都沒有銀彈,最適合的才是最好的。
點擊下方圖片即可閱讀
中年程序員都在想什么?