'從技術雷達看​DevOps的十年——容器技術和微服務'

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目

容器安全掃描,Docker,用 TDD 開發容器,Rancher,Kubernetes,Mesosphere DC/OS,Apache Mesos,Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook


從演進式架構到微服務

可以說,微服務是 DevOps 所有實踐發展的一個必然結果。它不光是一種應用架構,而是包含了多年來敏捷、DevOps、雲計算、容器等技術實踐的綜合應用。

在以 ESB 為基礎的大規模企業級應用出現之前,企業級應用軟件的開發規模相對較小,大部分都是基於現有軟件包產品的二次定製。採用敏捷的方式來交付這些應用是可控的。然而隨著 ESB 將企業級應用的信息孤島集成起來。敏捷軟件開發似乎就顯得力不從心了。

演進式架構在 2010 年第一期技術雷達就被提出來。在敏捷軟件開發實踐開始應用於大規模應用程序的案例中。”架構”和“變化”出現了矛盾。如何讓包含了“不輕易改變的決定”的架構和“擁抱變化”的敏捷共處,於是有了演進式架構:

我們幫助我們的許多客戶調整企業軟件體系結構實踐, 以適應敏捷軟件交付方法。在過去的一年裡, 我們看到人們對進化企業架構以及面向服務的架構如何塑造企業單位之間的界限越來越感興趣。企業架構的進化方法的價值在於創建重量更輕的系統, 從而簡化不同部件之間的集成。通過採用這種方法和將 web 作為企業應用程序平臺(Web as Enterprise Platform)的概念, 我們降低了應用程序體系結構的總體複雜性, 提高了質量和可擴展性, 並降低了開發成本。

2010 年 8 月演進式架構進入了”試驗”區域,但在2011年1月的技術雷達上更新了對它的評價:

敏捷軟件開發的一個原則是”最後責任時刻”的概念。這一概念適用於架構設計, 它在傳統架構師中引起了爭議。我們相信, 只要有適當闡述的原則和適當的測試套件, 架構就可以不斷髮展, 以滿足系統不斷變化的需求, 從而在不影響完整性的情況下, 在最後一個負責任的時刻做出體系結構決策系統的。我們將這種方法稱為進化體系結構, 因為我們允許體系結構隨著時間的推移而演變, 始終尊重體系結構的指導原則。

半年後,2011年6月,演進式架構進入了”採用”區域,技術雷達再次更新了評價:

與傳統的前期、重量級企業架構設計不同, 我們建議採用演進式架構。它提供了企業架構的好處, 而沒有嘗試準確預測未來所造成的問題。演進式架構不應該猜測組件將如何重用, 而是支持適應性, 使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來獲取系統中發生的重用。應儘早確定系統的驅動技術要求, 以確保在後續設計和實現中正確處理這些要求。我們主張將決定推遲到”最後責任時刻”, 這實際上可能是一些決定的先行。

在這些概念不斷變化的過程中,不斷有方法論、實踐和工具被提出。在演進式架構的思想影響下,誕生了新的實踐 —— 微服務。微服務的出現,讓演進式架構有了第一個實例化的例子。

微服務 1.0:輕量級 SOA

在技術雷達裡,微服務是以”Micro-services”而非”Microservices”出現的。在技術雷達的角度中,微服務仍然是 SOA 的一種輕量化的實現方式。在 2012 年 3月的技術雷達中,微服務首先出現在了技術雷達的“評估”區域:

微服務通常是脫離應用容器部署或使用嵌入式 HTTP 服務器部署, 它是對傳統的大型技術服務的一種遷移。這種方法通過增加運維複雜性而提升系統的可維護性。這些缺點通常使用基礎設施自動化和持續部署技術來解決。總的來說, 微服務是管理技術債務和處理不同伸縮特徵的有效方法, 尤其是在圍繞業務能力構建的面向服務的體系結構中部署時。

這裡需要劃幾個重點:

  1. 微服務脫離應用容器部署或者使用嵌入式 HTTP 服務器。這一年,Docker 還沒有出現。這裡的容器指的是 WebSphere,WebLogic 這樣的容器。嵌入式 HTTP 服務器指的是 Jetty、Tomcat 或者 DropWizard 這樣的輕量級選擇。這樣代碼庫可以自部署,而不是通過應用容器部署。
  2. 微服務是一種內部複雜度向外部的轉化:通過把應用隔離到不同的進程中,可以縮小變更的影響範圍。通過將內部複雜性轉化成外部複雜性從而使應用更易維護。而外部複雜性就交給自動化的基礎設施管理。
  3. 微服務提升了維護的複雜性和難度。如果沒有 DevOps 組織,服務之間的 應用的風險就由開發轉嫁給了維護。不過,作為Ops 可以通過自動化和持續部署/藍綠髮布來解決。
  4. 微服務便於管理技術債務,可以做到部分的按需伸縮。
  5. 微服務是圍繞業務能力的 SOA 架構。

總的來說,微服務在那個時期就是採用輕量級技術來圍繞業務實施 SOA。然而,這樣的實踐慢慢的形成了一種成熟的模式,並慢慢推廣開來。在2012年10月的技術雷達,微服務就進入了”試驗”區域,而到了 2014 年 1 月。技術雷達更新了對微服務的描述:

我們看到, 無論是在 ThoughtWorks 還是在更廣泛的社區, 微服務作為分佈式系統設計技術的採用都在上升。DropWizard 程序等框架和聲明性初始化等實踐表明技術和工具的成熟。避免採用通常的單體應用辦法,微服務更傾向於在必要的情況下替換而非修改局部應用系統。這對應用系統的總體成本具有重要的積極影響。我們認為, 這會在中長期有著巨大的影響, 特別是大部分應用的重寫週期都在 2 – 5 年。

隨著 DropWizard 開始在 Java 用戶群展露頭角,各個其它語言社區也出現了自己的輕量級 API 框架。Ruby 社區率先出現 了 Sinatra 框架,它的輕量級語法深刻的影響了未來各語言的微服務框架。例如而 .Net 社區中出現了Nancy。Python 社區出現了 Flask 。

微服務 2.0:結合基礎設施的全面架構設計

單一的輕量級服務端框架並不能端到端的解決服務消費者和服務提供者的所有問題。隨著應用慢慢的開始被拆分成了微服務,基礎設施的管理變成了一個新的問題。在分佈式系統環境下,基礎設施的範圍要比虛擬機時代廣泛的多。複雜的基礎設施和即代碼的集中式管理成為了另一個“單體”應用。於是有了前文介紹的去中心化的 Chef 和 Puppet 實踐。讓基礎設施代碼作為應用代碼庫的一個部分,這樣,就可以構建出一個“自部署”的應用。

這樣的想法推動了 Ansible 和 Vagrant 的流行,並伴隨著持續交付的實踐。我們可以通過構建可執行的虛擬機鏡像將應用切分成不同的虛擬機來運行。在那個時期,一個大型應用能夠被拆分到多個虛擬機中自動化管理已經很先進了。

然而,Docker 的出現,將這一系列最佳實踐固化成了一個完成的應用程序生命週期:開發人員通過構建 Docker 鏡像在本地開發,然後通過持續交付流水線構建成版本化鏡像。容器平臺按需拉取鏡像並直接運行,從開發環境到生產環境幾乎沒有差別。運維平臺只要能夠通過虛擬化資源使容器能夠輕易的運行,就打通了端到端的最短距離。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目

容器安全掃描,Docker,用 TDD 開發容器,Rancher,Kubernetes,Mesosphere DC/OS,Apache Mesos,Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook


從演進式架構到微服務

可以說,微服務是 DevOps 所有實踐發展的一個必然結果。它不光是一種應用架構,而是包含了多年來敏捷、DevOps、雲計算、容器等技術實踐的綜合應用。

在以 ESB 為基礎的大規模企業級應用出現之前,企業級應用軟件的開發規模相對較小,大部分都是基於現有軟件包產品的二次定製。採用敏捷的方式來交付這些應用是可控的。然而隨著 ESB 將企業級應用的信息孤島集成起來。敏捷軟件開發似乎就顯得力不從心了。

演進式架構在 2010 年第一期技術雷達就被提出來。在敏捷軟件開發實踐開始應用於大規模應用程序的案例中。”架構”和“變化”出現了矛盾。如何讓包含了“不輕易改變的決定”的架構和“擁抱變化”的敏捷共處,於是有了演進式架構:

我們幫助我們的許多客戶調整企業軟件體系結構實踐, 以適應敏捷軟件交付方法。在過去的一年裡, 我們看到人們對進化企業架構以及面向服務的架構如何塑造企業單位之間的界限越來越感興趣。企業架構的進化方法的價值在於創建重量更輕的系統, 從而簡化不同部件之間的集成。通過採用這種方法和將 web 作為企業應用程序平臺(Web as Enterprise Platform)的概念, 我們降低了應用程序體系結構的總體複雜性, 提高了質量和可擴展性, 並降低了開發成本。

2010 年 8 月演進式架構進入了”試驗”區域,但在2011年1月的技術雷達上更新了對它的評價:

敏捷軟件開發的一個原則是”最後責任時刻”的概念。這一概念適用於架構設計, 它在傳統架構師中引起了爭議。我們相信, 只要有適當闡述的原則和適當的測試套件, 架構就可以不斷髮展, 以滿足系統不斷變化的需求, 從而在不影響完整性的情況下, 在最後一個負責任的時刻做出體系結構決策系統的。我們將這種方法稱為進化體系結構, 因為我們允許體系結構隨著時間的推移而演變, 始終尊重體系結構的指導原則。

半年後,2011年6月,演進式架構進入了”採用”區域,技術雷達再次更新了評價:

與傳統的前期、重量級企業架構設計不同, 我們建議採用演進式架構。它提供了企業架構的好處, 而沒有嘗試準確預測未來所造成的問題。演進式架構不應該猜測組件將如何重用, 而是支持適應性, 使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來獲取系統中發生的重用。應儘早確定系統的驅動技術要求, 以確保在後續設計和實現中正確處理這些要求。我們主張將決定推遲到”最後責任時刻”, 這實際上可能是一些決定的先行。

在這些概念不斷變化的過程中,不斷有方法論、實踐和工具被提出。在演進式架構的思想影響下,誕生了新的實踐 —— 微服務。微服務的出現,讓演進式架構有了第一個實例化的例子。

微服務 1.0:輕量級 SOA

在技術雷達裡,微服務是以”Micro-services”而非”Microservices”出現的。在技術雷達的角度中,微服務仍然是 SOA 的一種輕量化的實現方式。在 2012 年 3月的技術雷達中,微服務首先出現在了技術雷達的“評估”區域:

微服務通常是脫離應用容器部署或使用嵌入式 HTTP 服務器部署, 它是對傳統的大型技術服務的一種遷移。這種方法通過增加運維複雜性而提升系統的可維護性。這些缺點通常使用基礎設施自動化和持續部署技術來解決。總的來說, 微服務是管理技術債務和處理不同伸縮特徵的有效方法, 尤其是在圍繞業務能力構建的面向服務的體系結構中部署時。

這裡需要劃幾個重點:

  1. 微服務脫離應用容器部署或者使用嵌入式 HTTP 服務器。這一年,Docker 還沒有出現。這裡的容器指的是 WebSphere,WebLogic 這樣的容器。嵌入式 HTTP 服務器指的是 Jetty、Tomcat 或者 DropWizard 這樣的輕量級選擇。這樣代碼庫可以自部署,而不是通過應用容器部署。
  2. 微服務是一種內部複雜度向外部的轉化:通過把應用隔離到不同的進程中,可以縮小變更的影響範圍。通過將內部複雜性轉化成外部複雜性從而使應用更易維護。而外部複雜性就交給自動化的基礎設施管理。
  3. 微服務提升了維護的複雜性和難度。如果沒有 DevOps 組織,服務之間的 應用的風險就由開發轉嫁給了維護。不過,作為Ops 可以通過自動化和持續部署/藍綠髮布來解決。
  4. 微服務便於管理技術債務,可以做到部分的按需伸縮。
  5. 微服務是圍繞業務能力的 SOA 架構。

總的來說,微服務在那個時期就是採用輕量級技術來圍繞業務實施 SOA。然而,這樣的實踐慢慢的形成了一種成熟的模式,並慢慢推廣開來。在2012年10月的技術雷達,微服務就進入了”試驗”區域,而到了 2014 年 1 月。技術雷達更新了對微服務的描述:

我們看到, 無論是在 ThoughtWorks 還是在更廣泛的社區, 微服務作為分佈式系統設計技術的採用都在上升。DropWizard 程序等框架和聲明性初始化等實踐表明技術和工具的成熟。避免採用通常的單體應用辦法,微服務更傾向於在必要的情況下替換而非修改局部應用系統。這對應用系統的總體成本具有重要的積極影響。我們認為, 這會在中長期有著巨大的影響, 特別是大部分應用的重寫週期都在 2 – 5 年。

隨著 DropWizard 開始在 Java 用戶群展露頭角,各個其它語言社區也出現了自己的輕量級 API 框架。Ruby 社區率先出現 了 Sinatra 框架,它的輕量級語法深刻的影響了未來各語言的微服務框架。例如而 .Net 社區中出現了Nancy。Python 社區出現了 Flask 。

微服務 2.0:結合基礎設施的全面架構設計

單一的輕量級服務端框架並不能端到端的解決服務消費者和服務提供者的所有問題。隨著應用慢慢的開始被拆分成了微服務,基礎設施的管理變成了一個新的問題。在分佈式系統環境下,基礎設施的範圍要比虛擬機時代廣泛的多。複雜的基礎設施和即代碼的集中式管理成為了另一個“單體”應用。於是有了前文介紹的去中心化的 Chef 和 Puppet 實踐。讓基礎設施代碼作為應用代碼庫的一個部分,這樣,就可以構建出一個“自部署”的應用。

這樣的想法推動了 Ansible 和 Vagrant 的流行,並伴隨著持續交付的實踐。我們可以通過構建可執行的虛擬機鏡像將應用切分成不同的虛擬機來運行。在那個時期,一個大型應用能夠被拆分到多個虛擬機中自動化管理已經很先進了。

然而,Docker 的出現,將這一系列最佳實踐固化成了一個完成的應用程序生命週期:開發人員通過構建 Docker 鏡像在本地開發,然後通過持續交付流水線構建成版本化鏡像。容器平臺按需拉取鏡像並直接運行,從開發環境到生產環境幾乎沒有差別。運維平臺只要能夠通過虛擬化資源使容器能夠輕易的運行,就打通了端到端的最短距離。

從技術雷達看​DevOps的十年——容器技術和微服務

正如上文所述“容器內”和“容器外”被清晰的隔離開,無論從組織上還是架構上,都適應了這套模型。此外,基礎設施的關注點分離變成了兩個部分:應用程序的運行時管理和應用間的通信。

剛開始的時候,Docker 看起來更像是一個“輕量級的虛擬機”——我們通過鏡像構建出一個運行實體。但隨著應用程序的責任分離,Docker 就更像是一個“重量級的進程”。我們如果把容器按責任分離,就可以把容器看做是一個個通過 API 暴露的資源。這樣,我們就可以採用雲計算的資源編排的方式來處理應用之間的問題。恰逢 Docker 的容器間網絡和編排工具的成熟,使我們有了更多的容器編排方案可以選擇。

剛開始的時候,微服務之間還是簡單的 HTTP 調用。我們可以通過 Nginx 作為 API 網關。隨著服務變得複雜,對於 API 網關的要求就越來越多,於是就有了單一的 API 網關方案,簡化了 API 管理。

如何讓網關知道每個服務的情況呢?一方面,API 網關需要知道服務的存活情況。另一方面,服務自身要能夠主動彙報自身的狀態,於是 Consul 這樣的服務註冊發現解決方案就逐漸流行起來。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目

容器安全掃描,Docker,用 TDD 開發容器,Rancher,Kubernetes,Mesosphere DC/OS,Apache Mesos,Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook


從演進式架構到微服務

可以說,微服務是 DevOps 所有實踐發展的一個必然結果。它不光是一種應用架構,而是包含了多年來敏捷、DevOps、雲計算、容器等技術實踐的綜合應用。

在以 ESB 為基礎的大規模企業級應用出現之前,企業級應用軟件的開發規模相對較小,大部分都是基於現有軟件包產品的二次定製。採用敏捷的方式來交付這些應用是可控的。然而隨著 ESB 將企業級應用的信息孤島集成起來。敏捷軟件開發似乎就顯得力不從心了。

演進式架構在 2010 年第一期技術雷達就被提出來。在敏捷軟件開發實踐開始應用於大規模應用程序的案例中。”架構”和“變化”出現了矛盾。如何讓包含了“不輕易改變的決定”的架構和“擁抱變化”的敏捷共處,於是有了演進式架構:

我們幫助我們的許多客戶調整企業軟件體系結構實踐, 以適應敏捷軟件交付方法。在過去的一年裡, 我們看到人們對進化企業架構以及面向服務的架構如何塑造企業單位之間的界限越來越感興趣。企業架構的進化方法的價值在於創建重量更輕的系統, 從而簡化不同部件之間的集成。通過採用這種方法和將 web 作為企業應用程序平臺(Web as Enterprise Platform)的概念, 我們降低了應用程序體系結構的總體複雜性, 提高了質量和可擴展性, 並降低了開發成本。

2010 年 8 月演進式架構進入了”試驗”區域,但在2011年1月的技術雷達上更新了對它的評價:

敏捷軟件開發的一個原則是”最後責任時刻”的概念。這一概念適用於架構設計, 它在傳統架構師中引起了爭議。我們相信, 只要有適當闡述的原則和適當的測試套件, 架構就可以不斷髮展, 以滿足系統不斷變化的需求, 從而在不影響完整性的情況下, 在最後一個負責任的時刻做出體系結構決策系統的。我們將這種方法稱為進化體系結構, 因為我們允許體系結構隨著時間的推移而演變, 始終尊重體系結構的指導原則。

半年後,2011年6月,演進式架構進入了”採用”區域,技術雷達再次更新了評價:

與傳統的前期、重量級企業架構設計不同, 我們建議採用演進式架構。它提供了企業架構的好處, 而沒有嘗試準確預測未來所造成的問題。演進式架構不應該猜測組件將如何重用, 而是支持適應性, 使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來獲取系統中發生的重用。應儘早確定系統的驅動技術要求, 以確保在後續設計和實現中正確處理這些要求。我們主張將決定推遲到”最後責任時刻”, 這實際上可能是一些決定的先行。

在這些概念不斷變化的過程中,不斷有方法論、實踐和工具被提出。在演進式架構的思想影響下,誕生了新的實踐 —— 微服務。微服務的出現,讓演進式架構有了第一個實例化的例子。

微服務 1.0:輕量級 SOA

在技術雷達裡,微服務是以”Micro-services”而非”Microservices”出現的。在技術雷達的角度中,微服務仍然是 SOA 的一種輕量化的實現方式。在 2012 年 3月的技術雷達中,微服務首先出現在了技術雷達的“評估”區域:

微服務通常是脫離應用容器部署或使用嵌入式 HTTP 服務器部署, 它是對傳統的大型技術服務的一種遷移。這種方法通過增加運維複雜性而提升系統的可維護性。這些缺點通常使用基礎設施自動化和持續部署技術來解決。總的來說, 微服務是管理技術債務和處理不同伸縮特徵的有效方法, 尤其是在圍繞業務能力構建的面向服務的體系結構中部署時。

這裡需要劃幾個重點:

  1. 微服務脫離應用容器部署或者使用嵌入式 HTTP 服務器。這一年,Docker 還沒有出現。這裡的容器指的是 WebSphere,WebLogic 這樣的容器。嵌入式 HTTP 服務器指的是 Jetty、Tomcat 或者 DropWizard 這樣的輕量級選擇。這樣代碼庫可以自部署,而不是通過應用容器部署。
  2. 微服務是一種內部複雜度向外部的轉化:通過把應用隔離到不同的進程中,可以縮小變更的影響範圍。通過將內部複雜性轉化成外部複雜性從而使應用更易維護。而外部複雜性就交給自動化的基礎設施管理。
  3. 微服務提升了維護的複雜性和難度。如果沒有 DevOps 組織,服務之間的 應用的風險就由開發轉嫁給了維護。不過,作為Ops 可以通過自動化和持續部署/藍綠髮布來解決。
  4. 微服務便於管理技術債務,可以做到部分的按需伸縮。
  5. 微服務是圍繞業務能力的 SOA 架構。

總的來說,微服務在那個時期就是採用輕量級技術來圍繞業務實施 SOA。然而,這樣的實踐慢慢的形成了一種成熟的模式,並慢慢推廣開來。在2012年10月的技術雷達,微服務就進入了”試驗”區域,而到了 2014 年 1 月。技術雷達更新了對微服務的描述:

我們看到, 無論是在 ThoughtWorks 還是在更廣泛的社區, 微服務作為分佈式系統設計技術的採用都在上升。DropWizard 程序等框架和聲明性初始化等實踐表明技術和工具的成熟。避免採用通常的單體應用辦法,微服務更傾向於在必要的情況下替換而非修改局部應用系統。這對應用系統的總體成本具有重要的積極影響。我們認為, 這會在中長期有著巨大的影響, 特別是大部分應用的重寫週期都在 2 – 5 年。

隨著 DropWizard 開始在 Java 用戶群展露頭角,各個其它語言社區也出現了自己的輕量級 API 框架。Ruby 社區率先出現 了 Sinatra 框架,它的輕量級語法深刻的影響了未來各語言的微服務框架。例如而 .Net 社區中出現了Nancy。Python 社區出現了 Flask 。

微服務 2.0:結合基礎設施的全面架構設計

單一的輕量級服務端框架並不能端到端的解決服務消費者和服務提供者的所有問題。隨著應用慢慢的開始被拆分成了微服務,基礎設施的管理變成了一個新的問題。在分佈式系統環境下,基礎設施的範圍要比虛擬機時代廣泛的多。複雜的基礎設施和即代碼的集中式管理成為了另一個“單體”應用。於是有了前文介紹的去中心化的 Chef 和 Puppet 實踐。讓基礎設施代碼作為應用代碼庫的一個部分,這樣,就可以構建出一個“自部署”的應用。

這樣的想法推動了 Ansible 和 Vagrant 的流行,並伴隨著持續交付的實踐。我們可以通過構建可執行的虛擬機鏡像將應用切分成不同的虛擬機來運行。在那個時期,一個大型應用能夠被拆分到多個虛擬機中自動化管理已經很先進了。

然而,Docker 的出現,將這一系列最佳實踐固化成了一個完成的應用程序生命週期:開發人員通過構建 Docker 鏡像在本地開發,然後通過持續交付流水線構建成版本化鏡像。容器平臺按需拉取鏡像並直接運行,從開發環境到生產環境幾乎沒有差別。運維平臺只要能夠通過虛擬化資源使容器能夠輕易的運行,就打通了端到端的最短距離。

從技術雷達看​DevOps的十年——容器技術和微服務

正如上文所述“容器內”和“容器外”被清晰的隔離開,無論從組織上還是架構上,都適應了這套模型。此外,基礎設施的關注點分離變成了兩個部分:應用程序的運行時管理和應用間的通信。

剛開始的時候,Docker 看起來更像是一個“輕量級的虛擬機”——我們通過鏡像構建出一個運行實體。但隨著應用程序的責任分離,Docker 就更像是一個“重量級的進程”。我們如果把容器按責任分離,就可以把容器看做是一個個通過 API 暴露的資源。這樣,我們就可以採用雲計算的資源編排的方式來處理應用之間的問題。恰逢 Docker 的容器間網絡和編排工具的成熟,使我們有了更多的容器編排方案可以選擇。

剛開始的時候,微服務之間還是簡單的 HTTP 調用。我們可以通過 Nginx 作為 API 網關。隨著服務變得複雜,對於 API 網關的要求就越來越多,於是就有了單一的 API 網關方案,簡化了 API 管理。

如何讓網關知道每個服務的情況呢?一方面,API 網關需要知道服務的存活情況。另一方面,服務自身要能夠主動彙報自身的狀態,於是 Consul 這樣的服務註冊發現解決方案就逐漸流行起來。

從技術雷達看​DevOps的十年——容器技術和微服務

同時,日誌收集和監控要集成到每個服務中去,從管理的角度也要能聚合所有的日誌和監控,於是有了OpenTracing 這樣的解決方案。

隨著微服務架構體系越來越複雜,這些零散的工具和應用開發框架的集成變成了新的問題。這樣的問題最早出現在 Java 社區 —— 因為大部分大型應用仍然是基於 Java EE 的。於是 Spring 推出了Spring Cloud —— 坊間稱之為 Spring 微服務全家桶,它包含了所有微服務端到端的組件。雖然Spring Boot 出現的比較晚,但憑藉著 Spring 在 Java 社區的號召力使其迅速超過 DropWizard,Jersey 等方案脫穎而出。成為了目前 Java 社區的 微服務構建首選。

然而,部署實例裡仍然存在著安全、監控、日誌收集這樣的基礎設施功能,就出現了”野心過大的 API 網關“。這個問題出現在了 2015 年11 月份的技術雷達上:

我們常見的抱怨之一是將業務智能推入中間件, 從而產生了具有運行關鍵應用程序邏輯雄心的應用程序服務器和企業服務總線。這些都需要在不適合這一目的的環境中進行復雜的編程。我們看到這種疾病的重新出現令人擔憂, 因為 API 網關產品常常野心過大。API 網關可以在處理一些一般問題 (例如, 身份驗證和速率限制) 時提供實用程序, 但任何域智能 (如數據轉換或規則處理) 都應駐留在應用程序或服務中, 這些應用程序或服務可以由與他們支持的領域密切合作的產品團隊。

不光 API 會出現這樣的問題。替代傳統消息隊列的 Kafka 也會面臨同樣的問題,雖然用了新技術,但貌似又回到了集中化的老路上去。這些都違背了微服務的”自治性原則”。

於是,就有人想,能不能通過容器技術,將代碼無關的一類安全、反向代理、日誌等拆散到各個服務實體上去。在單個服務的內部實現關注點分離——業務代碼和非業務組件隔離。比如,採用邊車模式處理端點的安全。這樣的方式十分有效的化解了集中服務組件的負載和依賴。於是這個模式就複製擴大,變成了服務網格(Service Mesh)。服務網格出現在 2017 年底的技術雷達上:

隨著大型組織過渡到擁有和運營自己微服務的自主團隊, 它們如何在不依賴集中式託管基礎結構的情況下確保這些服務之間必要的一致性和兼容性?為了高效地協同工作, 即使是自主的微服務也需要與某些組織標準保持一致。服務網格提供一致的發現、安全性、跟蹤、監視和故障處理, 而不需要共享資產 (如 API 網關或 ESB)。典型的實現涉及在每個服務進程旁邊部署的輕量級反向代理進程, 可能是在一個單獨的容器中。這些代理與服務註冊表、標識提供程序、日誌聚合器等進行通信。服務互操作性和可觀測性是通過此代理的共享實現獲得的, 而不是通過共享運行時實例獲得的。一段時間以來, 我們一直主張採用分散的微服務管理方法, 並很高興看到這種一致的模式出現。諸如 linkerd 和 Istio 這樣的開源項目將繼續成熟, 使服務網格更易於實現。

時下服務網格成為了微服務架構的熱門,但這種模式很明顯增大了網絡上的開銷,但分攤了服務治理的壓力。相對於微服務複雜性而言,這些開銷在某種程度上是可以接受的。

微服務 3.0:無服務器的微服務架構

從微服務技術的發展歷程來看,微服務技術的發展是不斷的把業務代碼和微服務運行時逐漸剝離的一個過程:讓儘可能多的不經常變更的部分沉澱到基礎設施裡,並通過基礎設施即代碼管理起來。

從 DevOps 的角度來看,應用程序在分離業務代碼和基礎設施的過程中清晰界定了開發和運維之間的職責。開發團隊要負責應用程序的業務代碼能夠跟隨業務的變化而演進。而運維團隊就要為開發團隊提供儘可能透明和可靠的基礎設施支持。

一言以蔽之:開發工程師除了寫業務代碼,什麼都不需要管。

早在 服務網格之前,後端應用即服務(Backend as service)就已經進入2014年的技術雷達。彼時還是移動端應用爆發的時候。開發人員可以通過這種方式專注於客戶端的開發。而到 AWS 推出了 AWS Lambda 和 Amazon APIGateway 後,函數即服務(Function as a service)的理念則標誌了無服務器應用架構(Serverless Architecture)的到來。

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目

容器安全掃描,Docker,用 TDD 開發容器,Rancher,Kubernetes,Mesosphere DC/OS,Apache Mesos,Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook


從演進式架構到微服務

可以說,微服務是 DevOps 所有實踐發展的一個必然結果。它不光是一種應用架構,而是包含了多年來敏捷、DevOps、雲計算、容器等技術實踐的綜合應用。

在以 ESB 為基礎的大規模企業級應用出現之前,企業級應用軟件的開發規模相對較小,大部分都是基於現有軟件包產品的二次定製。採用敏捷的方式來交付這些應用是可控的。然而隨著 ESB 將企業級應用的信息孤島集成起來。敏捷軟件開發似乎就顯得力不從心了。

演進式架構在 2010 年第一期技術雷達就被提出來。在敏捷軟件開發實踐開始應用於大規模應用程序的案例中。”架構”和“變化”出現了矛盾。如何讓包含了“不輕易改變的決定”的架構和“擁抱變化”的敏捷共處,於是有了演進式架構:

我們幫助我們的許多客戶調整企業軟件體系結構實踐, 以適應敏捷軟件交付方法。在過去的一年裡, 我們看到人們對進化企業架構以及面向服務的架構如何塑造企業單位之間的界限越來越感興趣。企業架構的進化方法的價值在於創建重量更輕的系統, 從而簡化不同部件之間的集成。通過採用這種方法和將 web 作為企業應用程序平臺(Web as Enterprise Platform)的概念, 我們降低了應用程序體系結構的總體複雜性, 提高了質量和可擴展性, 並降低了開發成本。

2010 年 8 月演進式架構進入了”試驗”區域,但在2011年1月的技術雷達上更新了對它的評價:

敏捷軟件開發的一個原則是”最後責任時刻”的概念。這一概念適用於架構設計, 它在傳統架構師中引起了爭議。我們相信, 只要有適當闡述的原則和適當的測試套件, 架構就可以不斷髮展, 以滿足系統不斷變化的需求, 從而在不影響完整性的情況下, 在最後一個負責任的時刻做出體系結構決策系統的。我們將這種方法稱為進化體系結構, 因為我們允許體系結構隨著時間的推移而演變, 始終尊重體系結構的指導原則。

半年後,2011年6月,演進式架構進入了”採用”區域,技術雷達再次更新了評價:

與傳統的前期、重量級企業架構設計不同, 我們建議採用演進式架構。它提供了企業架構的好處, 而沒有嘗試準確預測未來所造成的問題。演進式架構不應該猜測組件將如何重用, 而是支持適應性, 使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來獲取系統中發生的重用。應儘早確定系統的驅動技術要求, 以確保在後續設計和實現中正確處理這些要求。我們主張將決定推遲到”最後責任時刻”, 這實際上可能是一些決定的先行。

在這些概念不斷變化的過程中,不斷有方法論、實踐和工具被提出。在演進式架構的思想影響下,誕生了新的實踐 —— 微服務。微服務的出現,讓演進式架構有了第一個實例化的例子。

微服務 1.0:輕量級 SOA

在技術雷達裡,微服務是以”Micro-services”而非”Microservices”出現的。在技術雷達的角度中,微服務仍然是 SOA 的一種輕量化的實現方式。在 2012 年 3月的技術雷達中,微服務首先出現在了技術雷達的“評估”區域:

微服務通常是脫離應用容器部署或使用嵌入式 HTTP 服務器部署, 它是對傳統的大型技術服務的一種遷移。這種方法通過增加運維複雜性而提升系統的可維護性。這些缺點通常使用基礎設施自動化和持續部署技術來解決。總的來說, 微服務是管理技術債務和處理不同伸縮特徵的有效方法, 尤其是在圍繞業務能力構建的面向服務的體系結構中部署時。

這裡需要劃幾個重點:

  1. 微服務脫離應用容器部署或者使用嵌入式 HTTP 服務器。這一年,Docker 還沒有出現。這裡的容器指的是 WebSphere,WebLogic 這樣的容器。嵌入式 HTTP 服務器指的是 Jetty、Tomcat 或者 DropWizard 這樣的輕量級選擇。這樣代碼庫可以自部署,而不是通過應用容器部署。
  2. 微服務是一種內部複雜度向外部的轉化:通過把應用隔離到不同的進程中,可以縮小變更的影響範圍。通過將內部複雜性轉化成外部複雜性從而使應用更易維護。而外部複雜性就交給自動化的基礎設施管理。
  3. 微服務提升了維護的複雜性和難度。如果沒有 DevOps 組織,服務之間的 應用的風險就由開發轉嫁給了維護。不過,作為Ops 可以通過自動化和持續部署/藍綠髮布來解決。
  4. 微服務便於管理技術債務,可以做到部分的按需伸縮。
  5. 微服務是圍繞業務能力的 SOA 架構。

總的來說,微服務在那個時期就是採用輕量級技術來圍繞業務實施 SOA。然而,這樣的實踐慢慢的形成了一種成熟的模式,並慢慢推廣開來。在2012年10月的技術雷達,微服務就進入了”試驗”區域,而到了 2014 年 1 月。技術雷達更新了對微服務的描述:

我們看到, 無論是在 ThoughtWorks 還是在更廣泛的社區, 微服務作為分佈式系統設計技術的採用都在上升。DropWizard 程序等框架和聲明性初始化等實踐表明技術和工具的成熟。避免採用通常的單體應用辦法,微服務更傾向於在必要的情況下替換而非修改局部應用系統。這對應用系統的總體成本具有重要的積極影響。我們認為, 這會在中長期有著巨大的影響, 特別是大部分應用的重寫週期都在 2 – 5 年。

隨著 DropWizard 開始在 Java 用戶群展露頭角,各個其它語言社區也出現了自己的輕量級 API 框架。Ruby 社區率先出現 了 Sinatra 框架,它的輕量級語法深刻的影響了未來各語言的微服務框架。例如而 .Net 社區中出現了Nancy。Python 社區出現了 Flask 。

微服務 2.0:結合基礎設施的全面架構設計

單一的輕量級服務端框架並不能端到端的解決服務消費者和服務提供者的所有問題。隨著應用慢慢的開始被拆分成了微服務,基礎設施的管理變成了一個新的問題。在分佈式系統環境下,基礎設施的範圍要比虛擬機時代廣泛的多。複雜的基礎設施和即代碼的集中式管理成為了另一個“單體”應用。於是有了前文介紹的去中心化的 Chef 和 Puppet 實踐。讓基礎設施代碼作為應用代碼庫的一個部分,這樣,就可以構建出一個“自部署”的應用。

這樣的想法推動了 Ansible 和 Vagrant 的流行,並伴隨著持續交付的實踐。我們可以通過構建可執行的虛擬機鏡像將應用切分成不同的虛擬機來運行。在那個時期,一個大型應用能夠被拆分到多個虛擬機中自動化管理已經很先進了。

然而,Docker 的出現,將這一系列最佳實踐固化成了一個完成的應用程序生命週期:開發人員通過構建 Docker 鏡像在本地開發,然後通過持續交付流水線構建成版本化鏡像。容器平臺按需拉取鏡像並直接運行,從開發環境到生產環境幾乎沒有差別。運維平臺只要能夠通過虛擬化資源使容器能夠輕易的運行,就打通了端到端的最短距離。

從技術雷達看​DevOps的十年——容器技術和微服務

正如上文所述“容器內”和“容器外”被清晰的隔離開,無論從組織上還是架構上,都適應了這套模型。此外,基礎設施的關注點分離變成了兩個部分:應用程序的運行時管理和應用間的通信。

剛開始的時候,Docker 看起來更像是一個“輕量級的虛擬機”——我們通過鏡像構建出一個運行實體。但隨著應用程序的責任分離,Docker 就更像是一個“重量級的進程”。我們如果把容器按責任分離,就可以把容器看做是一個個通過 API 暴露的資源。這樣,我們就可以採用雲計算的資源編排的方式來處理應用之間的問題。恰逢 Docker 的容器間網絡和編排工具的成熟,使我們有了更多的容器編排方案可以選擇。

剛開始的時候,微服務之間還是簡單的 HTTP 調用。我們可以通過 Nginx 作為 API 網關。隨著服務變得複雜,對於 API 網關的要求就越來越多,於是就有了單一的 API 網關方案,簡化了 API 管理。

如何讓網關知道每個服務的情況呢?一方面,API 網關需要知道服務的存活情況。另一方面,服務自身要能夠主動彙報自身的狀態,於是 Consul 這樣的服務註冊發現解決方案就逐漸流行起來。

從技術雷達看​DevOps的十年——容器技術和微服務

同時,日誌收集和監控要集成到每個服務中去,從管理的角度也要能聚合所有的日誌和監控,於是有了OpenTracing 這樣的解決方案。

隨著微服務架構體系越來越複雜,這些零散的工具和應用開發框架的集成變成了新的問題。這樣的問題最早出現在 Java 社區 —— 因為大部分大型應用仍然是基於 Java EE 的。於是 Spring 推出了Spring Cloud —— 坊間稱之為 Spring 微服務全家桶,它包含了所有微服務端到端的組件。雖然Spring Boot 出現的比較晚,但憑藉著 Spring 在 Java 社區的號召力使其迅速超過 DropWizard,Jersey 等方案脫穎而出。成為了目前 Java 社區的 微服務構建首選。

然而,部署實例裡仍然存在著安全、監控、日誌收集這樣的基礎設施功能,就出現了”野心過大的 API 網關“。這個問題出現在了 2015 年11 月份的技術雷達上:

我們常見的抱怨之一是將業務智能推入中間件, 從而產生了具有運行關鍵應用程序邏輯雄心的應用程序服務器和企業服務總線。這些都需要在不適合這一目的的環境中進行復雜的編程。我們看到這種疾病的重新出現令人擔憂, 因為 API 網關產品常常野心過大。API 網關可以在處理一些一般問題 (例如, 身份驗證和速率限制) 時提供實用程序, 但任何域智能 (如數據轉換或規則處理) 都應駐留在應用程序或服務中, 這些應用程序或服務可以由與他們支持的領域密切合作的產品團隊。

不光 API 會出現這樣的問題。替代傳統消息隊列的 Kafka 也會面臨同樣的問題,雖然用了新技術,但貌似又回到了集中化的老路上去。這些都違背了微服務的”自治性原則”。

於是,就有人想,能不能通過容器技術,將代碼無關的一類安全、反向代理、日誌等拆散到各個服務實體上去。在單個服務的內部實現關注點分離——業務代碼和非業務組件隔離。比如,採用邊車模式處理端點的安全。這樣的方式十分有效的化解了集中服務組件的負載和依賴。於是這個模式就複製擴大,變成了服務網格(Service Mesh)。服務網格出現在 2017 年底的技術雷達上:

隨著大型組織過渡到擁有和運營自己微服務的自主團隊, 它們如何在不依賴集中式託管基礎結構的情況下確保這些服務之間必要的一致性和兼容性?為了高效地協同工作, 即使是自主的微服務也需要與某些組織標準保持一致。服務網格提供一致的發現、安全性、跟蹤、監視和故障處理, 而不需要共享資產 (如 API 網關或 ESB)。典型的實現涉及在每個服務進程旁邊部署的輕量級反向代理進程, 可能是在一個單獨的容器中。這些代理與服務註冊表、標識提供程序、日誌聚合器等進行通信。服務互操作性和可觀測性是通過此代理的共享實現獲得的, 而不是通過共享運行時實例獲得的。一段時間以來, 我們一直主張採用分散的微服務管理方法, 並很高興看到這種一致的模式出現。諸如 linkerd 和 Istio 這樣的開源項目將繼續成熟, 使服務網格更易於實現。

時下服務網格成為了微服務架構的熱門,但這種模式很明顯增大了網絡上的開銷,但分攤了服務治理的壓力。相對於微服務複雜性而言,這些開銷在某種程度上是可以接受的。

微服務 3.0:無服務器的微服務架構

從微服務技術的發展歷程來看,微服務技術的發展是不斷的把業務代碼和微服務運行時逐漸剝離的一個過程:讓儘可能多的不經常變更的部分沉澱到基礎設施裡,並通過基礎設施即代碼管理起來。

從 DevOps 的角度來看,應用程序在分離業務代碼和基礎設施的過程中清晰界定了開發和運維之間的職責。開發團隊要負責應用程序的業務代碼能夠跟隨業務的變化而演進。而運維團隊就要為開發團隊提供儘可能透明和可靠的基礎設施支持。

一言以蔽之:開發工程師除了寫業務代碼,什麼都不需要管。

早在 服務網格之前,後端應用即服務(Backend as service)就已經進入2014年的技術雷達。彼時還是移動端應用爆發的時候。開發人員可以通過這種方式專注於客戶端的開發。而到 AWS 推出了 AWS Lambda 和 Amazon APIGateway 後,函數即服務(Function as a service)的理念則標誌了無服務器應用架構(Serverless Architecture)的到來。

從技術雷達看​DevOps的十年——容器技術和微服務

Serverless 的架構把應用程序的理念推向了一個新的極致。以前的應用程序是需要考慮基礎設施狀態的:CPU/內存/磁盤是否足夠,帶寬是否足夠,網絡是否可靠。而在 Serverless 應用程序的世界裡,基礎設施層已經解決上述所有的問題,給開發者一個真正無限制的基礎設施空間。

開發者只要考慮的就是設計好各資源之間的事件處理關係,而所有的資源都是通過高可用的基礎設施承載。

在 UNIX 的世界裡,一切皆文件。而在 Serverless 應用的世界裡,一切皆 API。在 UNIX 的世界裡,我們消費流(Stream),應用程序是對流的處理。而在 Serverless 應用的世界裡,我們消費事件(Event),應用程序是對事件的處理。

這種思想特別適合基礎設施逐漸複雜的微服務,使得微服務的實施更加的輕便。但這也帶來了編程模型的轉變:函數式編程和麵向資源計算漸漸流行了起來。

從基礎設施的角度來看,微服務經歷了三代技術:

第一代微服務是基於虛擬機和物理機的基礎設施,將一個難以敏捷交付的大型應用程序通過輕量級分佈式系統敏捷化。為了提升可用性,我們要拆分應用的狀態以支持水平擴展。

第二代微服務是基於容器的基礎設施,我們通過容器鏡像分離了應用程序運行時狀態。

第三代微服務是基於雲的”運行時即服務(Runtime as a Service)”的能力,將基礎設施和應用程序的所有狀態都存儲在了雲計算平臺的高可用資源中。而應用程序本身則作為雲計算資源的配置被版本化管理起來。

這樣的思想影響也影響了容器社區,於是基於 Kubernetes 的 KNative 被開發了出來。企業級應用的理念和互聯網級應用的理念越來越接近。

應用微服務的組織問題

從上述的歷史可以看到,微服務是一系列技術和理念不斷革新的結果。而微服務這個詞掩蓋了太多的細節。

相較於技術和工具的不斷髮展,採用微服務的組織演進則緩慢的多。一方面是因為在大多數企業中,IT部門仍然不是核心部門,只是所有部門中的“二等公民”。另一方面是康威定律的生效時間會比較長。

特別是一些成功企業的“微服務”分享,使得那些擁有”落後”應用架構的組織開始嫉妒那些有微服務應用架構的組織。於是,就出現了”微服務嫉妒“的問題,它出現於 2015 年 11月的技術雷達:

我們仍然相信, 微服務可以為組織提供顯著優勢, 提高團隊自主權和加快變革頻率。分佈式系統帶來的額外複雜性需要額外的成熟度和投資水平。我們感到關切的是, 一些團隊在不瞭解開發、測試和操作的變化的情況下, 紛紛採用微服務。我們的一般建議仍然很簡單。避免“微服務嫉妒”, 在匆忙開發更多服務之前, 先從一兩個服務開始, 讓你的團隊有時間調整和理解合適的粒度水平。

強烈的攀比心態造成了微服務”大躍進”的風潮,這股風潮一直持續到現在。雖然採用的開發技術提升了,然而組織卻欠缺基礎的能力,使微服務的改造帶來了新的問題:

在現代基於雲的系統中, 微服務已經成為一種領先的架構技術, 但我們仍然認為團隊在做出這一選擇時應該謹慎行事。微服務嫉妒誘惑團隊通過擁有大量的服務來使他們的體系結構複雜化, 僅僅因為它是一種時尚的架構選擇。Kubernetes 等平臺使部署複雜的微服務集變得容易得多, 供應商正在推動他們的解決方案來管理微服務, 這可能會使團隊進一步走上這條道路。重要的是要記住, 微服務貿易發展的複雜性是運維的複雜性, 需要一個堅實的基礎,例如 自動化測試, 持續交付和 DevOps 文化。

這就是我經常說的:”眼光到位了,實力沒跟上”。

微服務是一系列基礎能力成熟後的必然結果。如果你要在短期內跨越這個階段,希望採用微服務架構來牽引組織能力的成長,就一定要有心理準備。你可以通過採購技術解決方案的方式一次性解決 3-5 年微服務實施中的技術問題。但組織中碰到的問題則沒有容易通過採購技術方案來消化。所以,在微服務的實施過程中,要警惕康威定律的作用,並且儘快讓組織裡形成 DevOps 的文化。

除此之外,很多架構師還一直停留在早期的分層架構思考,造成了”分層的微服務架構“:

微服務體系結構的一個決定性特徵是系統組件和服務是圍繞業務功能組織的。無論規模大小, 微服務都封裝了有意義的功能和信息分組, 以獨立交付業務價值。這與早期服務體系結構中根據技術特徵組織服務的方法形成鮮明對比。我們觀察到一些組織採用了分層微服務體系結構, 這在某些方面是矛盾的。這些組織已回到主要根據技術角色安排服務, 例如, 體驗 Api、進程 Api 或系統 Api。技術團隊很容易按層分配, 因此交付任何有價值的業務變化都需要多個團隊之間緩慢而代價高昂的協調。我們注意這種分層的影響, 並建議主要根據業務能力安排服務和團隊。

因此,架構師需要掌握新的技能,特別是領域驅動設計(Domain-Driven-Design,DDD)以及端口-適配器模式,採用六邊形架構來描述微服務架構,就會使你對整個架構的理解更加清晰。

除了開發、基礎設施、架構問題以外。微服務的測試是一個更大的問題。微服務雖然從架構上解耦了應用程序的複雜度,讓更少的功能隔離進了更小的發佈單元中。這樣可以縮小單個部署單元的測試範圍,但這無法保證整體的正確性。應用程序並不是一個線性系統,能夠通過部分的正確性加總得到整體的正確性。應用程序是一個複雜適應性系統,我們通過簡單的組件之間的組合只會使之更加複雜。

當我我們將複雜性通過技術設施移到了部署單元之外後,就會有更多的集成,因此集成測試的數量會立刻膨脹。如果你是一個前後端分離的團隊而不是一個圍繞業務的全功能團隊,你就需要”消費者驅動的契約測試“來做組織間的協作。

下面是微服務相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

"

在上一篇文章中,我們講到了基礎設施即代碼和雲計算給運維領域帶來的深遠影響。而 DevOps 運動不僅僅改變了運維端,同時也改變了開發端,特別是 Docker 的興起和微服務架構的流行。在這一篇,我們將通過技術雷達上相關條目的變化來考察 Docker 和微服務的發展。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

在 Docker 技術出現之前,可以說是 DevOps 技術的 1.0 的時代,人們關注如何做好 CI/CD 和基礎設施即代碼。而 Docker 的出現迎來了 DevOps 2.0 時代,DevOps 所有的實踐都圍繞著 Docker 展開,以 Docker 為中心的技術架構影響了軟件開發交付的方方面面。無論是開發還是運維都在討論和使用 Docker。它們採用統一的交付格式和技術語言在討論交付的過程,而不像之前開發只關注“打包前”,運維只關注“打包後”。

技術雷達關注 Linux 容器技術是在 Docker 出現之前,在 2012 年 4 月 的技術雷達上。“Linux 容器” 就出現在了技術雷達上的 “試驗” 區域:

虛擬容器是一種對 SaaS 和 PaaS 實現特別有吸引力的虛擬化風格。OpenVZ 等 Linux 容器提供了虛擬機的隔離和管理優勢, 而不需要通常與通用虛擬化相關的開銷。在容器模型中, Guest 操作系統僅限於與 Host 主機操作系統相同, 但這對許多雲應用程序來說並不是一個嚴重的限制。

一年之後,Docker 問世。兩年之後,Docker 進入技術雷達。

容器技術 1.0:輕量級的 Vagrant ?

在 Docker 出現之前,DevOps 社區就廣泛採用 Vagrant 測試 Chef 或者 Puppet 做基礎設施即代碼。所以,當我第一次看到 Docker 時,就感覺就是一個”輕量級的 Vagrant”。它們的思路幾乎一致:

  • Vagrant 通過 Ruby 語法的 Vagrantfile 構建一個虛擬機。而 Docker 通過 Dockerfile 構建一個容器。
  • Vagrant 通過 package 命令構建一個可複製虛擬機的鏡像。而 Docker 通過 build 構建一個鏡像。
  • Vagrant 通過 upload 將虛擬機鏡像上傳至 box 分享站點。而 Docker 通過 push 將鏡像上傳至 image 分享站點。

此外,每一個 Vagrant 命令,你都可以找到一個對應的Docker 命令。

唯一區別在於, Vagrant 是跨平臺的,而Docker 只針對 Linux 平臺。這樣就避免了 HAL(硬件抽象層)帶來的麻煩,使得 Docker 在 Linux 服務器上運行更加輕量,啟動更加快速和便捷。此外,Docker 的開發語言也使用 GO 而非 Ruby,相對而言前者更加穩定。那時,社區已經構建出來了基於 Vagrant 虛擬機的編排方案,並採用構建虛擬機鏡像的方式(Packer)構建生產環境的設施並部署應用,使得開發到生產環境上的差異最小化。

從技術雷達看​DevOps的十年——容器技術和微服務

(更多詳情可至ThoughtWorks官網查看)

不過,Docker 對 Vagrant 社區的精確定位塑造了它的成功。從 Vagrant 的鏡像站點 https://app.vagrantup.com/boxes/search 上可以看出,排名靠前的鏡像幾乎都是 Linux。所以,Docker 從 Vagrant 的市場中找到了 Linux 服務器這一個頭部市場,並且採用新的技術解決了這個核心頭部用戶群的痛點:重和慢。

此外,Docker 又借鑑了 Github 的版本化分享機制和麵向對象“繼承”的思想,提升了 Docker 鏡像的複用性。將基礎設施即代碼作為“源代碼”,鏡像作為編譯後的類,容器作為運行時的實例,完整的定義了一個應用和運行時的完整生命週期。這樣,應用程序就可以基於“自部署應用程序”的思想,將基礎設施和應用程序同時發佈,大大降低了基礎設施的配置和管理複雜度。

這樣的交付流程將 DevOps 1.0 時代的的“打包前”和“打包後”的開發-運維生命週期合作轉化成了“容器內”和“容器外”的雙生命週期合作。

如果將應用程序開發和運維看做是一個應用程序完整的生命週期,那麼容器內和容器外的劃分就是做了”關注點分離:容器提供了基礎設施無關的界面,使得基礎設施對開發人員透明,同時使得基礎設施獨立於應用。而容器外則是標準化、自動化且穩定的操作系統。

這種關注點分離的方式慢慢影響了應用程序的架構思路,促進了微服務技術向容器的發展。

容器技術 2.0:編排工具大混戰

一個運動繁榮的標誌就是有很多人蔘與並不斷湧現很多創新。在 Docker 出現之後,DevOps 在媒體上出現的頻率大大上升。從技術雷達就可以看出,在 Docker 出現在技術雷達後, DevOps 迎來了第二個繁榮期。

自從 Docker 在2016年進入技術雷達之後,技術雷達每一期都會有至少一個關於 Doker的新條目。

Docker 的開放確實為 DevOps 的實施製造了很大的想象空間。如果我們把之前的虛擬機編排改成容器編排會怎麼樣?是不是能夠基於容器構建自動水平伸縮?這樣是不是就可以節約更多的資源?可以更快的發佈應用。

多方都在這個領域中角逐,Docker 在開源圈不斷收購工具,將 fig 收購變為 docker-compose,將 Swarm 和 Docker machine 納入了 docker 全家桶中。Google 將自己的內部的編排方案 Borg 開源成為了 Kubernetes。此外還有基於 Apache Mesos 構建的 Mesosphare 和 Rancher 這樣的輕量級競爭對手。

從技術雷達看​DevOps的十年——容器技術和微服務

(2015年11月期技術雷達)

從它們在技術雷達所處的位置,就可以看出其發展趨勢,它們都於 2015 年 11 月進入 “評估” 區域。

  • Kubernetes 於 2016年 4月 從 “評估” 升入 “試驗” 區域,並於 2017 年 11 月正式進入 “採納” 區域。4 個月後從 CNCF 畢業。
  • Rancher 於 2016 年 11 月進入 “試驗” 區域後止步於此。
  • Mesosphere DCOS 則一直處於 “評估” 區域。

然而,作為 Docker 原生方案的 Docker Swarm 則從未出現在技術雷達上。

容器技術 3.0:圍繞微服務構建生態

當 Kubernetes 贏得了容器戰爭之後,所有的容器廠商俯首稱臣。各大廠商在保留了自己的容器編排方案後,紛紛宣佈對 Kubernetes 的支持,包括 Docker 自己。

觀望容器戰爭的雲計算廠商最後來摘取獲得經過市場淘汰後的果實。就像我們上篇講的,雲計算廠商也紛紛加入到了 Kubernetes 即服務(Kubernetes As A Service)的角逐中來。

這讓 Linux 基金會看到了商機。藉著 Kubernetes 的東風,Linux 基金會開始琢磨圍繞著 Kubernetes 構建出一個生態。為了避免被單一廠商劫持(Docker 曾經為了擠兌無法收購的競爭對手 ,強推自己的 Swarm 和 Docker EE 也發佈了很多其它平臺不兼容的版本),Linux 基金會在其旗下組建了 CNCF (雲原生計算基金會)。

相較於 Apache 基金會,CNCF 更加專注於開源的容器應用。不過,從商業角度上,它抓住了下游用戶和上游雲計算供應商的痛點,依仗著對 Kubernetes 的控制,篩選了符合其”下游壟斷”策略的開源項目。這樣做一方面避免了上游雲計算服務廠商在同一領域的競爭,另一方面給於了下游用戶更少的選擇。這個看似空手套白狼的生意一年能夠讓 CNCF 基金會進賬至少 871 萬美元(約合5850 萬 人民幣)。

如果說容器 1.0 是容器技術的競爭,容器技術 2.0 是編排技術的競爭,3.0 就是容器生態的競爭。CNCF 抓住了微服務這一大賣點。圍繞著 Kubernetes 組建了基於 Kubernetes 的微服務生態。

然而這些項目也不負眾望,繼 Kubernetes 第一個從 CNCF 孵化畢業後,相關其餘的開源項目逐個畢業。而這些開源項目在畢業前就出現在了技術雷達上:Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook

開源使得產業從廠商壟斷(類似於 微軟,IBM,Oracle 這樣的大型IT廠商)慢慢過渡到行會壟斷(類似 CNCF 這種基金會),說明了這個產業的供給在不斷加大。而隨著免費的內容越來越多,重複性低質量的內容反而會佔據很多時間。這樣雖然讓開源社區集中了注意力“把一件事情做好”,另一方面,利用對社區的劫持消滅了同期的其它競爭對手。

Windows 容器

在容器技術的大戰中,微軟一直是一個獨立的存在。眼瞅著 Linux 和虛擬化廠商們幹掉了商業 UNIX 廠商。眼看Linux 作為服務器操作系統在不斷蠶食 Windows Server的份額。微軟也坐不住了,開始加入容器領域。

Windows Server 最為詬病的就是太大太重,對於運行很多單一服務端應用程序和分佈式系統而言過於臃腫。於是微軟把圖形用戶界面和 32 位應用的支持以及遠程桌面都移除了。

Windows Server 因為沒有 Window 了,那還叫 Windows 嗎?所以,沒有 Window 的 Windows Server 就是就成為了 Microsoft Nano Server 。Microsoft Nano Server 就是微軟在服務器操作系統領域上的第一個容器化嘗試。 2015 年11月Microsoft Nano Server 和 Kubernetes 等編排工具一起出現在了進入技術雷達的 “評估” 區域。

與基於 Linux 的現代雲和容器解決方案不同, 即使是 Windows Server Core 也很重。Microsoft 正在做出反應, 並提供了 Nano server 的第一個預覽, 這是一個進一步剝離的 Windows Server 版本, 它丟棄了 GUI 堆棧、32位 win32 支持、本地登錄和遠程桌面支持, 從而產生了大約 400 MB 的磁盤上大小。早期的預覽很難使用, 最終的解決方案將僅限於使用 CoreCLR, 但對於有興趣運行的公司來說。基於網絡的解決方案, 納米服務器絕對值得看看這個階段。

但作為 Windows Server 的小表弟,出道之初並沒有那麼順利。相較於 Linux,Microsoft Nano Server 還是太大了。於是,微軟基於 Docker 推出了自己的容器技術,Windows Containers。Windows Containers 出現在了 2017 年11月的技術雷達上:

微軟正在用 Windows 容器在容器空間中迎頭趕上。在編寫本報告時, Microsoft 提供了兩個 Windows 操作系統映像作為 Docker 容器, 即 Windows Server 2016 Server Core 和 Windows Server 2016 Nano Server。儘管 Windows 容器還有改進的餘地, 例如, 減少了較大的鏡像大小, 並豐富了生態系統的支持和文檔, 但我們的團隊已經開始在其他容器一直在工作的情況下使用它們成功, 例如:構建代理(Build Agent)。

容器技術作為一種輕量級的操作系統隔離和應用程序發佈手段,帶來了很大的便利性。它讓我們能夠將複雜的內容通過簡單的方式封裝起來,從而進一步降低複雜性,特別是對大型應用程序的解耦,這就推動了微服務技術的進一步發展。

下面是 Docker 相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目

容器安全掃描,Docker,用 TDD 開發容器,Rancher,Kubernetes,Mesosphere DC/OS,Apache Mesos,Prometheus、Istio、Helm、Jaeger、OpenTracing,Rook


從演進式架構到微服務

可以說,微服務是 DevOps 所有實踐發展的一個必然結果。它不光是一種應用架構,而是包含了多年來敏捷、DevOps、雲計算、容器等技術實踐的綜合應用。

在以 ESB 為基礎的大規模企業級應用出現之前,企業級應用軟件的開發規模相對較小,大部分都是基於現有軟件包產品的二次定製。採用敏捷的方式來交付這些應用是可控的。然而隨著 ESB 將企業級應用的信息孤島集成起來。敏捷軟件開發似乎就顯得力不從心了。

演進式架構在 2010 年第一期技術雷達就被提出來。在敏捷軟件開發實踐開始應用於大規模應用程序的案例中。”架構”和“變化”出現了矛盾。如何讓包含了“不輕易改變的決定”的架構和“擁抱變化”的敏捷共處,於是有了演進式架構:

我們幫助我們的許多客戶調整企業軟件體系結構實踐, 以適應敏捷軟件交付方法。在過去的一年裡, 我們看到人們對進化企業架構以及面向服務的架構如何塑造企業單位之間的界限越來越感興趣。企業架構的進化方法的價值在於創建重量更輕的系統, 從而簡化不同部件之間的集成。通過採用這種方法和將 web 作為企業應用程序平臺(Web as Enterprise Platform)的概念, 我們降低了應用程序體系結構的總體複雜性, 提高了質量和可擴展性, 並降低了開發成本。

2010 年 8 月演進式架構進入了”試驗”區域,但在2011年1月的技術雷達上更新了對它的評價:

敏捷軟件開發的一個原則是”最後責任時刻”的概念。這一概念適用於架構設計, 它在傳統架構師中引起了爭議。我們相信, 只要有適當闡述的原則和適當的測試套件, 架構就可以不斷髮展, 以滿足系統不斷變化的需求, 從而在不影響完整性的情況下, 在最後一個負責任的時刻做出體系結構決策系統的。我們將這種方法稱為進化體系結構, 因為我們允許體系結構隨著時間的推移而演變, 始終尊重體系結構的指導原則。

半年後,2011年6月,演進式架構進入了”採用”區域,技術雷達再次更新了評價:

與傳統的前期、重量級企業架構設計不同, 我們建議採用演進式架構。它提供了企業架構的好處, 而沒有嘗試準確預測未來所造成的問題。演進式架構不應該猜測組件將如何重用, 而是支持適應性, 使用適當的抽象、數據庫遷移、測試套件、持續集成和重構來獲取系統中發生的重用。應儘早確定系統的驅動技術要求, 以確保在後續設計和實現中正確處理這些要求。我們主張將決定推遲到”最後責任時刻”, 這實際上可能是一些決定的先行。

在這些概念不斷變化的過程中,不斷有方法論、實踐和工具被提出。在演進式架構的思想影響下,誕生了新的實踐 —— 微服務。微服務的出現,讓演進式架構有了第一個實例化的例子。

微服務 1.0:輕量級 SOA

在技術雷達裡,微服務是以”Micro-services”而非”Microservices”出現的。在技術雷達的角度中,微服務仍然是 SOA 的一種輕量化的實現方式。在 2012 年 3月的技術雷達中,微服務首先出現在了技術雷達的“評估”區域:

微服務通常是脫離應用容器部署或使用嵌入式 HTTP 服務器部署, 它是對傳統的大型技術服務的一種遷移。這種方法通過增加運維複雜性而提升系統的可維護性。這些缺點通常使用基礎設施自動化和持續部署技術來解決。總的來說, 微服務是管理技術債務和處理不同伸縮特徵的有效方法, 尤其是在圍繞業務能力構建的面向服務的體系結構中部署時。

這裡需要劃幾個重點:

  1. 微服務脫離應用容器部署或者使用嵌入式 HTTP 服務器。這一年,Docker 還沒有出現。這裡的容器指的是 WebSphere,WebLogic 這樣的容器。嵌入式 HTTP 服務器指的是 Jetty、Tomcat 或者 DropWizard 這樣的輕量級選擇。這樣代碼庫可以自部署,而不是通過應用容器部署。
  2. 微服務是一種內部複雜度向外部的轉化:通過把應用隔離到不同的進程中,可以縮小變更的影響範圍。通過將內部複雜性轉化成外部複雜性從而使應用更易維護。而外部複雜性就交給自動化的基礎設施管理。
  3. 微服務提升了維護的複雜性和難度。如果沒有 DevOps 組織,服務之間的 應用的風險就由開發轉嫁給了維護。不過,作為Ops 可以通過自動化和持續部署/藍綠髮布來解決。
  4. 微服務便於管理技術債務,可以做到部分的按需伸縮。
  5. 微服務是圍繞業務能力的 SOA 架構。

總的來說,微服務在那個時期就是採用輕量級技術來圍繞業務實施 SOA。然而,這樣的實踐慢慢的形成了一種成熟的模式,並慢慢推廣開來。在2012年10月的技術雷達,微服務就進入了”試驗”區域,而到了 2014 年 1 月。技術雷達更新了對微服務的描述:

我們看到, 無論是在 ThoughtWorks 還是在更廣泛的社區, 微服務作為分佈式系統設計技術的採用都在上升。DropWizard 程序等框架和聲明性初始化等實踐表明技術和工具的成熟。避免採用通常的單體應用辦法,微服務更傾向於在必要的情況下替換而非修改局部應用系統。這對應用系統的總體成本具有重要的積極影響。我們認為, 這會在中長期有著巨大的影響, 特別是大部分應用的重寫週期都在 2 – 5 年。

隨著 DropWizard 開始在 Java 用戶群展露頭角,各個其它語言社區也出現了自己的輕量級 API 框架。Ruby 社區率先出現 了 Sinatra 框架,它的輕量級語法深刻的影響了未來各語言的微服務框架。例如而 .Net 社區中出現了Nancy。Python 社區出現了 Flask 。

微服務 2.0:結合基礎設施的全面架構設計

單一的輕量級服務端框架並不能端到端的解決服務消費者和服務提供者的所有問題。隨著應用慢慢的開始被拆分成了微服務,基礎設施的管理變成了一個新的問題。在分佈式系統環境下,基礎設施的範圍要比虛擬機時代廣泛的多。複雜的基礎設施和即代碼的集中式管理成為了另一個“單體”應用。於是有了前文介紹的去中心化的 Chef 和 Puppet 實踐。讓基礎設施代碼作為應用代碼庫的一個部分,這樣,就可以構建出一個“自部署”的應用。

這樣的想法推動了 Ansible 和 Vagrant 的流行,並伴隨著持續交付的實踐。我們可以通過構建可執行的虛擬機鏡像將應用切分成不同的虛擬機來運行。在那個時期,一個大型應用能夠被拆分到多個虛擬機中自動化管理已經很先進了。

然而,Docker 的出現,將這一系列最佳實踐固化成了一個完成的應用程序生命週期:開發人員通過構建 Docker 鏡像在本地開發,然後通過持續交付流水線構建成版本化鏡像。容器平臺按需拉取鏡像並直接運行,從開發環境到生產環境幾乎沒有差別。運維平臺只要能夠通過虛擬化資源使容器能夠輕易的運行,就打通了端到端的最短距離。

從技術雷達看​DevOps的十年——容器技術和微服務

正如上文所述“容器內”和“容器外”被清晰的隔離開,無論從組織上還是架構上,都適應了這套模型。此外,基礎設施的關注點分離變成了兩個部分:應用程序的運行時管理和應用間的通信。

剛開始的時候,Docker 看起來更像是一個“輕量級的虛擬機”——我們通過鏡像構建出一個運行實體。但隨著應用程序的責任分離,Docker 就更像是一個“重量級的進程”。我們如果把容器按責任分離,就可以把容器看做是一個個通過 API 暴露的資源。這樣,我們就可以採用雲計算的資源編排的方式來處理應用之間的問題。恰逢 Docker 的容器間網絡和編排工具的成熟,使我們有了更多的容器編排方案可以選擇。

剛開始的時候,微服務之間還是簡單的 HTTP 調用。我們可以通過 Nginx 作為 API 網關。隨著服務變得複雜,對於 API 網關的要求就越來越多,於是就有了單一的 API 網關方案,簡化了 API 管理。

如何讓網關知道每個服務的情況呢?一方面,API 網關需要知道服務的存活情況。另一方面,服務自身要能夠主動彙報自身的狀態,於是 Consul 這樣的服務註冊發現解決方案就逐漸流行起來。

從技術雷達看​DevOps的十年——容器技術和微服務

同時,日誌收集和監控要集成到每個服務中去,從管理的角度也要能聚合所有的日誌和監控,於是有了OpenTracing 這樣的解決方案。

隨著微服務架構體系越來越複雜,這些零散的工具和應用開發框架的集成變成了新的問題。這樣的問題最早出現在 Java 社區 —— 因為大部分大型應用仍然是基於 Java EE 的。於是 Spring 推出了Spring Cloud —— 坊間稱之為 Spring 微服務全家桶,它包含了所有微服務端到端的組件。雖然Spring Boot 出現的比較晚,但憑藉著 Spring 在 Java 社區的號召力使其迅速超過 DropWizard,Jersey 等方案脫穎而出。成為了目前 Java 社區的 微服務構建首選。

然而,部署實例裡仍然存在著安全、監控、日誌收集這樣的基礎設施功能,就出現了”野心過大的 API 網關“。這個問題出現在了 2015 年11 月份的技術雷達上:

我們常見的抱怨之一是將業務智能推入中間件, 從而產生了具有運行關鍵應用程序邏輯雄心的應用程序服務器和企業服務總線。這些都需要在不適合這一目的的環境中進行復雜的編程。我們看到這種疾病的重新出現令人擔憂, 因為 API 網關產品常常野心過大。API 網關可以在處理一些一般問題 (例如, 身份驗證和速率限制) 時提供實用程序, 但任何域智能 (如數據轉換或規則處理) 都應駐留在應用程序或服務中, 這些應用程序或服務可以由與他們支持的領域密切合作的產品團隊。

不光 API 會出現這樣的問題。替代傳統消息隊列的 Kafka 也會面臨同樣的問題,雖然用了新技術,但貌似又回到了集中化的老路上去。這些都違背了微服務的”自治性原則”。

於是,就有人想,能不能通過容器技術,將代碼無關的一類安全、反向代理、日誌等拆散到各個服務實體上去。在單個服務的內部實現關注點分離——業務代碼和非業務組件隔離。比如,採用邊車模式處理端點的安全。這樣的方式十分有效的化解了集中服務組件的負載和依賴。於是這個模式就複製擴大,變成了服務網格(Service Mesh)。服務網格出現在 2017 年底的技術雷達上:

隨著大型組織過渡到擁有和運營自己微服務的自主團隊, 它們如何在不依賴集中式託管基礎結構的情況下確保這些服務之間必要的一致性和兼容性?為了高效地協同工作, 即使是自主的微服務也需要與某些組織標準保持一致。服務網格提供一致的發現、安全性、跟蹤、監視和故障處理, 而不需要共享資產 (如 API 網關或 ESB)。典型的實現涉及在每個服務進程旁邊部署的輕量級反向代理進程, 可能是在一個單獨的容器中。這些代理與服務註冊表、標識提供程序、日誌聚合器等進行通信。服務互操作性和可觀測性是通過此代理的共享實現獲得的, 而不是通過共享運行時實例獲得的。一段時間以來, 我們一直主張採用分散的微服務管理方法, 並很高興看到這種一致的模式出現。諸如 linkerd 和 Istio 這樣的開源項目將繼續成熟, 使服務網格更易於實現。

時下服務網格成為了微服務架構的熱門,但這種模式很明顯增大了網絡上的開銷,但分攤了服務治理的壓力。相對於微服務複雜性而言,這些開銷在某種程度上是可以接受的。

微服務 3.0:無服務器的微服務架構

從微服務技術的發展歷程來看,微服務技術的發展是不斷的把業務代碼和微服務運行時逐漸剝離的一個過程:讓儘可能多的不經常變更的部分沉澱到基礎設施裡,並通過基礎設施即代碼管理起來。

從 DevOps 的角度來看,應用程序在分離業務代碼和基礎設施的過程中清晰界定了開發和運維之間的職責。開發團隊要負責應用程序的業務代碼能夠跟隨業務的變化而演進。而運維團隊就要為開發團隊提供儘可能透明和可靠的基礎設施支持。

一言以蔽之:開發工程師除了寫業務代碼,什麼都不需要管。

早在 服務網格之前,後端應用即服務(Backend as service)就已經進入2014年的技術雷達。彼時還是移動端應用爆發的時候。開發人員可以通過這種方式專注於客戶端的開發。而到 AWS 推出了 AWS Lambda 和 Amazon APIGateway 後,函數即服務(Function as a service)的理念則標誌了無服務器應用架構(Serverless Architecture)的到來。

從技術雷達看​DevOps的十年——容器技術和微服務

Serverless 的架構把應用程序的理念推向了一個新的極致。以前的應用程序是需要考慮基礎設施狀態的:CPU/內存/磁盤是否足夠,帶寬是否足夠,網絡是否可靠。而在 Serverless 應用程序的世界裡,基礎設施層已經解決上述所有的問題,給開發者一個真正無限制的基礎設施空間。

開發者只要考慮的就是設計好各資源之間的事件處理關係,而所有的資源都是通過高可用的基礎設施承載。

在 UNIX 的世界裡,一切皆文件。而在 Serverless 應用的世界裡,一切皆 API。在 UNIX 的世界裡,我們消費流(Stream),應用程序是對流的處理。而在 Serverless 應用的世界裡,我們消費事件(Event),應用程序是對事件的處理。

這種思想特別適合基礎設施逐漸複雜的微服務,使得微服務的實施更加的輕便。但這也帶來了編程模型的轉變:函數式編程和麵向資源計算漸漸流行了起來。

從基礎設施的角度來看,微服務經歷了三代技術:

第一代微服務是基於虛擬機和物理機的基礎設施,將一個難以敏捷交付的大型應用程序通過輕量級分佈式系統敏捷化。為了提升可用性,我們要拆分應用的狀態以支持水平擴展。

第二代微服務是基於容器的基礎設施,我們通過容器鏡像分離了應用程序運行時狀態。

第三代微服務是基於雲的”運行時即服務(Runtime as a Service)”的能力,將基礎設施和應用程序的所有狀態都存儲在了雲計算平臺的高可用資源中。而應用程序本身則作為雲計算資源的配置被版本化管理起來。

這樣的思想影響也影響了容器社區,於是基於 Kubernetes 的 KNative 被開發了出來。企業級應用的理念和互聯網級應用的理念越來越接近。

應用微服務的組織問題

從上述的歷史可以看到,微服務是一系列技術和理念不斷革新的結果。而微服務這個詞掩蓋了太多的細節。

相較於技術和工具的不斷髮展,採用微服務的組織演進則緩慢的多。一方面是因為在大多數企業中,IT部門仍然不是核心部門,只是所有部門中的“二等公民”。另一方面是康威定律的生效時間會比較長。

特別是一些成功企業的“微服務”分享,使得那些擁有”落後”應用架構的組織開始嫉妒那些有微服務應用架構的組織。於是,就出現了”微服務嫉妒“的問題,它出現於 2015 年 11月的技術雷達:

我們仍然相信, 微服務可以為組織提供顯著優勢, 提高團隊自主權和加快變革頻率。分佈式系統帶來的額外複雜性需要額外的成熟度和投資水平。我們感到關切的是, 一些團隊在不瞭解開發、測試和操作的變化的情況下, 紛紛採用微服務。我們的一般建議仍然很簡單。避免“微服務嫉妒”, 在匆忙開發更多服務之前, 先從一兩個服務開始, 讓你的團隊有時間調整和理解合適的粒度水平。

強烈的攀比心態造成了微服務”大躍進”的風潮,這股風潮一直持續到現在。雖然採用的開發技術提升了,然而組織卻欠缺基礎的能力,使微服務的改造帶來了新的問題:

在現代基於雲的系統中, 微服務已經成為一種領先的架構技術, 但我們仍然認為團隊在做出這一選擇時應該謹慎行事。微服務嫉妒誘惑團隊通過擁有大量的服務來使他們的體系結構複雜化, 僅僅因為它是一種時尚的架構選擇。Kubernetes 等平臺使部署複雜的微服務集變得容易得多, 供應商正在推動他們的解決方案來管理微服務, 這可能會使團隊進一步走上這條道路。重要的是要記住, 微服務貿易發展的複雜性是運維的複雜性, 需要一個堅實的基礎,例如 自動化測試, 持續交付和 DevOps 文化。

這就是我經常說的:”眼光到位了,實力沒跟上”。

微服務是一系列基礎能力成熟後的必然結果。如果你要在短期內跨越這個階段,希望採用微服務架構來牽引組織能力的成長,就一定要有心理準備。你可以通過採購技術解決方案的方式一次性解決 3-5 年微服務實施中的技術問題。但組織中碰到的問題則沒有容易通過採購技術方案來消化。所以,在微服務的實施過程中,要警惕康威定律的作用,並且儘快讓組織裡形成 DevOps 的文化。

除此之外,很多架構師還一直停留在早期的分層架構思考,造成了”分層的微服務架構“:

微服務體系結構的一個決定性特徵是系統組件和服務是圍繞業務功能組織的。無論規模大小, 微服務都封裝了有意義的功能和信息分組, 以獨立交付業務價值。這與早期服務體系結構中根據技術特徵組織服務的方法形成鮮明對比。我們觀察到一些組織採用了分層微服務體系結構, 這在某些方面是矛盾的。這些組織已回到主要根據技術角色安排服務, 例如, 體驗 Api、進程 Api 或系統 Api。技術團隊很容易按層分配, 因此交付任何有價值的業務變化都需要多個團隊之間緩慢而代價高昂的協調。我們注意這種分層的影響, 並建議主要根據業務能力安排服務和團隊。

因此,架構師需要掌握新的技能,特別是領域驅動設計(Domain-Driven-Design,DDD)以及端口-適配器模式,採用六邊形架構來描述微服務架構,就會使你對整個架構的理解更加清晰。

除了開發、基礎設施、架構問題以外。微服務的測試是一個更大的問題。微服務雖然從架構上解耦了應用程序的複雜度,讓更少的功能隔離進了更小的發佈單元中。這樣可以縮小單個部署單元的測試範圍,但這無法保證整體的正確性。應用程序並不是一個線性系統,能夠通過部分的正確性加總得到整體的正確性。應用程序是一個複雜適應性系統,我們通過簡單的組件之間的組合只會使之更加複雜。

當我我們將複雜性通過技術設施移到了部署單元之外後,就會有更多的集成,因此集成測試的數量會立刻膨脹。如果你是一個前後端分離的團隊而不是一個圍繞業務的全功能團隊,你就需要”消費者驅動的契約測試“來做組織間的協作。

下面是微服務相關條目的發展歷程一覽圖。實線為同一條目變動,虛線為相關不同條目變動:

從技術雷達看​DevOps的十年——容器技術和微服務

相關條目:

演進式架構,Nancy,Consul,OpenTracing ,Spring Cloud ,野心過大的 API 網關,邊車模式處理端點的安全,服務網格(Service Mesh),後端應用即服務(Backend as service),AWS Lambda, Amazon APIGateway ,無服務器應用架構(Serverless Architecture),KNative,分層的微服務架構,消費者驅動的契約測試,微服務嫉妒


文/ThoughtWorks顧宇

更多精彩洞見,請關注微信公眾號:ThoughtWorks洞見

"

相關推薦

推薦中...