螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

尋夢新聞LINE@每日推播熱門推薦文章,趣聞不漏接❤️

加入LINE好友

小螞蟻說:

本文是基於在 Service Mesher Meetup 上海站的主題分享《螞蟻金服 Service Mesh 漸進式遷移方案》內容整理,完整的分享 PPT 獲取方式見文章底部。

敖小劍,螞蟻金服高級技術專家,十六年軟件開發經驗,微服務專家,Service Mesh 布道師,Servicemesher 社區聯合創始人;龍軾,阿里巴巴技術專家、前京東 Hadoop 負責人、Hadoop 代碼貢獻者、現負責UC 基於 Kubernetes 自研的 PaaS 平台整體的穩定性。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

大家好,今天給大家帶來的演講主題是《螞蟻金服 Service Mesh 漸進式遷移方案》,給大家介紹一下我們螞蟻金服主站的 Service Mesh 遷移方案,在稍後的內容中我會給大家解釋什麼是「漸進式」。今天的演講方式有些特殊,將會是兩位講師合作。我是敖小劍,來自螞蟻金服中間件團隊,另外一位講師 龍軾 ,來自 UC 基礎研發部。

Service Mesh 演進路線

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

今天的內容將會有四塊主要內容:

  1. Service Mesh演進路線:介紹螞蟻金服計劃在主站落地Service Mesh的方案,由於涉及到大量的存量應用和超大規模,又要保證遷移過程的平滑,因此我們的落地方案相比社區方案要複雜的多。
  2. 做到平滑遷移的關鍵:介紹在整個遷移方案中,為了做到平滑遷移的幾個關鍵做法,然後今天我們將詳細展開其他的一個關鍵點:DNS尋址方案。
  3. DNS尋址方案的演進:詳細介紹Kubernetes/Istio/SOFAMesh一路演進過來的DNS尋址方式。
  4. DNS尋址方案的後續規劃:介紹我們在DNS尋址方案上的後續規劃。

前兩塊內容將由我來為大家介紹,後兩塊內容將由我的同事 龍軾 為大家介紹。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

在展開內容之前,先看一下背景,Service Mesh在螞蟻金服主站落地的背景:

  • 目標:需要滿足我們對長期目標的認可,具體指服務間通訊走Service Mesh,而且是Istio這種帶完整的控制平面的Service Mesh形態,基礎設施要構建在k8s之上,而應用的形態要向微服務靠攏。
  • 現狀:而現實是存在很多挑戰,首先還有很多應用沒有做到微服務化,而且我們的k8s普及程度也不夠,還有非常多的應用沒有運行在kubernets之上。Istio的成熟程度也稍顯不足,不夠穩定,更大的挑戰的是Istio目前無法原生支持我們螞蟻金服的規模,我們還在試圖對Istio進行改進和擴展。最後,在落地時必須考慮的非常現實的一點:現有系統中為數眾多的應用不可能一夜之間全部遷移。
  • 關鍵需求:因此在落地實施時,非常重要的需求是:要做到平滑遷移。簡單說,微服務 + Service Mesh + kubernetes 是我們的目標,但是如何從現有體系出發,向目標平穩和堅實的邁進,必須給出可行的實踐指導。

今天演講的內容,要給大家介紹的就是,在這樣的背景下,我們螞蟻金服選擇的Service Mesh主站落地演進方案。這個方案預期會在2019年初全面鋪開。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

主站落地方案的實施原則,這是我們在過去半年的實踐中,總結歸納出來的行為指導:

  • 符合遠期規劃:一定要有清晰的長期目標,明確的知道未來的大方向。避免走彎路,避免浪費投資,理想狀態是計劃中的每一步都可以為下一步奠定堅實的基礎。即使因為某些原因不得已妥協或繞行,也應該清晰的知道後面應該如何回歸,謝絕中途推倒重來——代價太高,無法承受。
  • 循序漸進:認清現實,如此之大的變革,一定是需要分步進行,不要心存一步登天的幻想,現實可行的方式是小步快跑。將整個過程拆解為若干個大步驟,每一步的工作量和複雜度都控制在一個可以接受的範圍內,以保證每一步都簡單方便,切實可行。
  • 有可操作性:在操作層面上,要有足夠的彈性,即每個步驟中的工作內容,都應該是可以分批進行。以步步為營的方式,逐步擴大戰果,杜絕一刀切。

在接下來的演進路線中,大家將會體會到這三個原則在實際落地時的指導作用。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

這個圖的信息量有點大,描述的是 Service Mesh 和 k8s 落地可能的多種演進路線。

我們先從最下面開始看,這是當前螞蟻金服主站大多數應用的現狀:即應用”部署在非k8s上”,應用也”不是Service Mesh形態”。 然後看最上面,這是我們期望的螞蟻金服主站未來的應用終極形態:應用”部署在k8s上”,應用也遷移到了”Service Mesh形態”。

這里有個特別的地方,我們將Service Mesh形態細分為兩種模式:

  1. Sidecar模式:只有Sidecar,沒有控制平面,和外部系統的各種集成都是在Sidecar中直接進行。這是第一代的Service Mesh,Linkerd/Envoy都是如此,華為基於ServiceComb演進而來的mesher,新浪微博的Mesh,包括我們螞蟻金服基於MOSN開發的用於取代多語言客戶端的Mesh方案。
  2. Istio模式:有完善的控制平面,可以提供強大的控制能力,而且從數據平面分離,這是第二代的Service Mesh,典型如Istio和Conkduit/Linkerd 2.0。

之所以將Service Mesh形態細分,是因為我們有著這樣一個特殊背景:目前的原生Istio無法支撐我們螞蟻金服的規模,因此在改進完善Istio之前,我們不得不暫時在Sidecar模式下短暫停留。另外一個原因就是考慮到存量應用的遷移,多一個Sidecar模式作為中間緩沖,會讓整個遷移過程平滑很多。

現在我們來介紹圖中展示的四條演進路線:

  1. 左邊的路線1,思路是先將應用遷移k8s部署,再遷移到Service Mesh形態。這條路線的最大好處,是過程中每個階段的絕大多數投資都將最終得以保留,因為符合k8s+service mesh的遠期目標。
  2. 右邊的路線2,思路是跳過k8s,先遷移到Service Mesh形態,一路演進到Istio模式,然後最後遷移到k8s。
  3. 中間的路線3,直接一步到位,這個路線是Istio默認的方式,或者說Istio根本沒有考慮過遷移的問題,默認客戶已經有完善的k8s,然後將改造好的應用直接部署在Istio上。這個路線對於螞蟻金服主站的複雜場景,當然是不現實的。(補充:只是對螞蟻金服主站不合適,對於大多數公司,規模不是那麼巨大,也沒有歷史負擔,也有k8s基礎,完全可行。)
  4. 還有一條特別的路線4,走位飄忽,先和路線2一樣遷移到Sidecar模式,然後走回路線1,上k8s,再在有k8s支持的情況下繼續演進到Istio模式。

下面我們來詳細分析各條演進路線的優劣和實施條件。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

演進路線2,和路線1的核心差別,在於:是先上k8s,還是先上Service Mesh。而且路線2是在非k8s條件下一路演進Service Mesh到我們期望的終極形態Istio模式,這意味著過程中和最終目標有非常大的偏移。

演進路線2的好處,在於第一步非常的自然:

  • 沒有k8s的限制,因此不依賴基礎設施,實施方便。畢竟,k8s普及度是個大問題。
  • 在原有的侵入式框架的客戶端SDK基礎上,通過包裹一個proxy,重用原有SDK的能力,可以非常快速的得到一個基本可用的Sidecar。
  • 除了多一個proxy外,沒有引入太多的新概念和新思想,符合現有開發人員/運維人員的心智,容易接受

因此,路線2特別容易落地,可以快速達成短期目標,直接拿到Service Mesh的部分紅利,如:多語言支持,方便類庫升級等。

但是,這個路線的問題在於再往後走,開始完善Service Mesh的功能以向Istio模式靠攏時,由於沒有k8s的底層支持,因此不得不做大量的工作來提供類k8s的功能。尤其是Istio的非k8s支持,官方方案基本上只是一個demo,完全不具備生產可用性,要完善好,工作量很大。而關鍵點在於,這些投入,在遷移到k8s時,又因為和k8s提供的功能重復而被放棄。

因此,結合我們前面的原則(符合遠期規劃,不浪費投資),路線2對螞蟻金服主站落地是不合適的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

演進路線4是一個非常特殊的路線,可以理解為路線1(先上k8s再上Service Mesh)的短期妥協版本。因為路線1的前提條件是要先大規模鋪開k8s,將現有應用遷移到k8s之後再繼續往Service Mesh演進,這對於還沒有普及k8s的公司來說是一個非常高的門檻,很容易因此受阻而無法啟動。

因此,如果暫時不具備k8s條件, 又不想就此止步,那麼選擇路線2是唯一的出路。而上面我們分析過,路線2雖然能夠在第一步快速拿到短期紅利,但是由於偏離長期目標後續發展會有問題。怎麼辦?

路線4可以是這種場景下的一個折衷選擇:在k8s沒有鋪開之前,第一步沿路線2走,先吃下非k8s下Sidecar模式快速落地的紅利。然後第二步避開非k8s下繼續演進到Istio模式的大坑,切換到路線1,回歸長期目標。

好處非常明顯:

  • 在k8s未鋪開前,先往前邁進一步,避免就此卡殼。
  • 和路線2一樣,第一步可以快速的拿到短期紅利。
  • 後續轉為路線1後,因為符合遠期規劃,因此後續演進不存在投資浪費的問題

缺點就是存在少量的投資浪費,畢竟非k8s下的Sidecar模式還是有些工作內容在遷移到k8s之後會有改動。不過,這個改動不會太大,和拿到的紅利相比還是值得的。

路線4在操作時,存在一個變數:現有應用在向Sidecar模式的Service Mesh遷移,是需要一定時間的。有一種可能,就是在遷移過程中,k8s的普及開始了。這個變數的發生,取決於Sidecar模式的Service Mesh普及快,還是k8s的普及快。

對路線4的分析結果:這是(k8s沒有普及的)特殊時期的選擇。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

在對四條可能的演進路線分析完成之後,我們來具體介紹螞蟻金服的最終選擇。

坦言說,在過去半年中,我們的演進路線有幾次搖擺和修訂,今天我們公布的路線,和過去幾個月中我們通過 meetup/技術大會/博客文章 等方式透露出來的方式會有一些變化。主要原因是在過去的這半年中,一方面我們對Sercice Mesh的認知更加深入,另一方面是螞蟻金服的k8s背景也在變化。

首先,在今年年初,我們確認Service Mesh大方向時,k8s還沒有在螞蟻金服普及,而且也沒有明確的時間表。因此,我們在一番調研之後,選擇了兩條腿走路的方式:

  1. 在非k8s環境下,以Sidecar模式先進行少量落地,主要是替換掉原有的多語言客戶端 (拿短期紅利)。
  2. 開發SOFAMesh,集成MOSN到Istio,增加對多種RPC協議的支持,增加對RPC服務模式的兼容(為最終目標做準備 )

在今年6月底的杭州第一屆Service Mesh 線下 meetup 中,我們公布了 SOFAMesh 項目,我當時做了一個演講 大規模微服務架構下的Service Mesh探索之路 ,有興趣的同學可以去回顧一下我們當時的背景/需求/設計方案。

大概在今年九月,我們完成了對非k8s下運行istio的深入調研,得出的結論是要做到這個模式需要非常多的工作。而且,我們對Service Mesh的認知也更加深刻,明確了通過Service Mesh將傳統中間件能力向以k8s為代表的基礎設施層下沉的戰略方向。期間,內部也明確了k8s普及的大方向,因此,綜合這兩個重要輸入,我們選擇放棄繼續在路線2上繼續演進(即 istio on 非k8s)的想法。關於這一點,有興趣的同學可以去閱讀我在10月份QCon大會上的演講內容 長路漫漫踏歌而行:螞蟻金服Service Mesh實踐探索 。

最近,k8s普及的時間表再一次明確提前,螞蟻金服將會在短時間內開啟k8s的大面積普及。因此,我們的演進路線再一次發生變化。目前最新的演進路線將會是這樣:

  1. 當前還沒有開始遷移的應用(處於演進路線圖最下方),將按照路線1的方式進行遷移:先遷移到k8s,再遷移到Sidecar模式的Service Mesh。
  2. 目前部分已經遷移的應用(路線2/4的第一步,非k8s部署的 Sidecar 模式),將沿路線4遷移,和路線1會師。
  3. 由於應用眾多,因此預計到 k8s + Sidecar模式 的遷移工作會持續比較長時間,在此期間,我們會同步完善Istio,和Istio官方一起合作來做到Istio對超大規模部署的支持。
  4. 最後一步,遷移到最終目標(當然這一步的方案依然有很多待定內容,繼續努力)

需要強調的是:這個演進路線針對的是螞蟻金服主站的特殊場景,並不具體普適性。大家可以在理解我們演進路線背後的思路和權衡方式之後,再結合自身的實際情況進行決策。比如,我們在UC落地時,由於UC有完善的k8s支持,而且目前落地的規模沒那麼誇張,因此是直接從”部署在k8s上” + “不是Service Mesh形態”,直接遷移到終態的。預計在金融雲落實時,也會是如此,因為客戶也不會有如此規模。

總結:前面我們介紹了當應用程序向Service Mesh和K8s遷移時的幾種可能的演進路線,分析了各條路線的利弊。並以螞蟻金服主站為例,介紹了我們遷移的背景和演進路線的選擇思路,希望能夠幫助大家更好的理解Service Mesh的落地實踐,以便在未來設計自家的落地方案時能有所參考。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

做到平滑遷移的關鍵

前面給大家介紹了螞蟻金服主站的Service Mesh演進路線,期間談到要做到現有應用的平滑遷移。今天的第二個內容,將給大家介紹平滑遷移做到中的幾個關鍵做法。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

首先,第一個關鍵是盡量保證遷移前後服務間網路互通。

以向k8s遷移為例,在非k8s環境,典型的服務間訪問方式是這樣:

  • 每個服務向註冊中心註冊。
  • 客戶端發起訪問前,通過註冊中心得到目標服務的實例列表信息,如IP地址/端口等

在向k8s遷移的過程中,我們的做法是保證k8s內外網路打通,即服務的IP地址(在k8s中是pod ip)是可以相互直接訪問的。基於這個前提,服務在遷移到k8s的過程中,原有的服務註冊/服務發現/發起請求等邏輯都無需修改,是不是在k8s內,是不是pod ip,對原有服務化體系完全是透明的。

因此,向k8s的遷移可以做到對業務應用非常的平滑,基本感知。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

透明攔截在遷移過程中,可以起到非常關鍵的作用。

以Service-A要訪問Service-B,在應用向Sidecar模式的Service Mesh遷移前後,會有有四種排列組合場景:

  1. Service-A和Service-B都沒有遷移到Serive Mesh:此時請求會直接從Service-A發送到Service-B,稱為直連,這是應用在開始遷移到Service Mesh之前的標準工作方式。
  2. Service-A已經遷移到Service Mesh,Service-B還沒有:此時Service-A發出來的請求,會被劫持,然後發送到和Service-A一起部署的Sidecar(稱為Outbound Sidecar),此時鏈路中只有一個Sidecar,稱為(客戶端)單跳。
  3. Service-B已經遷移到Service Mesh,Service-A還沒有:此時Service-A發出來的請求,在到達Service-B時,會被劫持到和Service-B一起部署的Sidecar(稱為Inbound Sidecar),此時鏈路中也只有一個Sidecar,稱為(服務器端)單跳。
  4. Service-A和Service-B都遷移到Serive Mesh:此時Service-A發出來的請求,會被兩次劫持,分別進入Outbound Sidecar和Inbound Sidecar,此時鏈路中有兩個Sidecar,稱為雙跳。這是Istio的標準工作模式,也是我們遷移完成之後的最終工作模式。

在這四種場景中,所有的網路請求,請求報文都是完全一致的,即不管是否被劫持到Sidecar,對請求報文都沒有影響,也就是對發出請求報文的客戶端和接受請求報文的客戶端都是透明的,完全無感之。

因此,在遷移過程中,可以單個服務逐個遷移,甚至服務的單個實例逐個遷移,而無需修改應用本身。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

在展開第三個關鍵點之前,我們來探討一下:在Service Mesh時代,理想的客戶端應該是什麼樣子?

圖中我們列舉了一個傳統的侵入式框架的客戶端所包含的功能,在侵入式框架中,大部分的功能都是由客戶端做到,因此會包含非常多的功能,如服務發現、負載均衡等基本功能,加密、認證、路由等高級功能。在應用遷移到Service Mesh之後,這些功能都下沉到Service Mesh中。因此,Service Mesh下的客戶端可以進行大幅度的簡化,成為一個新的輕量級客戶端。

對於這個輕量級客戶端,我們希望可以盡可能的做的輕薄通用:做到簡單,不管哪個編程語言都可以做到輕鬆做到,因此跨語言就方便了。而且越簡單之後升級的可能性就會越少,以避免升級客戶端。

那我們來繼續看,這個輕量級客戶端里面最後還能剩下什麼內容?

圖中列出了三個,其中最重要的,也是必不可少的是目標服務的標識,即無論如何簡化,最低限度應該告之要訪問誰吧?然後是序列化,對於RPC類肯定需要提供編解碼功能,不過對於HTTP/REST類很多語言直接內置了標準做到。然後鏈路追蹤,需要做一點工作來傳遞諸如SpanID之類的參數,同樣這塊也有可能通過自動埋點來做到。因此,最理想最單薄的客戶端,可能只保留最後一個信息:目標服務的標示。

在侵入式框架下,目標服務的標示是和服務註冊/服務發現是直接關聯的,這個標示通常都是服務名,通過服務發現機制做到了一個服務名到服務實例的尋址方式。在Service Mesh機制下,由於服務發現機制被下沉到Service Mesh中,因此只要底層Service Mesh能支持,這個目標服務的標示可以不必拘泥於服務名。

那麼,問題來了,對客戶端來說:最簡單,最通用,支持最廣泛的尋址方式是什麼?是DNS!

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

在我們的遷移方案中,我們考慮引入DNS尋址方式。除了前面說的DNS是支持度最好,使用最普遍的尋址方式,在所有的編程語言和平台上都可以支持之外,我們還希望將DNS尋址方式作為未來產品的長期方向:

  • 在SOFAMesh和SOFAMosn中,我們已經基於名為x-protocol的方式做到了DNS通用尋址方式,用來解決Dubbo/HSF/SOFA等傳統SOA服務模型在Service Mesh下的訪問問題 (備註: 具體內容請見我的博客文章 SOFAMesh中的多協議通用解決方案x-protocol介紹系列(1)-DNS通用尋址方案 )
  • 未來在我們的serverless產品中,我們希望可以為運行其上的Function提供DNS尋址支持。
  • 可能還會有其他更加廣泛的使用場景。

因此,在我們的演進過程中,對於客戶端SDK,我們有這樣一個思路:

  • 一方面簡化原有的SDK,去除和Sidecar重復的內容(滿足短期需求)。
  • 另一方面,考慮到必然有一次客戶端SDK的更換過程,那麼我們希望在簡化的同時引入基於DNS的通用尋址方式,以便在未來的後續遷移和功能擴展中可以依托這個機制來做到 (符合長期目標)

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

圖中描述的是在Service Mesh下,客戶端通過域名來指定要訪問的目標服務,然後通過DNS解析機制來串聯底層的服務註冊/DNS記錄更新/透明劫持傳遞原始信息/Sidecar查找路由目標等詳細做到機制。

這里僅做簡單示意,我就不詳細展開了。在接下來的內容中,我的同事,來自UC基礎研發部的 龍軾 同學,將為大家詳細的展開DNS尋址方案的細節做到。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

DNS尋址方案的演進

大家好,我是來自UC基礎研發部的龍軾。 感謝小劍老師給我們介紹了螞蟻和UC共建的Service Mesh的演進路線和做到平滑遷移的關鍵。

接下來由我來向大家分享下做到平滑遷移的關鍵中的DNS尋址方案的演進。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

大家可以看上面的所示的DNS尋址方案的演進,我們先了解下各個服務尋址方案的背景。

從 SOA 的尋址,到 Kubernetes 的尋址,然後再到 Istio 的尋址,最後是我們的 SOFAMesh 的DNS尋址方案。

它們的尋址方案有什麼不同,我們將一一分析它們的細節和總體尋址方案的演進路線。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

現在大家可以先來看下 SOA 架構下基於服務註冊和服務發現的尋址。

我們可以看到圖中的 SOA 其實是單進程多接口的,依賴於 SOA 的服務註冊與服務發現的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

接下來我們看下 Kubernetes 的 DNS 尋址方式,它的尋址方式其實是通過DNS 的。

從圖中我們可以看到部署到K8S 上面的userservice 服務會生成一條DNS記錄指向K8S 的ClusterIP。

我們在 Pod 里面發起請求時通過 DNS 的 SearchDomain 域名補全規則就會從 DNS 里面查詢得到ClusterIP,我們可以看出 Kubernetes 的尋址方案是單進程單接口的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

看完 Kubernetes 的服務發現之後我們繼續來看 Istio 的服務發現。

從圖中我們可以看出之前的流程都和 K8S 一脈相承,不同的地方在於 Istio 里面有個 SideCar 它把ClusterIP 拿到之後根據 ClusterIP 從 VirtualHost 里面匹配到 Rule 規則 轉PO給目標的 Pod 地址。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

最後我們來看下 SOFAMesh 的 DNS 通用尋址方案。

  1. 根據我們之前分析的 SOA 尋址方案和 Kubernetes 尋址方案,我們可以看出如果我們的微服務不經過拆分和改造想上 Service Mesh 的話我們需要支持SOA之前的那種單個Pod 多個接口的。
  2. 從圖中看就是我們需要支持 com.alipay.userservice.interface1, com.alipay.userservice.interface2 這些接口解析到 ClusterIP, 我們知道k8s 中的service 是不支持的。
  3. 那該如何是好,我們只能在DNS 上做文章修改DNS的記錄來做到這一功能。確定了這一方案之後我們來看下我們設計的DNS尋址方案做到細節。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

大家看這張圖:

  1. 我們用 CRD 定義了一個 RPCService 和之前的 Service 有同樣的 selector 的標籤。
  2. 然後用 RPC Service Controller 對 RPCService 做 Watch,當 RPCService 有更新的時候我們就把接口就是上述的 com.alipay.userservice.interface1 的記錄寫入 CoreDNS 里面。
  3. 而 interface 是通過 Pod 里面的 Register Agent 來獲取 Dubbo 里面暴露的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

好的,說完這個方案的細節之後。我們可以看出其實其他的問題都不大,但是要更新DNS的這個我們需要支持。

一開始我們 K8S 集群里面是用 Kube-DNS 來做 DNS 尋址的,但我們看這張 Kube-DNS 的架構圖。

可以看出修改它成本是比較大的,而且所有的DNS 都在同一個域里面,這個風險系數很高。 如果一旦修改錯誤勢必會影響到之前的 k8s 的 service,導致線上的故障。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

  1. 這個時候我們跟蹤到社區的 CoreDNS 項目,我們來看下 CoreDNS 的具體的架構。 它採用作為 Web 服務器 Caddy 的服務器框架,延用了Caddy 中的插件機制,大大的增加了 CoreDNS 的靈活性。
  2. 它的插件機制也特別簡單,把所有的插件註冊進一個Map里面來,在調用的時候從Map拿出他們有共同接口的函數。有興趣的同學可以看下 Caddy 的插件代碼做到。
  3. 它的 DNS 協議庫採用是由 Google 工程師 Meikg 開發的 DNS 庫,他同時也是 SkyDNS 的開發者。
  4. 後端可以採用 UDP/TCP、TLS 或者 gRPC 作為後端數據查詢。上面有個Google工程師用 gRPC 做了一個 CoreDNS 插件的後端數據查詢例子,有興趣的同學可以看下。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

OK,既然 CoreDNS 的 Plugins 這麼強大,我們可不可以用它來做到我們剛才說到的 Renew DNS的機制。 答案很顯然是可以。

我們看下上面的圖,做到CoreDNS 的插件很簡單,只需要繼承上面的接口就可以了。 CoreDNS 官網有具體的教程在教我們怎麼寫一個插件。這個就不具體的展開了。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

  1. 到了我們最關鍵的點了:我們應該怎麼更新我們的DNS。其實這點 CoreDNS 社區里面已經有人提出需求用 REST API 的形式提供更新 DNS 的接口。
  2. 互聯網任務工程小組也早在 rfc2136 定義了標準的 DNS UPDATE。 Google Cloud 和AWS 都有相應的做到。
  3. CoreDNS 社區其實已經把接口做到了,但是後端存儲是基於file 的,數據沒有落地。 螞蟻和UC 這邊擴展了 ETCD 插件的接口,把對應 DNS UPDATE 接口給做到了,做到 DNS 數據寫入ETCD 里面。
  4. 從圖中我們可以看到 rpc.cluster.local 這個域 和 k8s 域 cluster.local 是在不同的插件鏈上的。這樣在k8s域中沒有 dynapirest 插件,我們就不能對k8s域中的DNS進行更新,這樣就把之前Kube-DNS改造之後會對k8s域里面造成影響給去除了,更加的安全。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

我們可以看下 CoreDNS 後端存儲的接口,其實和我們之前對數據操作的接口是沒有什麼差別的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

目前 CoreDNS 的 DynAPI 還在主庫代碼沒合併的狀態。之後 DynAPI 這個項目會獨立成一個插件項目。我們可以看下 CoreDNS 社區的 DynAPI 插件進展。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

OK,我們來看下我們的DynAPI 做到DNS 更新的一個效果。從圖中我們可以看出 record.json 里面的一個域名的更新。通過 DynAPI 我們成功把 record.json 的DNS 記錄給更新進去並且dns正常工作了。到現在我們通過CoreDNS 的插件就把DNS 更新的需求給解決了。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

其實CoreDNS 官網還有許多有趣的插件,可以豐富 CoreDNS 的功能和提升 CoreDNS 的性能。 大家可以看下中間的 autopath 插件,他把我們多次的在 searchdomain 拼湊的 DNS 記錄的查詢在在服務器上給做到了。 避免了多次的 Client 端和 Server 端的數據交互。有興趣的同學可以看下 A-Deep-Dive-into-CoreDNS-2018。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

我們把 CoreDNS 的功能開發完了,上線的話很多人關注它的性能。 我們這邊做了一個簡單的性能測試,可以看出 CoreDNS 和 Bind DNS 這種現在比較通用的DNS的性能還是有點差距的。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

但是,我們通過上面的圖可以看到在一定的QPS 下,CoreDNS 的延時是很低的。 我們可以看到所有的延時都落在4ms 之內。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

為了解決QPS的問題,我們通過 Kubernetes 的 HPA 給 CoreDNS 進行橫向的擴展。

一開始我們只是通過CPU的維度給 CoreDNS 擴展,但發現波動有點大。 之後我們切換成通過QPS的維度來進行擴容。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

CoreDNS 將會在Kubernetes 1.13 之後成為 Kubernetes 的默認的DNS服務。我們將會緊跟社區實施我們的方案並且反饋給社區。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

DNS尋址方案的後續規劃

我們再來看下我們後續的一些規劃。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

可以看到我們的 DynAPI 其實在安全上還是有欠缺的。我們後續會把 HTTP 加強成 HTTPS 協議來增強 DynAPI 的安全性。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

還有如果我們 CoreDNS 的後端變化的更新的 Watch 由於 Watch的範圍過大的話,會返回過多的數據。這樣會影響到 Watch 的性能,CoreOS 在 ETCD3.2 增加了proxy 可以讓我們根據不同的 ETCD KeySpace 去Watch,這樣大大的提高了Watch的性能。

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

最後一個,我們建議在創建 Kubernetes 集群的時候把 idc 的信息給帶進Kubernetes的後綴域名中。這樣我們之後可以通過 kubernetai 插件把不同的 Kubernetes 集群的域名進行整合通過本 IDC 緩存提高跨 IDC DNS 的訪問速度。

總結

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

最後我們總結下,總體方面小劍老師給我們講了螞蟻金服主站 Service Mesh 的漸進式演進路線和做到平滑遷移的幾個關鍵。 具體細節方面我們通過CoreDNS 的單點突破解決了 SOFAMesh 的 DNS 尋址的問題。

感謝大家,希望這次演講能讓大家有所收獲。

視頻回放與資料下載

地址:https://tech.antfin.com/activities/2/review

相關鏈接:

SOFA 文檔: http://www.sofastack.tech/

SOFA: https://github.com/alipay

SOFAMosn:

https://github.com/alipay/sofa-mosn

SOFAMesh:

https://github.com/alipay/sofa-mesh

螞蟻金服Service Mesh 漸進式遷移方案|Service Mesh Meetup 實錄

作者:平生栗子

About 尋夢園
尋夢園是台灣最大的聊天室及交友社群網站。 致力於發展能夠讓會員們彼此互動、盡情分享自我的平台。 擁有數百間不同的聊天室 ,讓您隨時隨地都能找到志同道合的好友!