天天看點

微服務運作指南——For Cattle

站在微服務的角度看容器的基礎設施服務可以分為三層:

微服務基礎層

微服務建構層

微服務通路層

<a href="http://s5.51cto.com/wyfs02/M02/8D/5F/wKioL1iadrWAOUKkAADux1ekNrY143.jpg" target="_blank"></a>

Rancher的服務發現就是基于rancher-dns來實作,建立的stack&amp;service都會生成相應的DNS記錄,使用者可以通過相應的規則進行通路,這樣在微服務之間就可以無需知曉各自的IP位址,直接用服務名進行連接配接即可。

微服務基礎層主要是為容器提供計算、存儲、網絡等基礎資源。主機計算資源主要是對docker-machine封裝來提供相關服務;容器存儲通過Convoy元件來接入,目前對NFS協定的存儲适配性最佳;容器之間的網絡通過rancher-net元件實作,目前支援ipsec overlay,在Rancher1.2版本會支援CNI标準的網絡插件。

微服務建構層,除了有微服務本身主體程式,還需要有一些額外的輔助工具來完善對應微服務的架構體系。rancher-dns來實作服務發現機制;rancher-metadata可以靈活動态向微服務所在容器中注入一些配置資料;healthcheck來保證微服務的高可用;同時我們還需要有微服務打包的工具,保證微服務可以在任意環境拉起運作。

微服務通路層,目前服務對外暴露通路主要以DNS綁定或是負載均衡VIP方式。Rancher提供external-dns、external-lb架構可以讓進階使用者hack自身的場景需求,external-dns除了支援公共的DNS服務(如route53),還支援内部DNS伺服器(如bind9),而external-lb目前支援F5裝置。除此之外,Rancher内置的負載均衡是基于Haproxy實作的,支援L4-L7。

本次分享,我将會以概念介紹原理講解并穿插一些實際案例這樣的方式進行分享。

<a href="http://s5.51cto.com/wyfs02/M00/8D/62/wKiom1iadsmCJZARAAC3wDwPOfM211.jpg" target="_blank"></a>

Rancher的中繼資料服務rancher-metadata靈活性非常大,比較複雜的微服務架構可以通過metadata實作一定程度的解耦,尤其是confd+metadata會有意想不到妙用,這部分内容可以參考 http://niusmallnan.github.io/_build/html/_templates/rancher/confd_metadata.html

Rancher的healthcheck基于Haproxy實作,支援TCP/HTTP,當unhealthy觸發時按照預先設定的政策執行:

什麼也不做

按照scale的容器數量重建

保證至少x個healthy的容器數量

<a href="http://s1.51cto.com/wyfs02/M02/8D/5F/wKioL1iadx-xanPvAARpX4-Ln5g473.jpg" target="_blank"></a>

當針對某個service建立healthcheck政策後,service中容器所在的agent節點上會啟動Haproxy服務,同時把healthcheck的配置轉化為Haproxy的配置。如圖中所示添加了backend,其對應的ip就是container的ip。此外還要将Haproxy的stats scket暴露出來,以便讀取backend的狀态資訊。

<a href="http://s5.51cto.com/wyfs02/M02/8D/62/wKiom1iad9bR9AaoAAlS6yrdTNU130.jpg" target="_blank"></a>

我們可以在外部程式中與Haproxy sock通信,可以擷取相關backend的狀态資訊,由于我們在Haproxy中設定check機制,是以backend的狀态是會自動更新的。

<a href="http://s4.51cto.com/wyfs02/M02/8D/5F/wKioL1iad-3y6WKEAALb9vrUb3w791.jpg" target="_blank"></a>

Rancher Agent上運作的host-api元件通過Haproxy sock來讀取backend狀态資訊,同時通過rancher event機制把狀态資訊push給rancher-server,rancher-server根據之前設定的healthcheck政策,來控制相關的rancher agent執行container recreate操作。

<a href="http://s4.51cto.com/wyfs02/M00/8D/62/wKiom1iaeAKhy2krAAVRyLWxpcU112.jpg" target="_blank"></a>

如果微服務本身是自帶服務端口(TCP/HTTP),那麼healthcheck規則很好設定,隻要正常填寫表單項就可以。但實際應用中有些微服務并不會有端口暴露,它可能隻是一個與DB互動的程式,這時我們會考慮讓服務本身不要有大的代碼改造,是以就需要用一些小工具來輔助一下。

<a href="http://s2.51cto.com/wyfs02/M00/8D/62/wKiom1iaeBXR9HvtAAFaJpj_Xt0375.jpg" target="_blank"></a>

微服務的通路入口,除了我們熟知的LB方式,還可以通過綁定DNS來實作,尤其是在私有雲場景下,内部DNS的使用其實比單純使用LB暴露IP+Port方式更加簡潔,因為這樣無需考慮微服務的容器漂移導緻的服務IP出現變化。

<a href="http://s2.51cto.com/wyfs02/M00/8D/5F/wKioL1iaeCuClADTAAQxlJGQ5LE266.jpg" target="_blank"></a>

Rancher提供了一個external-dns架構 https://github.com/rancher/external-dns,它可以實作service的服務位址轉換成DNS的記錄。

<a href="http://s4.51cto.com/wyfs02/M01/8D/5F/wKioL1iaeD-S3zFvAAGBYSXcbe8921.jpg" target="_blank"></a>

私有雲場景中,很多行業使用者在内部都使用F5硬體負載均衡來暴露服務通路位址。微服務的改造我們盡量控制在程式架構層面,而原有的網絡結構盡量不要改變,那麼就會引來一個微服務場景如何整合F5裝置的問題。

<a href="http://s2.51cto.com/wyfs02/M00/8D/5F/wKioL1iaeF3gg9oXAAc8twE-NPE441.jpg" target="_blank"></a>

我們以一個應用場景為例,生産環境系統中有4個微服務暴露端口分别是9070、9071、9072、9073,出于容災恢複的考慮需要部署兩套環境主環境和備環境,每個環境三台主機,所有的資料庫層均放在非容器環境中,所有服務最終通過F5來暴露通路。

<a href="http://s1.51cto.com/wyfs02/M01/8D/5F/wKioL1iaeHSSygPiAAOtKkcGlns106.jpg" target="_blank"></a>

基于Rancher來實作這種應用場景:建立兩個environment分屬主環境和備環境,由于是不同的ENV,是以這兩個環境是從計算存儲網絡層面都是隔離的。每個環境中建立一個stack,stack下建立4個service,service加上global=true的label,保證每台host上都運作該service,同時通過portmap把service的服務端口直接暴露在host上,外部的F5裝置則将VIP配置到這些HostIP+Port上。

<a href="http://s2.51cto.com/wyfs02/M02/8D/5F/wKioL1iaeIuwsFntAAN-vmbK2XU831.jpg" target="_blank"></a>

關鍵的F5設定,我們要考慮最好能夠動态設定。Rancher提供了一個external-lb架構 https://github.com/rancher/external-lb來解決此問題,F5的驅動亦位列其中,同樣也是通過rancher-metadata元件來擷取微服務的IP+Port資訊。

<a href="http://s5.51cto.com/wyfs02/M00/8D/62/wKiom1iaeJ6QboV7AAFEhwdgKGo226.jpg" target="_blank"></a>

浮動IP本是Iaas的産物,而Caas仍處在不斷演變的過程中,企業内部的網絡結構仍然需要浮動IP的機制。最主要的場景就是防火牆的規則設定,通常其規則都是針對某個IP,而這個IP就意味着無論後端的服務怎麼變換,它要求IP是不能變化的,否則就要不停的修改防火牆規則,這是企業運維人員最無法接受的。

本質上我們需要解決微服務相關的容器發生漂移之後,其對外暴露的IP仍然保持不變。

Rancher的合作夥伴睿雲智合提出過一個浮動IP的解決方案,是一個很不錯的思路。

當然我們也可以利用Cattle自有機制來變通地搞定這個問題。

<a href="http://s2.51cto.com/wyfs02/M00/8D/5F/wKioL1iaeLzgxBkWAATq_hmjGPw801.jpg" target="_blank"></a>

微服務的通路入口使用内置的rancher-lb方式,可以通過label scheduling方式,讓rancher-lb的容器隻落在固定主機上,相關的防火牆隻要配置固定的主機IP即可。

<a href="http://s4.51cto.com/wyfs02/M01/8D/62/wKiom1iaeNOzDqRiAAFT5xHiHAs878.jpg" target="_blank"></a>

最後,我們來一起看一下,比較合适的通用的微服務部署結構。

<a href="http://s2.51cto.com/wyfs02/M01/8D/5F/wKioL1iaeOzgnTIZAAb9dwe0Y-Q561.jpg" target="_blank"></a>

這裡面使用sidekick容器來分離主服務的功能,配置檔案和日志分别由不同的容器來處理,同時保證整體性,可以完整擴容和克隆。配置檔案統一放在 convoy連接配接的NFS存儲中,保證配置檔案的一緻性。logging容器會把日志統一發送到ELK日志系統中,便于集中查詢和管理。保證服務的可用性,healthcheck必不可少。外部則使用内置的Rancher LB來暴露通路。

Q &amp; A

Q:convoy插件的現在有支援ceph或者gluster的catalog麼?

A:gluster的catalog 之前有,但是一直有些問題,現在已經被移除了。convoy目前還不支援ceph。

Q:最後一個架構裡面,是把日志存到一個volume,然後應用和日志服務,同時挂載的意思麼?

A:日志就是通過logging容器發送到ELK中收集起來。

Q:直接用log插件發的麼?

A:log driver隻能把标準輸入輸出發送出去,而圖中的架構更适合傳統的寫日志檔案形式,把日志檔案的内容發送到elk中。

Q:具體的操作是不是日志存在一個sidekick 容易中,讓後讓logging容器來解析和發送?

A:是這樣的。

Q:這樣這個volume 需要mount 本地目錄上去麼?還是就已一個container的形式存在?

A:一個container足矣。

Q:現在convoy是不是暫時沒有其他方案把一個叢集的本地host的磁盤利用起來?

A:Rancher有一個longhorn是你說的場景,還在疊代中。

本文轉自 RancherLabs 51CTO部落格,原文連結:http://blog.51cto.com/12462495/1895934