日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DockOne微信分享(八十四):Docker在B站的实施之路

發布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DockOne微信分享(八十四):Docker在B站的实施之路 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本文講的是DockOne微信分享(八十四):Docker在B站的實施之路【編者的話】B站一直在關注Docker的發展,去年成功在核心SLB(Tengine)集群上實施了Docker。今年我們對比了各種Docker實施方案后選擇了Mesos。結合CI&CD,打通了整個業務的Docker上線流程,并實現了全自動擴縮容。這次結合我們的實施之路,分享一下遇到的重點與難點:
  • 自研Docker網絡插件的介紹;
  • Bili PaaS平臺中的CD實現與優化;
  • 應用全自動擴縮容的實現方案;
  • Nginx動態Upstream跟Docker的配合使用。

  • B站一直在關注Docker的發展,去年成功在核心SLB(Tengine)集群上實施了Docker,規模不大但訪問量大、沒有CI & CD的工作。隨著業務量的增長,應用擴縮需求越來越多。但在沒有docker標準化的情況下,應用擴容需要擴服務器,操作繁重。同時為了減少因測試、線上環境不一致導致的問題,我們計劃將業務全部Docker化,并配合CI & CD,打通整個業務上線流程,達到秒級動態擴縮容。

    下面是我們的實施之路,整體架構圖如下:

    為什么選擇Mesos?

    Kubernetes太重,功能繁多。我們主要看中Mesos的調度功能,且輕量更易維護。另外和我們選擇了Macvlan的網絡有關。

    Docker網絡選擇

    Docker自帶的網絡都不能滿足我們的需求。

    Bridger:Docker分配私有IP,本機通過bridge跟容器通信。不同宿主機如果要通信需要iptables映射端口。隨著容器的增多,端口管理會很混亂,iptables規則也越來越多。

    Host:使用宿主機的網絡,不同容器不能監聽相同端口。

    None:Docker不給容器分配網絡,手動分配。

    正當我們無法選定Docker的網絡方案時,發現最新的Docker 1.12版本提供了另外兩種網絡驅動:Overlay和Macvlan。

    Overlay:在原來的TCP/IP數據包基礎上再封裝成UDP的數據包傳輸。當網絡出現問題需要抓包時,會比較麻煩。而且,Overlay依靠服務器的CPU來解UDP數據包,會導致Docker網絡性能非常不穩定,性能損耗比較嚴重,在生產環境中難以使用。

    Macvlan:在交換機上配置VLAN,然后在宿主機上配置物理網卡,使其接收對應的VLAN。Docker在創建Network時driver指定Macvlan。對Docker的Macvlan網絡進行壓測,跑在Macvlan網絡的容器比跑在host網絡的容器性能損失10~15%左右,但總體性能很穩定,沒有抖動。這是能接受的。

    基于Macvlan,我們開發了自己的IPAM Driver Plugin—底層基于Consul。
    Docker在創建Macvlan網絡時,驅動指定為自己研發的Consul。Consul中會記錄free和used的IP。如下圖:

    IPAM Driver在每臺宿主機上都存在,通過Socket的方式暴露給Docker調用。Docker在創建容器時,IPAM Plugin會從Consul申請一個free的IP地址。刪除容器時,IPAM Plugin會釋放這個IP到Consul。因為所有宿主機上的IPAM Plugin連接到的是同一個Consul,就保證了所有容器的IP地址唯一性。

    我們用IPAM Plugin遇到的問題:

    1)?Consul IPAM Plugin在每臺宿主機上都存在,通過Socket方式調用,目前使用容器啟動。

    當Docker daemon重啟加載Network時,因為容器還未啟動,會找不到Consul IPAM Plugin的Socket文件,導致Docker daemon會去重試請求IPAM,延長daemon的啟動時間,報錯如下:
    level=warning?msg="Unable?to?locate?plugin:?consul,?retrying?in?1s" level=warning?msg="Unable?to?locate?plugin:?consul,?retrying?in?2s" level=warning?msg="Unable?to?locate?plugin:?consul,?retrying?in?4s" level=warning?msg="Unable?to?locate?plugin:?consul,?retrying?in?8s" level=warning?msg="Failed?to?retrieve?ipam?driver?for?network?\"vlan1062\"

    解決方案:Docker識別Plugin的方式有三種:
  • sock files are UNIX domain sockets.
  • spec files are text files containing a URL, such as unix:///other.sock or tcp://localhost:8080.
  • json files are text files containing a full json specification for the plugin.

  • 最早我們是通過.sock的方式識別IPAM Plugin。現在通過.spec文件的方式調用非本地的IPAM Plugin。這樣Docker daemon在重啟時就不受IPAM Plugin的影響。

    2)?在通過Docker network rm 刪除用Consul IPAM創建的網絡時,會把網關地址釋放給Consul,下次創建容器申請IP時會獲取到網關的IP,導致網關IP地址沖突。

    解決方案:在刪除容器釋放IP時,檢測下IP地址,如果是網關IP,則不允許添加到Consul的free列表。

    基于以上背景,我們剛開始選型的時候,測試過Docker 1.11 + Swarm 和Docker 1.12集成的SwarmKit。Docker 1.11 + Swarm網絡沒有Macvlan驅動,而Docker 1.12集成的SwarmKit只能使用Overlay網絡,Overlay的性能太差。最終我們采用了Docker 1.12 + Mesos。

    CI & CD

    對于CI,我們采用了目前公司中正在大量使用的Jenkins。 Jenkins通過Pipeline分為多個step,step 1 build出要構建war包。Step 2 build Docker 鏡像并push到倉庫中。

    第一步: build出想要的war,并把war包保存到固定的目錄。第二步:build docker鏡像,會自動發現前面build出的war包,并通過寫好的Dockerfile build鏡像,鏡像名即為應用名。鏡像構建成功后會push到我們的私有倉庫。每次鏡像構建都會打上一個tag,tag即為發布版本號。后續我們計劃把CI從jenkins獨立出來,通過自建的Paas平臺來build war包和鏡像。

    我們自研了基于Docker的PaaS平臺(持續開發中)。該平臺的功能主要包括信息錄入、應用部署、監控、容器管理、應用擴縮等。CD就在Paa上。

    當要部署一個新的業務系統時,要先在Paas系統上錄入應用相關信息,比如基礎鏡像地址、容器資源配置、容器數量、網絡、健康檢查等

    CD時,需要選擇鏡像的版本號,即上文提到的tag

    我們同時支持控制迭代速度,即迭代比例的設置

    這個設置是指,每次迭代20%的容器,同時存活的容器不能低于迭代前的100%。

    我們遇到的問題:控制迭代比例。

    Marathon有兩個參數控制迭代比例:
    • minimumHealthCapacity(Optional. Default: 1.0)處于health狀態的最少容器比例;
    • maximumOverCapacity(Optional. Default: 1.0)可同時迭代的容器比例。

    假如有個Java應用通過Tomcat部署,分配了四個容器,默認配置下迭代,Marathon可以同時啟動四個新的容器,啟動成功后刪除四個老的容器。四個新的Tomcat容器在對外提供服務的瞬間,因為請求量太大,需要立即擴線程數預熱,導致剛進來的請求處理時間延長甚至超時(B站因為請求量大,請求設置的超時時間很短,在這種情況下,請求會504超時)。

    解決方法:

    對于請求量很大需要預熱的應用,嚴格控制迭代比例,比如設置maximumOverCapacity為0.1,則迭代時只能同時新建10%的容器,這10%的容器啟動成功并刪除對應老的容器后才會再新建10%的容器繼續迭代。

    對于請求量不大的應用,可適當調大maximumOverCapacity,加快迭代速度。

    動態擴縮容

    節假日或做活動時,為了應對臨時飆高的QPS,需要對應用臨時擴容。或者當監控到某個業務的平均資源使用率超過一定限制時,自動擴容。我們的擴容方式有兩種:1、手動擴容;2、制定一定的規則,當觸發到規則時,自動擴容。我們的Bili PaaS平臺同時提供了這兩種方式,底層是基于Marathon的Scale API。這里著重講解下基于規則的自動擴縮容。

    自動擴縮容依賴總架構圖中的幾個組件:Monitoring Agent、Nginx+UpSync+Consul、Marathon Hook、Bili PaaS。

    Monitor Agent:我們自研了Docker的監控Agent,封裝成容器,部署在每臺Docker宿主機上,通過docker stats的接口獲取容器的CPU、內存、IO等信息,信息錄入InfluxDB,并在Grafana展示。

    Bili PaaS:應用在錄入PaaS平臺時可以選擇擴縮容的規則,比如:平均CPU > 300% OR MEM > 4G。PaaS平臺定時輪詢判斷應用的負載情況,如果達到擴容規則,就按一定的比例增加節點。本質上是調用Marathon的API進行擴縮。

    Marathon Hook:通過Marathon提供的/v2/events接口監聽Marathon的事件流。當在Bili PaaS平臺手動擴容或觸發規則自動擴容時,Bili Paas平臺會調用Marathon的API。Marathon的每個操作都會產生事件,通過/v2/events接口暴露出來。Marathon Hook程序會把所有容器的信息注冊到Consul中。當Marathon刪除或創建容器時,Marathon Hook就會更新Consul中的Docker容器信息,保證Consul中的信息和Marathon中的信息是一致的,并且是最新的。

    Nginx+UpSync+Consul:當Marathon擴容完成時,新容器的IP:PORT一定要加到SLB(Tengine/Nginx)的Upstream中,并reload SLB后才能對外提供服務。但Tengine/Nginx reload時性能會下降。為了避免頻繁reload SLB導致的性能損耗,我們使用了動態Upstream:Nginx + UpSync + Consul。Upsync是Weibo開源的一個模塊,使用Consul保存Upstream的server信息。Nginx啟動時會從Consul獲取最新的Upstream server信息,同時Nginx會建立一個TCP連接hook到Consul,當Consul里的數據有變更時會立即通知到Nginx,Nginx的worker進程更新自己的Upstream server信息。整個過程不需要reload nginx。注意:UpSync的功能是動態更新upstream server,當有vhost的變更時,還是需要reload nginx。

    我們遇到的問題:

    1)?Nginx + UpSync 在reload時會產生shutting down。因為Nginx Hook到Consul的鏈接不能及時斷開。曾在GitHub上因這個問題提過issue,作者回復已解決。個人測試發現shuttding down還是存在。并且UpSync和Tengine的http upstream check模塊不能同時編譯。

    解決方案:Tengine + Dyups。我們正在嘗試把Nginx + Dyups替換為Tengine + Dyups。Dyups的弊端就是Upstream信息是保存在內存里的。Reload/Restart Tengine時就會丟失。需要自己同步Upstream信息到磁盤中。基于此,我們對Tengine + Dyups做了封裝,由一個代理進程Hook Consul,發現有更時則主動更新Tengine,并提供了Web管理界面。目前正在內部測試中。

    2)Docker Hook —> Marathon Hook,最早我們是去Hook Docker的events。這需要在每臺宿主機上起一個Hook服務。當應用迭代時,Docker會立即產生一個create container的事件。Hook程序監控到后去更新Consul,然后Consul通知Nginx去更新。導致問題就是:容器里的服務還沒啟動成功(比如Tomcat),就已經對外提供服務了。這會導致很多請求失敗,產生重啟請求。

    解決方案:Marathon Hook。Marathon中有一個health check的配置。如下圖

    我們規定所有的Web服務必須提供一個Health Check接口,這個接口隨著服務一同起來,這個接口任何非200的http code都代表應用異常。Marathon剛啟動容器時,顯示此容器的Health狀態是uknow。當Health Check成功時,Marathon顯示此容器的Health狀態Healthy,并會產生一個事件。Marathon Hook程序通過Hook這個事件,就能準確捕獲容器中應用啟動成功的時間,并更新Consul,同步Nginx,對外提供服務。

    3)Marathon Failover后會丟失command health check,通過Marathon給容器添加Health Check時,有三種方式可以選擇:HTTP TCP COMMAND

    當使用HTTP TCP時,Check是由Marathon發起的,無法選擇Check時的端口,Marathon會用自己分配的PORT進行Check。實際上我們并未使用marathon映射的端口。我們選擇了COMMAND方式,在容器內部發起curl請求來判斷容器里的應用狀態。當Marathon發生failover后,會丟失COMMAND health check,所有容器狀態都顯示unknow。需要重啟或者迭代應用才能恢復。

    Q&A

    Q:你好 問下貴公司的自動擴容是針對應用的吧 有沒有針對Mesos資源池監控并做Mesos Agent的擴容?
    A:目前的自動擴容是針對應用的。Mesos Agent擴容時,先把物理機信息錄入PaaS平臺,手動在PaaS平臺點擊擴容,后臺會調用Ansible,分鐘快速級擴Mesos Agent。 Q:現在是確定Nginx+UpSync+Upsteam check是無法一起用的么?貴公司的Nginx版本是多少哇?
    A:測試過Nginx 1.8和1.10,確認無法一同編譯。我們用的最多的Nginx(SLB)是Tengine 2.1.1,部署在Docker上。 Q:既然是封裝, 那底層用Mesos比Kubernets并沒有太大的靈活性吧?
    A:對于PaaS平臺,目前我們希望的只需要資源調度這個功能,其他功能我們還是希望可以自己實現,而Mesos是專注于調度資源,而且已經歷經了大量級的考驗。而Kubernetes目前提供的很多服務,我們并不需要,所以選擇了Mesos。 Q:容器是采用Monitor Agent監控,那容器內的呢?也還是內部埋點?還是EFK嗎?監控是采用Prometheus嗎?
    A:Prometheus沒有使用,我們是用自己的監控Agent -> InfluxDB。容器內有多種監控方式。有用ELK,也有其他埋點,比如StatsD,基于Dapper論文實現的全鏈路追蹤。 Q:網絡選型這塊,還調研過其他網絡方案嗎?譬如Calico、Weave等,為什么會選用Macvlan?
    A:我們的選型第一步是先選擇標準的,要從CoreOS主導的cni還是Docker官方主導cnm里面選擇,目前由于我們容器方案還是走的Docker,所以選擇了cnm,那從cnm的標準里面的選擇基本是:1. 基于XVLAN的Overlay;2. 基于三層路由的Calico;3. 基于二層隔離的Macvlan,實際以上的方案我們都調研使用過,基于希望盡量簡單的原則最終選型還是Macvlan。 Q:Bili PaaS平臺,自動擴容和手動擴容,應用多的是哪種方式?自動擴容后,資源會重調度么?是否會中斷已有業務呢?
    A:用的更多的是根據制定好的策略,自動擴容。通過Nginx 動態Upstream對外提供服務,不會中斷業務。 Q:關于日志收集每個容器里都跑一個Logstash嗎?好像ELK不能搜索展示上下文的啊?
    A:容器里面沒有跑Logstash。目前是在遠端的Logstash集群上監聽一個UDP端口,應用直接把日志推送到Logstash的UDP端口,然后Logstash把日志推送到Kafka,Kafka的消費者有兩個,一個是Elasticsearch,一個是HDFS。一般用ELK足以。需要詳細日志時,由運維通過HDFS查詢。 Q:我想請教下Nginx的一些動態配置文件是封裝在容器內部了?還是通過volume的方式掛載了?有沒有配置中心類似的服務?這塊想了解下是怎么實現的?
    A:Nginx的Upstream是從Consul動態獲取生成在本地的,通過Volume掛載,持久化到宿主機。有配置中心。業務Docker化時,就會推動業務配置接配置中心,Docker中不在保存業務依賴的配置。

    以上內容根據2016年9月27日晚微信群分享內容整理。分享人武安闖,Bilibili 運維工程師,目前主要負責B站運維和業務Docker化的實施。一直關注于Docker的發展,Docker與Mesos結合的容器平臺實施?。DockOne每周都會組織定向的技術分享,歡迎感興趣的同學加微信:liyingjiesz,進群參與,您有想聽的話題或者想分享的話題都可以給我們留言。

    原文發布時間為:2016-09-29

    本文作者:武安闖

    本文來自云棲社區合作伙伴Dockerone.io,了解相關信息可以關注Dockerone.io。

    原文標題:DockOne微信分享(八十四):Docker在B站的實施之路

    總結

    以上是生活随笔為你收集整理的DockOne微信分享(八十四):Docker在B站的实施之路的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。