AI獨角獸商湯科技的內部服務容器化歷程

本文由阿爾曼,商湯科技運維工程師於4月26日晚在Rancher微信羣所作的技術分享整理而成。商湯科技是專一於計算機視覺領域的AI公司。本次分享結合了容器平臺團隊幫助公司業務/內部服務容器化歷程,介紹商湯科技在容器化歷程中使用的工具、擁有的最佳實踐及值得分享的經驗教訓。java

搜索微信號RancherLabsChina,或文末掃碼,添加Rancher小助手爲好友,可加入官方技術交流羣,實時參加下一次分享~node

內容目錄

● 背景python

● 需求分析與技術選型mysql

● 容器鏡像sql

● 監控報警docker

● 可靠性保障編程

● 總結json

背 景

商湯科技是一家計算機視覺領域的AI創業公司,公司內會有一些業務須要雲端API支持,一些客戶也會經過公網調用這些所謂SaaS服務。整體來說,雲API的架構比較簡單,另外因爲公司成立不久,歷史包袱要輕許多,不少業務在設計之初就有相似微服務的架構,比較適合經過容器化來適配其部署較繁複的問題。ubuntu

公司各個業務線相對獨立,在組織上,體如今人員,績效及彙報關係的差別;在技術上體如今編程語言,框架及技術架構的獨自演進,而服務的部署上線和後續維護的工做,則劃歸於運維部門。這種獨立性、差別性所加大的運維複雜度須要獲得收斂。swift

咱們遇到的問題不是新問題,業界也是有很多應對的工具和方法論,但在早期,咱們對運維工具的複雜性增加仍是保持了必定的剋制:ssh + bash script扛過了早期的一段時光,ansible也獲得過數月的應用,但現實所迫,咱們最終仍是投向了Docker的懷抱。

Docker是革命性的,乾淨利落的UX俘獲了技術人員的芳心,咱們當時所處的時期,容器編排的大戰則正處於Docker Swarm mode發佈的階段,而咱們須要尋找那種工具,要既能應對日益增加的運維複雜度,也能把運維工程師從單調、重複、壓力大的發佈中解放出來。

Rancher是咱們在HackerNews上的評論上看到的,其簡單易用性讓咱們看到了生產環境部署容器化應用的曙光,可是要真正能放心地在生產環境使用容器,不「翻車」,仍是有很多工做要作。因爲篇幅的緣由,事無鉅細的描述是不現實的。我接下來首先介紹咱們當時的需求分析和技術選型,再談談幾個重要的組成部分如容器鏡像、監控報警和可靠性保障。

輸入圖片說明

需求分析與技術選型

暫時拋開容器/容器編排/微服務這些時髦的詞在一邊,對於咱們當時的狀況,這套新的運維工具須要三個特性才能算成功:開發友好、操做可控及易運維。

開發友好

能把應用打包的工做推給開發來作,來消滅本身打包/編譯如java/ruby/python代碼的工做,但又要保證開發打出的包在生產環境至少要能運行,因此怎麼能讓開發人員方便正確地打出發佈包,後者又能自動流轉到生產環境是關鍵。長話短說,咱們採起的是Docker + Harbor的方式,由開發人員構建容器鏡像,經過LDAP認證推送到公司內部基於Harbor的容器鏡像站,再經過Harbor的replication機制,自動將內部鏡像同步到生產環境的鏡像站,具體實現可參考接下來的容器鏡像一節。

操做可控

能讓開發人員參與到服務發佈的工做中來,因爲業務線迥異的業務場景/技術棧/架構,使得只靠運維人員來解決發佈時出現的代碼相關問題是勉爲其難的,因此須要可以讓開發人員在受控的情境下,參與到服務平常的發佈工做中來,而這就須要像其提供一些受限可審計且易用的接口,WebUI+Webhook就是比較靈活的方案。這方面,Rancher提供的功能符合需求。

易運維

運維複雜度實話說是咱們關注的核心,畢竟容器化是運維部門爲適應複雜度與日俱增而發起的,屁股決定腦殼。考慮到自己容器的黑盒性和穩定性欠佳的問題,再加上真正把容器技術搞明白的人寥寥無幾,能平穩落地的容器化運維在咱們這裏體現爲三個需求:多租戶支持,穩定且出了事能知道,故障切換成本低。多租戶是支持多個並行業務線的必要項;容器出問題的狀況太多,線上環境以操做系統鏡像的方式限定每臺機器Docker和內核版本;因爲傳統監控報警工具在容器化環境捉襟見肘,須要一整套新的監控報警解決方案;沒人有把握能現場調試全部容器問題(如跨主機容器網絡不通/掛載點泄漏/dockerd卡死/基礎組件容器起不來),須要藍綠部署的出故障後能馬上切換,維護可靠與可控感對於一個新系統相當重要。

技術架構圖

總結一下,Rancher, Harbor, Prometheus/Alertmanager爲主的開源系統組合能夠基本知足容器管理的大部分需求,整體架構以下圖

輸入圖片說明

容器鏡像

容器鏡像服務是公司級別的IT基礎設施,在各個辦公區互聯帶寬有限的物理限制下,須要給分散在多個地理位置的用戶以一致、方便、快速的使用體驗。咱們主要使用了Vmware開源的Harbor工具來搭建容器鏡像服務,雖然Harbor解決了如認證、同步等問題,但Harbor不是這個問題的銀色子彈,仍是須要作一些工做來使鏡像服務有比較好的用戶體驗。這種體驗咱們以Google Container Registry爲例來展示。

做爲Google的開放容器鏡像服務,全球各地的用戶都會以同一個域名gcr.io推拉鏡像docker push gcr.io/my_repo/my_image:my_tag,但其實用戶推拉鏡像的請求,因爲來源地理位置不一樣,可能會被GeoDNS分發在不一樣的Google數據中心上,這些數據中心之間有高速網絡鏈接,各類應用包括GCR會經過網絡同步數據。這樣的方法既給用戶一致的使用體驗,即全部人都是經過gcr.io的域名推拉鏡像,又由於每一個人都是同本身地理位置近的數據中心交互而不會太「卡」,而且因爲Google Container Registry底層存儲的跨數據中心在不斷高速同步鏡像(得益於Google優異的IT基礎設施),異國他鄉的別人也能感受很快地拉取咱們推送的鏡像(鏡像「推」和「拉」的異步性是前提條件)。

花篇幅介紹Google Container Registry的目的是,用戶體驗對用戶接受度相當重要,然後者每每是一個新服務存活的關鍵,即在公司內部提供相似GCR通常的體驗,是咱們容器鏡像服務爲了成功落地而想接近的產品觀感。爲了達到這種觀感,須要介紹兩個核心的功能,開發/生產鏡像自動同步,鏡像跨辦公區同步。另外,雖然有點超出鏡像服務自己,但因爲特殊的國情和使用關聯性,國外鏡像(DockerHub, GCR, Quay)拉取慢也是影響容器鏡像服務使用體驗的關鍵一環,鏡像加速服務也是須要的。

開發/生產鏡像自動同步

因爲開發環境(公司私網),生產環境(公網)的安全性和使用場景的差別,咱們部署了兩套鏡像服務,內網的爲了方便開發人員使用是基於LDAP認證,而公網的則作了多種安全措施來限制訪問。但這帶來的問題是如何方便地向生產環境傳遞鏡像,即開發人員在內網打出的鏡像須要能自動地同步到生產環境。

咱們利用了Harbor的replication功能,只對生產環境須要的項目才手動啓用了replication,經過這種方式只需初次上線時候的配置,後續開發的鏡像推送就會有內網Harbor自動同步到公網的Harbor上,不須要人工操做。

鏡像跨辦公區同步

因爲公司在多地有辦公區,同一個team的成員也會有地理位置的分佈。爲了使他們能方便地協做開發,鏡像須要跨地同步,這咱們就依靠了公司已有的swift存儲,這一起沒有太多可說的,帶寬越大,同步的速度就越快。值得一提的是,因爲Harbor的UI須要從MySQL提取數據,因此若是須要各地看到同樣的界面,是須要同步Harbor MySQL數據的。

鏡像加速

不少開源鏡像都託管在DockerHub、Google Container Registry和Quay上,因爲受制於GFW及公司網絡帶寬,直接pull這些鏡像,速度如龜爬,極大影響工做心情和效率。

一種可行方案是將這些鏡像經過代理下載下來,docker tag後上傳到公司鏡像站,再更改相應manifest yaml,但這種方案的用戶體驗就是像最終幻想裏的踩雷式遇敵,普通用戶不知道爲何應用起不了,即便知道了是由於鏡像拉取慢,鏡像有時能拉有時又不能拉,他的機器能拉,個人機器不能拉,得搞明白哪裏去配默認鏡像地址,並且還得想辦法把鏡像從國外拉回來,上傳到公司,整個過程繁瑣耗時低智,把時間浪費在這種事情上,實在是浪費生命。

咱們採起的方案是,用mirror.example.com的域名來mirror DockerHub,同時公司nameserver劫持quay,gcr,這樣用戶只須要配置一次docker daemon就能夠無痛拉取全部經常使用鏡像,也不用擔憂是否哪裏須要override拉取鏡像的位置,並且每一個辦公區都作相似的部署,這樣用戶都是在辦公區本地拉取鏡像,速度快而且節約寶貴的辦公區間帶寬。

值得一提的是,因爲對gcr.io等域名在辦公區內網作了劫持,但咱們手裏確定沒有這些域名的key,因此必須用http來拉取鏡像,因而須要配置docker daemon的--insecure-registry這個項

用戶體驗

配置docker daemon(以Ubuntu 16.04爲例)

sudo -s
cat << EOF > /etc/docker/daemon.json
{
  "insecure-registries": ["quay.io", "gcr.io","k8s.gcr.io],
  "registry-mirrors": ["https://mirror.example.com"]
}
EOF
systemctl restart docker.service

測試

# 測試解析,應解析到一個內網IP地址(private IP address)
# 拉取dockerhub鏡像
docker pull ubuntu:xenial
# 拉取google鏡像
docker pull gcr.io/google_containers/kube-apiserver:v1.10.0
# 拉取quay鏡像
docker pull quay.io/coreos/etcd:v3.2
# minikube
minikube start --insecure-registry gcr.io,quay.io,k8s.gcr.io --registry-mirror https://mirror.example.com

技術架構圖

輸入圖片說明

監控報警

因爲zabbix等傳統監控報警工具容器化環境中捉襟見肘,咱們須要從新創建一套監控報警系統,幸好prometheus/alertmanager使用還算比較方便,而且已有的zabbix因爲使用不善,致使已有監控系統的用戶體驗不好(誤報/漏報/報警風暴/命名不規範/操做複雜等等),否則在有限的時間和人員條件下,只是爲了kick start而什麼都得另起爐竈,仍是很麻煩的。

其實分佈式系統的監控報警系統,不論在是否用容器,都須要解決這些問題:能感知機器/容器(進程)/應用/三個層面的指標,分散在各個機器的日誌要能儘快收集起來供查詢檢索及報警低信噪比、不誤報不漏報、能「望文生義」等。

而這些問題就像以前提到的,prometheus/alertmanager已經解決得比較好了:經過exporter pattern,插件化的解決靈活適配不一樣監控目標(node-exporter, cAdvisor, mysql-exporter, elasticsearch-exporter等等);利用prometheus和rancher dns服務配合,能夠動態發現新加入的exporter/agent;alertmanager則是一款很優秀的報警工具,能實現alerts的路由/聚合/正則匹配,配合已有的郵件和咱們本身添加的微信(現已官方支持)/電話(集成阿里雲語音服務),天天報警數量和頻次達到了oncall人員能接受的狀態。

至於日誌收集,咱們仍是聽從了社區的推薦,使用了Elasticsearch + fluentd + Kibana的組合,fluentd做爲Rancher的Global Serivce(對應於Kubernetes的daemon set),收集每臺機器的系統日誌,dockerd日誌,經過docker_metadata這個插件來收集容器標準輸出(log_driver: json_file)的日誌,rancher基礎服務日誌,既本地文件系統壓縮存檔也及時地發往相應的elasticsearch服務(並未用容器方式啓動),經過Kibana可視化供產品售後使用。基於的日誌報警使用的是Yelp開源的elastalert工具。

爲每一個環境手動建立監控報警stack仍是蠻繁瑣的,因而咱們也自定義了一個Rancher Catalog來方便部署。

監控報警系統涉及的方面太多,而至於什麼是一個「好」的監控報警系統,不是我在這裏能闡述的話題,Google的Site Reliability Engineering的這本書有我認爲比較好的詮釋,但一個拋磚引玉的觀點能夠分享,即把監控報警系統也當成一個嚴肅的產品來設計和改進,須要有一我的(最好是核心oncall人員)承擔產品經理般的角色,來從人性地角度來衡量這個產品是否真的好用,是否有觀感上的問題,特別是要避免破窗效應,這樣對於創建oncall人員對監控報警系統的信賴和承認相當重要。

技術架構圖 輸入圖片說明

可靠性保障

分佈式系統在提高了併發性能的同時,也增大了局部故障的機率。健壯的程序設計和部署方案可以提升系統的容錯性,提升系統的可用性。可靠性保障是運維部門發起的一系列目的在於保障業務穩定/可靠/魯棒的措施和方法,具體包括:

● 生產就緒性檢查

● 備份管理體系

● 故障分析與總結

● chaos monkey

主要談談chaos monkey,整體思路就是流水不腐,戶樞不蠹。經過模擬各類可能存在的故障,發現系統存在的可用性問題,提醒開發/運維人員進行各類層面的改進。

預期

  • 大多數故障無需人馬上干預

  • 業務異常(如HTTP 502/503)窗口在兩分鐘之內

  • 報警系統應該保證

    不漏報
    
         沒有報警風暴
    
         報警分級別(郵件/微信/電話)發到該接收報警的人

測試樣例

咱們須要進行測試的case有:

  • service升級

  • 業務容器隨機銷燬

  • 主機遣散

  • 網絡抖動模擬

  • Rancher基礎服務升級

  • 主機級別網絡故障

  • 單主機機器宕機

  • 若干個主機機器宕機

  • 可用區宕機

部署示例(單個租戶 & 單個地域)

輸入圖片說明

總 結

一、體量較小公司也能夠搭建相對可用的容器平臺。

二、公司發展早期投入一些精力在基礎設施的建設上,從長遠來看仍是有價值的,這種價值體如今很早就能夠積累一批有能力有經驗有幹勁兒的團隊,來不斷對抗規模擴大後的複雜性猛增的問題。一個「讓人直觀感受」,「看起來」混亂的基礎技術架構,會很大程度上影響開發人員編碼效率。甚至能夠根據破窗原理揣測,開發人員可能會以爲將會運行在「髒」,「亂」,」差」平臺的項目不必把質量看得過重。對於一個大的組織來說,秩序是一種難得的資產,是有沒法估量的價值的。

三、鏡像拉取慢問題也能夠比較優雅地緩解。

四、國內訪問國外網絡資源整體來說仍是不方便的,即便沒有GFW,帶寬也是很大的問題。而咱們的解決方案也很樸素,就是緩存加本地訪問,這樣用比較優雅高效地方法解決一個「蒼蠅」問題,改善了不少人的工做體驗,做爲工程人員,內心是很知足的。

五、容器化也能夠看做是一種對傳統運維體系的重構。

六、容器化本質上是當容器成爲技術架構的所謂building blocks以後,對已有開發運維解決方案從新審視,設計與重構。微服務、雲原生催生了容器技術產生,然後者,特別是Docker工具自己美妙的UX,極大地鼓舞了技術人員與企業奔向運維「應許之地」的熱情。雖然你們都心知肚明銀色子彈並不存在,但Kubernetes ecosystem愈來愈看起來前途不可限量,給人以無限但願。而販賣但願自己被歷史不斷證實,倒真是穩賺不虧的商業模式。

致 謝

一、感謝Richard Stallman爲表明的自由軟件運動的參與者、貢獻者們,讓小人物、小公司也能有大做爲。

二、感謝Google Search讓搜索信息變得如此便利。

三、感謝Docker公司及Docker軟件的貢獻者們,催生了一個巨大的行業也改善了衆多開發/運維人員的生活。

四、感謝Rancher這個優秀的開源項目,提供瞭如Docker般的容器運維UX。

五、感謝GitHub讓軟件協做和代碼共享如此便利和普及。

六、感謝mermaid插件的做者們,能夠方便地用markdown定義編輯好看的流程圖。

相關文章
相關標籤/搜索