隨著公司產品的微服務化,安裝包數量翻倍增長,運維工作更加困難,研發和運維之間的矛盾更加突出,所以我們需要一套DevOps平臺解決這些問題,最後我們選擇了圍繞Docker和Kubernetes來構建這套平臺。
先講一下背景,國信之前的軟體部署方式是找臺機器,把war包或者jar包往機器上一扔,啟動就可以了,所有功能都在一個包裡面,模組之間相互耦合,導致新功能開發上線週期很長,客戶的需求得不到及時滿足。
所以我們把我們的應用微服務化改造,微服務化以後,原來一個應用現在變成了十幾個,每個應用功能相對獨立,開發人員需要瞭解的東西變少,開發新功能也比以前簡單了;但是軟體部署運維變得困難了,原來一個軟體包,現在成了十幾個。瞭解過DevOps的同學一定知道,開發和運維之間有一道牆,現在這道牆更高了。
所以我們希望有一款產品能解決我們這些痛點,最後我們把標的鎖定在Docker和Kubernetes上,我們希望基於這個平臺來實現DevOps的部分流程,來減輕部署運維的負擔,同時能提高我們的資源利用率。
最後我們制定了下麵這樣一個架構:
這張圖的最左邊是我們控制檯,叫BCM,使用者所有的操作都在BCM的介面上面完成,包括映象的構建,服務的釋出、升級等,這種介面的東西各公司根據業務和服務物件不同會有所不同,但是主要功能都差不多,所以不展開說了,後面會貼幾張介面。
我們先說最核心的Kubernetes部分,因為所有工作都是圍繞著Kubernetes展開的。
雲平臺的主體基於Kubernetes+Docker構建;透過KubeDNS來為叢集內的應用程式提供域名解析。
透過Heapster收集效能資訊,寫入InfluxDB,然後是BCM讀取InfluxDB資訊進行展示,我們沒有使用Grafana,主要是考慮到我們的平臺是多租戶的,不同的租戶只能看到自己系統的效能指標;而且我們透過對Kubelet和Heapster的修改,增加了對容器內應用的執行緒數和socket連線數的監控,為什麼要增加?因為我們在使用過程中發現有些應用程式碼質量不高,亂用執行緒,有的檔案控制代碼開啟後忘記關閉,導致執行一段時間後連線資料庫失敗,所以我們增加了這兩項監控,當然嚴格執行程式碼質量檢查和review才是更重要的。
大家也看到我們使用了Prometheus,我們主要使用了Prometheus對CPU和記憶體使用率進行告警,同時對Prometheus和Alertmanager增加了配置介面,在應用部署時,把閾值配置下去,同時多載Prometheus的配置,完成監控功能。
我們使用Fluent來收集容器的日誌,寫入Elasticsearch,透過Kibana進行檢索。同時BCM的Web介面上可以檢視實時日誌,這本來是個小功能,但是開發過程也是一波三折,開始我們使用了Kubernetes的API進行日誌獲取,當日誌檔案很大的時候,發現讀取很慢,接著我們又修改成透過Docker的API獲取,但是還是很慢。有時候我們只想檢視一個特定時間段的日誌,這個日誌量應該不會太大,應該很快才對。
於是我們查看了Docker原始碼,發現有兩點需要最佳化,第一是讀取緩衝區,太小了,只有1KB;第二就是從第一條日誌進行讀取,反序列後進行時間比較,看看是否在時間段內,其實Docker不支援結束時間。
針對第一點,修改方法很簡單,增大一下讀取緩衝區就可以了;第二點,修改策略是把日誌分成多個檔案,並且記錄每個檔案的開始日誌時間和結束日誌時間,透過查詢記錄資訊,定位到第一個需要讀取的日誌檔案和最後一個需要讀取的檔案,減少不必要的IO。
下麵我們再說一下我們的服務發現:
我們使用了Nginx來做反向代理,同時我們開發了KubeNg這樣一個後臺程式,為每個Nginx伺服器配置一個KubeNg,KubeNg透過kube-ApiServer實時監控服務的變化,更新Nginx的配置檔案,reload nginx配置。kubeNg是一個後臺程式,沒有介面,生成的Nginx配置都是固定格式的,有些使用者對自己應用程式的Nginx配置有特殊的要求,需要修改,我們又沒有介面來修改,這不行啊,所以我們又開發了一個NgFront前端程式,NgFront滿足下麵幾點要求:
-
透過NgFront可以管理多套Nginx叢集,因為有些租戶公用一套Nginx,有些租戶單獨使用一套Nginx。
-
可以修改抓取到的配置,解決租戶對配置有特殊的要求。
-
可以增加沒有使用容器進行部署的服務的反向代理,因為不是所有服務都會使用容器進行部署,起碼剛開始不會,但是這些服務還想共用容器的Nginx,當然運維人員可以登入到每臺Nginx機器上進行配置,但是這樣很容易出錯,直接在介面上面編輯完成,下發到所有機器就可以了。
-
Reload之前進行配置檔案語法檢查。
-
可以下載配置檔案,有時候會有運維人員繞過NgFront進行操作,導致Nginx叢集內各節點的配置不一致,有些使用者可以正常訪問,有些不能正常訪問,取決於LVS把使用者的請求負載均衡到哪臺Nginx上面了,所以出現這種情況的時候,我們點選下載,用文字對比工具對比一下,很快就能發現問題。
下麵我們再說說ttyEntry:
這個主要是解決使用者除錯方便的需求。使用者在剛開始使用容器的時候,碰到最多的問題就是配置檔案忘記修改了,導致系統啟動失敗。使用者需要重新上傳個jar包到BCM平臺,進行映象構建,所以他們需要有一個環境像使用虛擬機器一樣,可以使用vi進行編輯,修改完成後,執行java –jar進行測試,如果正常,直接打包成映象,推送到倉庫。
BCM使用了xterm來做了一個Web版的終端,TtyEntry主要功能就是把xterm發過來的請求轉發到容器內部。
下麵再說說Pinpoint功能:
這個是一個很贊的工具,在不需要修改程式碼的情況下,可以給出應用之間的呼叫關係和花費的時間,而且效能損失很小。
下麵是Pinpoint的架構圖,我們把紅色框中的Pinpoint Agent做到了容器內,透過BCM介面上的開關控制是否開啟監控。
精華也在Pinpoint Agent,Agent會在我們應用程式的class載入的時候,進行JVM虛擬機器程式碼的註入,在class執行的時候採集執行時間傳送給Collector,後面的HBase就是儲存, Web UI就是展示。
深入的原理還是要看Google的論文,Pinpoint是根據Google的Dapper論文研發的。
再回到我們剛開始的整體框架圖,裡面有個Ceph,Ceph用來提供高效能的網路儲存。我們的應用程式不全是無狀態的,有很多應用程式需要使用者上傳指令碼、說明檔案等,這些東西顯然不能儲存在容器內部的儲存上。
大家知道Docker容器重啟後,裡面儲存的資料就會丟失,所以我們就把Ceph掛載到容器內部,把這些需要持久化的東西儲存到Ceph,即使pod被重新排程到其他節點,儲存在Ceph裡面的檔案也不會丟失。另外Ceph的塊儲存也可以為我們的MySQL、Redis等的容器化提供儲存。
我們還有一部分沒有介紹,就是下麵這塊:
這其實就是個簡配的DevOps,之所以做一個簡配版,主要是考慮到兩方面:1. 實現簡單;2. 推廣簡單。一個工具一旦複雜了,就很難推廣落地,所以我們前期先做一最簡單的,先讓大家上船,後面才好往下走。
我們開發了一個持續整合工具SheRa,就是動畫片裡面的“希瑞請賜予我力量吧”的希瑞。SheRa只是一個後臺服務,提供RESTful的介面,BCM實現配置頁面。下麵是介面:
介面配置Git的地址、Maven編譯命令,Sonar程式碼質量檢查是可選的配置,如果選擇了,最後生成的映象就有一個相應的質量標簽,最後是Dockerfile,我們的shera自帶了幾個工具,如果最後生成的映象有問題,可以把shera自帶的工具打包進去,協助進行除錯。
比如,連線MySQL不成功,可以把MySQL客戶端打包到映象內,透過SSH進入映象,進行連線測試。因為剛開始使用容器,研發很容易把屎盆子扣在容器頭上,我們可以透過這些工具有理有據的告訴他們,資料庫連線沒有問題,你們是不是打包配置錯了JDBC。
下麵是配置完成,編譯後的介面:
點選專案名稱,進入詳情:
點選快速部署按鈕,進行部署:
Q:請問灰度釋出如何實現的?
Q:Pinpoint是Tomcat啟動時候載入的,不重啟應用的情況下,如何控制Pinpoint開關?
Q:請問掛在的Ceph儲存的方式是什麼,塊還是檔案系統?
Q:有沒有把MySQL或者Redis之類的中介軟體放入容器中執行,如果是如何除錯,如果沒有,如何實現彈性擴容?
Q:請問Ceph是如何管理的,申請和開通掛載都是自動的嗎?用的Ceph RBD嗎?
Q:使用Ceph承載有狀態服務的資料持久化有遇到什麼坑嗎?
Q:請問這個系統用了多少人多久完成的?
Q:請問這套架構,從規劃到實施到推廣完成用了多久?
本次培訓包含:Kubernetes核心概念;Kubernetes叢集的安裝配置、運維管理、架構規劃;Kubernetes元件、監控、網路;針對於Kubernetes API介面的二次開發;DevOps基本理念;Docker的企業級應用與運維等,點選識別下方二維碼加微信好友瞭解具體培訓內容。