Service Mesh(服務網格)是雲原生和微服務發展的一個新階段,本文是2018年11月25日(週日)ServiceMesher 社群和螞蟻金服聯合主辦的 Service Mesh Meetup上海站的演講內容,前面一半內容來自螞蟻金服的敖小劍,後一半來自阿里UC的龍軾。
原文地址:www.servicemesher.com/blog/ant-fi…
大家好,今天給大家帶來的演講主題是“螞蟻金服Service Mesh漸進式遷移方案”,給大家介紹一下我們螞蟻金服主站的Service Mesh遷移方案,在稍後的內容中我會給大家解釋什麼是“漸進式”。今天的演講方式有些特殊,將會是兩位講師合作。我是敖小劍,來自螞蟻金服中介軟體團隊,另外一位講師 龍軾 ,來自 UC 基礎研發部。
今天的內容將會有四塊主要內容:
Service Mesh演進路線:介紹螞蟻金服計劃在主站落地Service Mesh的方案,由於涉及到大量的存量應用和超大規模,又要保證遷移過程的平滑,因此我們的落地方案相比社群方案要複雜的多。
實現平滑遷移的關鍵:介紹在整個遷移方案中,為了實現平滑遷移的幾個關鍵做法,然後今天我們將詳細展開其他的一個關鍵點:DNS定址方案。
DNS定址方案的演進:詳細介紹Kubernetes/Istio/SOFAMesh一路演進過來的DNS定址方式
DNS定址方案的後續規劃:介紹我們在DNS定址方案上的後續規劃
前兩塊內容將由我來為大家介紹,後兩塊內容將由我的同事 龍軾 為大家介紹。
在展開內容之前,先看一下背景,Service Mesh在螞蟻金服主站落地的背景:
目標:需要滿足我們對長期目標的認可,具體指服務間通訊走Service Mesh,而且是Istio這種帶完整的控制平面的Service Mesh形態,基礎設施要構建在k8s之上,而應用的形態要向微服務靠攏。
現狀:而現實是存在很多挑戰,首先還有很多應用沒有實現微服務化,而且我們的k8s普及程度也不夠,還有非常多的應用沒有執行在kubernets之上。Istio的成熟程度也稍顯不足,不夠穩定,更大的挑戰的是Istio目前無法原生支援我們螞蟻金服的規模,我們還在試圖對Istio進行改進和擴充套件。最後,在落地時必須考慮的非常現實的一點:現有系統中為數眾多的應用不可能一夜之間全部遷移。
關鍵需求:因此在落地實施時,非常重要的需求是:要實現平滑遷移。簡單說,微服務 + Service Mesh + kubernetes 是我們的目標,但是如何從現有體系出發,向目標平穩和堅實的邁進,必須給出可行的實踐指導。
今天演講的內容,要給大家介紹的就是,在這樣的背景下,我們螞蟻金服選擇的Service Mesh主站落地演進方案。這個方案預期會在2019年初全面鋪開。
主站落地方案的實施原則,這是我們在過去半年的實踐中,總結歸納出來的行為指導:
符合遠期規劃:一定要有清晰的長期目標,明確的知道未來的大方向。避免走彎路,避免浪費投資,理想狀態是計劃中的每一步都可以為下一步奠定堅實的基礎。即使因為某些原因不得已妥協或繞行,也應該清晰的知道後面應該如何迴歸,謝絕中途推倒重來——代價太高,無法承受。
循序漸進:認清現實,如此之大的變革,一定是需要分步進行,不要心存一步登天的幻想,現實可行的方式是小步快跑。將整個過程拆解為若干個大步驟,每一步的工作量和複雜度都控制在一個可以接受的範圍內,以保證每一步都簡單方便,切實可行。
有可操作性:在操作層面上,要有足夠的彈性,即每個步驟中的工作內容,都應該是可以分批進行。以步步為營的方式,逐步擴大戰果,杜絕一刀切。
在接下來的演進路線中,大家將會體會到這三個原則在實際落地時的指導作用。
這個圖的資訊量有點大,描述的是 Service Mesh 和 k8s 落地可能的多種演進路線。
我們先從最下面開始看,這是當前螞蟻金服主站大多數應用的現狀:即應用"部署在非k8s上",應用也"不是Service Mesh形態"。 然後看最上面,這是我們期望的螞蟻金服主站未來的應用終極形態:應用"部署在k8s上",應用也遷移到了"Service Mesh形態"。
這裡有個特別的地方,我們將Service Mesh形態細分為兩種模式:
Sidecar模式:只有Sidecar,沒有控制平面,和外部系統的各種整合都是在Sidecar中直接進行。這是第一代的Service Mesh,Linkerd/Envoy都是如此,華為基於ServiceComb演進而來的mesher,新浪微博的Mesh,包括我們螞蟻金服基於MOSN開發的用於取代多語言客戶端的Mesh方案。
Istio模式:有完善的控制平面,可以提供強大的控制能力,而且從資料平面分離,這是第二代的Service Mesh,典型如Istio和Conkduit/Linkerd 2.0。
之所以將Service Mesh形態細分,是因為我們有著這樣一個特殊背景:目前的原生Istio無法支撐我們螞蟻金服的規模,因此在改進完善Istio之前,我們不得不暫時在Sidecar模式下短暫停留。另外一個原因就是考慮到存量應用的遷移,多一個Sidecar模式作為中間緩衝,會讓整個遷移過程平滑很多。
現在我們來介紹圖中展示的四條演進路線:
左邊的路線1,思路是先將應用遷移k8s部署,再遷移到Service Mesh形態。這條路線的最大好處,是過程中每個階段的絕大多數投資都將最終得以保留,因為符合k8s+service mesh的遠期目標
右邊的路線2,思路是跳過k8s,先遷移到Service Mesh形態,一路演進到Istio模式,然後最後遷移到k8s。
中間的路線3,直接一步到位,這個路線是Istio預設的方式,或者說Istio根本沒有考慮過遷移的問題,預設客戶已經有完善的k8s,然後將改造好的應用直接部署在Istio上。這個路線對於螞蟻金服主站的複雜場景,當然是不現實的。(補充:只是對螞蟻金服主站不合適,對於大多數公司,規模不是那麼巨大,也沒有歷史負擔,也有k8s基礎,完全可行。)
還有一條特別的路線4,走位飄忽,先和路線2一樣遷移到Sidecar模式,然後走迴路線1,上k8s,再在有k8s支援的情況下繼續演進到Istio模式。
下面我們來詳細分析各條演進路線的優劣和實施條件。
演進路線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對螞蟻金服主站落地是不合適的。
演進路線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沒有普及的)特殊時期的選擇。
在對四條可能的演進路線分析完成之後,我們來具體介紹螞蟻金服的最終選擇。
坦言說,在過去半年中,我們的演進路線有幾次搖擺和修訂,今天我們公佈的路線,和過去幾個月中我們通過 meetup/技術大會/部落格文章 等方式透露出來的方式會有一些變化。主要原因是在過去的這半年中,一方面我們對Sercice Mesh的認知更加深入,另一方面是螞蟻金服的k8s背景也在變化。
首先,在今年年初,我們確認Service Mesh大方向時,k8s還沒有在螞蟻金服普及,而且也沒有明確的時間表。因此,我們在一番調研之後,選擇了兩條腿走路的方式:
在非k8s環境下,以Sidecar模式先進行少量落地,主要是替換掉原有的多語言客戶端 (拿短期紅利)
開發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的方式進行遷移:先遷移到k8s,再遷移到Sidecar模式的Service Mesh
目前部分已經遷移的應用(路線2/4的第一步,非k8s部署的 Sidecar 模式),將沿路線4遷移,和路線1會師
由於應用眾多,因此預計到 k8s + Sidecar模式 的遷移工作會持續比較長時間,在此期間,我們會同步完善Istio,和Istio官方一起合作來實現Istio對超大規模部署的支援
最後一步,遷移到最終目標(當然這一步的方案依然有很多待定內容,繼續努力)
需要強調的是:這個演進路線針對的是螞蟻金服主站的特殊場景,並不具體普適性。大家可以在理解我們演進路線背後的思路和權衡方式之後,再結合自身的實際情況進行決策。比如,我們在UC落地時,由於UC有完善的k8s支援,而且目前落地的規模沒那麼誇張,因此是直接從"部署在k8s上" + "不是Service Mesh形態",直接遷移到終態的。預計在金融雲落實時,也會是如此,因為客戶也不會有如此規模。
總結:前面我們介紹了當應用程式向Service Mesh和K8s遷移時的幾種可能的演進路線,分析了各條路線的利弊。並以螞蟻金服主站為例,介紹了我們遷移的背景和演進路線的選擇思路,希望能夠幫助大家更好的理解Service Mesh的落地實踐,以便在未來設計自家的落地方案時能有所參考。
前面給大家介紹了螞蟻金服主站的Service Mesh演進路線,期間談到要實現現有應用的平滑遷移。今天的第二個內容,將給大家介紹平滑遷移實現中的幾個關鍵做法。
首先,第一個關鍵是儘量保證遷移前後服務間網路互通。
以向k8s遷移為例,在非k8s環境,典型的服務間訪問方式是這樣:
每個服務向註冊中心註冊
客戶端發起訪問前,通過註冊中心得到目標服務的例項列表資訊,如IP地址/埠等
在向k8s遷移的過程中,我們的做法是保證k8s內外網路打通,即服務的IP地址(在k8s中是pod ip)是可以相互直接訪問的。基於這個前提,服務在遷移到k8s的過程中,原有的服務註冊/服務發現/發起請求等邏輯都無需修改,是不是在k8s內,是不是pod ip,對原有服務化體系完全是透明的。
因此,向k8s的遷移可以做到對業務應用非常的平滑,基本感知。
透明攔截在遷移過程中,可以起到非常關鍵的作用。
以Service-A要訪問Service-B,在應用向Sidecar模式的Service Mesh遷移前後,會有有四種排列組合場景:
Service-A和Service-B都沒有遷移到Serive Mesh:此時請求會直接從Service-A傳送到Service-B,稱為直連,這是應用在開始遷移到Service Mesh之前的標準工作方式
Service-A已經遷移到Service Mesh,Service-B還沒有:此時Service-A發出來的請求,會被劫持,然後傳送到和Service-A一起部署的Sidecar(稱為Outbound Sidecar),此時鏈路中只有一個Sidecar,稱為(客戶端)單跳
Service-B已經遷移到Service Mesh,Service-A還沒有:此時Service-A發出來的請求,在到達Service-B時,會被劫持到和Service-B一起部署的Sidecar(稱為Inbound Sidecar),此時鏈路中也只有一個Sidecar,稱為(伺服器端)單跳
Service-A和Service-B都遷移到Serive Mesh:此時Service-A發出來的請求,會被兩次劫持,分別進入Outbound Sidecar和Inbound Sidecar,此時鏈路中有兩個Sidecar,稱為雙跳。這是Istio的標準工作模式,也是我們遷移完成之後的最終工作模式。
在這四種場景中,所有的網路請求,請求報文都是完全一致的,即不管是否被劫持到Sidecar,對請求報文都沒有影響,也就是對發出請求報文的客戶端和接受請求報文的客戶端都是透明的,完全無感之。
因此,在遷移過程中,可以單個服務逐個遷移,甚至服務的單個例項逐個遷移,而無需修改應用本身。
在展開第三個關鍵點之前,我們來探討一下:在Service Mesh時代,理想的客戶端應該是什麼樣子?
圖中我們列舉了一個傳統的侵入式框架的客戶端所包含的功能,在侵入式框架中,大部分的功能都是由客戶端實現,因此會包含非常多的功能,如服務發現、負載均衡等基本功能,加密、認證、路由等高階功能。在應用遷移到Service Mesh之後,這些功能都下沉到Service Mesh中。因此,Service Mesh下的客戶端可以進行大幅度的簡化,成為一個新的輕量級客戶端。
對於這個輕量級客戶端,我們希望可以儘可能的做的輕薄通用:實現簡單,不管哪個程式語言都可以做到輕鬆實現,因此跨語言就方便了。而且越簡單之後升級的可能性就會越少,以避免升級客戶端。
那我們來繼續看,這個輕量級客戶端裡面最後還能剩下什麼內容?
圖中列出了三個,其中最重要的,也是必不可少的是目標服務的標識,即無論如何簡化,最低限度應該告之要訪問誰吧?然後是序列化,對於RPC類肯定需要提供編解碼功能,不過對於HTTP/REST類很多語言直接內建了標準實現。然後鏈路追蹤,需要做一點工作來傳遞諸如SpanID之類的引數,同樣這塊也有可能通過自動埋點來實現。因此,最理想最單薄的客戶端,可能只保留最後一個資訊:目標服務的標示。
在侵入式框架下,目標服務的標示是和服務註冊/服務發現是直接關聯的,這個標示通常都是服務名,通過服務發現機制實現了一個服務名到服務例項的定址方式。在Service Mesh機制下,由於服務發現機制被下沉到Service Mesh中,因此只要底層Service Mesh能支援,這個目標服務的標示可以不必拘泥於服務名。
那麼,問題來了,對客戶端來說:最簡單,最通用,支援最廣泛的定址方式是什麼?是DNS!
在我們的遷移方案中,我們考慮引入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下,客戶端通過域名來指定要訪問的目標服務,然後通過DNS解析機制來串聯底層的服務註冊/DNS記錄更新/透明劫持傳遞原始資訊/Sidecar查詢路由目標等詳細實現機制。
這裡僅做簡單示意,我就不詳細展開了。在接下來的內容中,我的同事,來自UC基礎研發部的 龍軾 同學,將為大家詳細的展開DNS定址方案的細節實現。
大家好,我是來自UC基礎研發部的龍軾。 感謝小劍老師給我們介紹了螞蟻和UC共建的Service Mesh的演進路線和實現平滑遷移的關鍵。
接下來由我來向大家分享下實現平滑遷移的關鍵中的DNS定址方案的演進。
大家可以看上面的所示的DNS定址方案的演進,我們先了解下各個服務定址方案的背景。
從 SOA 的定址,到 Kubernetes 的定址,然後再到 Istio 的定址,最後是我們的 SOFAMesh 的DNS定址方案。
它們的定址方案有什麼不同,我們將一一分析它們的細節和總體定址方案的演進路線。
現在大家可以先來看下 SOA 架構下基於服務註冊和服務發現的定址。
我們可以看到圖中的 SOA 其實是單程式多介面的,依賴於 SOA 的服務註冊與服務發現的。
接下來我們看下 Kubernetes 的 DNS 定址方式,它的定址方式其實是通過DNS 的。
從圖中我們可以看到部署到K8S 上面的userservice 服務會生成一條DNS記錄指向K8S 的ClusterIP。
我們在 Pod 裡面發起請求時通過 DNS 的 SearchDomain 域名補全規則就會從 DNS 裡面查詢得到ClusterIP,我們可以看出 Kubernetes 的定址方案是單程式單介面的。
看完 Kubernetes 的服務發現之後我們繼續來看 Istio 的服務發現。
從圖中我們可以看出之前的流程都和 K8S 一脈相承,不同的地方在於 Istio 裡面有個 SideCar 它把ClusterIP 拿到之後根據 ClusterIP 從 VirtualHost 裡面匹配到 Rule 規則 轉發給目標的 Pod 地址。
最後我們來看下 SOFAMesh 的 DNS 通用定址方案。
根據我們之前分析的 SOA 定址方案和 Kubernetes 定址方案,我們可以看出如果我們的微服務不經過拆分和改造想上 Service Mesh 的話我們需要支援SOA之前的那種單個Pod 多個介面的。
從圖中看就是我們需要支援
com.alipay.userservice.interface1
,com.alipay.userservice.interface2
這些介面解析到 ClusterIP, 我們知道k8s 中的service 是不支援的。那該如何是好,我們只能在DNS 上做文章修改DNS的記錄來實現這一功能。確定了這一方案之後我們來看下我們設計的DNS定址方案實現細節。
大家看這張圖:
我們用 CRD 定義了一個 RPCService 和之前的 Service 有同樣的 selector 的標籤。
然後用 RPC Service Controller 對 RPCService 做 Watch,當 RPCService 有更新的時候我們就把介面就是上述的
com.alipay.userservice.interface1
的記錄寫入 CoreDNS 裡面而 interface 是通過 Pod 裡面的 Register Agent 來獲取 Dubbo 裡面暴露的。
好的,說完這個方案的細節之後。我們可以看出其實其他的問題都不大,但是要更新DNS的這個我們需要支援。
一開始我們 K8S 叢集裡面是用 Kube-DNS 來做 DNS 定址的,但我們看這張 Kube-DNS 的架構圖。
可以看出修改它成本是比較大的,而且所有的DNS 都在同一個域裡面,這個風險係數很高。 如果一旦修改錯誤勢必會影響到之前的 k8s 的 service,導致線上的故障。
這個時候我們跟蹤到社群的 CoreDNS 專案,我們來看下 CoreDNS 的具體的架構。 它採用作為 Web 伺服器 Caddy 的伺服器框架,延用了Caddy 中的外掛機制,大大的增加了 CoreDNS 的靈活性。
它的外掛機制也特別簡單,把所有的外掛註冊進一個Map裡面來,在呼叫的時候從Map拿出他們有共同介面的函式。有興趣的同學可以看下 Caddy 的外掛程式碼實現。
它的 DNS 協議庫採用是由 Google 工程師 Meikg 開發的 DNS 庫,他同時也是 SkyDNS 的開發者。
後端可以採用 UDP/TCP、TLS 或者 gRPC 作為後端資料查詢。上面有個Google工程師用 gRPC 做了一個 CoreDNS 外掛的後端資料查詢例子,有興趣的同學可以看下。
OK,既然 CoreDNS 的 Plugins 這麼強大,我們可不可以用它來實現我們剛才說到的 Renew DNS的機制。 答案很顯然是可以。
我們看下上面的圖,實現CoreDNS 的外掛很簡單,只需要繼承上面的介面就可以了。 CoreDNS 官網有具體的教程在教我們怎麼寫一個外掛。這個就不具體的展開了。
到了我們最關鍵的點了:我們應該怎麼更新我們的DNS。其實這點 CoreDNS 社群裡面已經有人提出需求用 REST API 的形式提供更新 DNS 的介面。
網際網路任務工程小組也早在 rfc2136 定義了標準的 DNS UPDATE。 Google Cloud 和AWS 都有相應的實現。
CoreDNS 社群其實已經把介面實現了,但是後端儲存是基於file 的,資料沒有落地。 螞蟻和UC 這邊擴充套件了 ETCD 外掛的介面,把對應 DNS UPDATE 介面給實現了,實現 DNS 資料寫入ETCD 裡面。
從圖中我們可以看到
rpc.cluster.local
這個域 和 k8s 域 cluster.local 是在不同的外掛鏈上的。 這樣在k8s域中沒有 dynapirest 外掛,我們就不能對k8s域中的DNS進行更新,這樣就把之前Kube-DNS改造之後會對k8s域裡面造成影響給去除了,更加的安全。
我們可以看下 CoreDNS 後端儲存的介面,其實和我們之前對資料操作的介面是沒有什麼差別的。
目前 CoreDNS 的 DynAPI 還在主庫程式碼沒合併的狀態。之後 DynAPI 這個專案會獨立成一個外掛專案。我們可以看下 CoreDNS 社群的 DynAPI 外掛進展。
OK,我們來看下我們的DynAPI 實現DNS 更新的一個效果。從圖中我們可以看出 record.json 裡面的一個域名的更新。通過 DynAPI 我們成功把 record.json 的DNS 記錄給更新進去並且dns正常工作了。到現在我們通過CoreDNS 的外掛就把DNS 更新的需求給解決了。
其實CoreDNS 官網還有許多有趣的外掛,可以豐富 CoreDNS 的功能和提升 CoreDNS 的效能。 大家可以看下中間的 autopath 外掛,他把我們多次的在 searchdomain 拼湊的 DNS 記錄的查詢在在伺服器上給實現了。 避免了多次的 Client 端和 Server 端的資料互動。有興趣的同學可以看下 A-Deep-Dive-into-CoreDNS-2018。
我們把 CoreDNS 的功能開發完了,上線的話很多人關注它的效能。 我們這邊做了一個簡單的效能測試,可以看出 CoreDNS 和 Bind DNS 這種現在比較通用的DNS的效能還是有點差距的。
但是,我們通過上面的圖可以看到在一定的QPS 下,CoreDNS 的延時是很低的。 我們可以看到所有的延時都落在4ms 之內。
為了解決QPS的問題,我們通過 Kubernetes 的 HPA 給 CoreDNS 進行橫向的擴充套件。
一開始我們只是通過CPU的維度給 CoreDNS 擴充套件,但發現波動有點大。 之後我們切換成通過QPS的維度來進行擴容。
CoreDNS 將會在Kubernetes 1.13 之後成為 Kubernetes 的預設的DNS服務。我們將會緊跟社群實施我們的方案並且反饋給社群。
我們再來看下我們後續的一些規劃。
可以看到我們的 DynAPI 其實在安全上還是有欠缺的。我們後續會把 HTTP 加強成 HTTPS 協議來增強 DynAPI 的安全性。
還有如果我們 CoreDNS 的後端變化的更新的 Watch 由於 Watch的範圍過大的話,會返回過多的資料。這樣會影響到 Watch 的效能,CoreOS 在 ETCD3.2 增加了proxy 可以讓我們根據不同的 ETCD KeySpace 去Watch,這樣大大的提高了Watch的效能。
最後一個,我們建議在建立 Kubernetes 叢集的時候把 idc 的資訊給帶進Kubernetes的字尾域名中。這樣我們之後可以通過 kubernetai 外掛把不同的 Kubernetes 叢集的域名進行整合通過本 IDC 快取提高跨 IDC DNS 的訪問速度。
最後我們總結下,總體方面小劍老師給我們講了螞蟻金服主站 Service Mesh 的漸進式演進路線和實現平滑遷移的幾個關鍵。 具體細節方面我們通過CoreDNS 的單點突破解決了 SOFAMesh 的 DNS 定址的問題。
感謝大家,希望這次演講能讓大家有所收穫。