蘑菇街 私有云Docker實例應用
對于蘑菇街而言,每年的11.11已經(jīng)成為一年中最大的考驗,考驗的是系統(tǒng)穩(wěn)定性,容災能力,緊急故障處理,運維等各個方面的能力。蘑菇街的私有云平臺,從無到有,已經(jīng)經(jīng)過了近一年的發(fā)展,生產(chǎn)環(huán)境上經(jīng)歷了3次大促,穩(wěn)定性方面得到了初步驗證。本文我將從架構、技術選型、應用等角度來談談蘑菇街的私有云平臺。
另,ArchSummit全球架構師峰會北京站將于2015年12月18日~19日在北京國際會議中心召開,大會設置了《揭秘雙十一背后的技術較量》專題來深入解讀雙十一背后的技術故事,歡迎關注。
蘑菇街的私有云平臺(以下簡稱蘑菇街私有云)是蘑菇街面向內(nèi)部上層業(yè)務提供的基礎性平臺。通過基礎設施的服務化和平臺化,可以使上層業(yè)務能夠更加專注在業(yè)務自身,而不是關心底層運行環(huán)境的差異性。它通過基于Docker的CaaS層和KVM的IaaS層來為上層提供IaaS/PaaS層的云服務,以提高物理資源的利用率,以及業(yè)務部署和交付的效率,并促進應用架構的拆分和微服務化。
在架構選型的時候,我們覺得Docker的輕量化,秒級啟動,標準化的打包/部署/運行的方案,鏡像的快速分發(fā),基于鏡像的灰度發(fā)布等特性,都十分適合我們的應用場景。而Docker自身的集群管理能力在當時條件下還很不成熟,因此我們沒有選擇剛出現(xiàn)的Swarm,而是用了業(yè)界最成熟的OpenStack,這樣能同時管理Docker和KVM虛擬機。相對來說,Docker適合于無狀態(tài),分布式的業(yè)務,KVM適合對安全性,隔離性要求更高的業(yè)務。
對于上層業(yè)務來說,它不需要關心是運行在容器中,還是KVM虛擬機里。今后的思路是應用的微服務化,把上層的業(yè)務進行拆分,變成一個個微服務,從而對接PaaS基于容器的部署和灰度發(fā)布。
技術架構
在介紹雙十一的準備工作之前,我先簡單介紹一下蘑菇街私有云的技術架構。
我們采用的是OpenStack+novadocker+Docker的架構模式,novadocker是StackForge上一個開源項目,它做為nova的一個插件,通過調用Docker的RESTful接口來控制容器的啟停等動作。每個Docker就是所謂的“胖容器”,它會有獨立的IP地址,通過supervisord來管理容器內(nèi)的子進程,常見的如SSHD、監(jiān)控agent等進程。

我們在IaaS的基礎上自研了PaaS層的編排調度等組件,實現(xiàn)了應用的彈性伸縮、灰度升級,支持一定的調度策略。我們通過Docker和Jenkins實現(xiàn)了持續(xù)集成(CI)。Git中的項目如果發(fā)生了git push等動作,便會觸發(fā)Jenkins Job進行自動構建,如果構建成功便會生成Docker Image并push到鏡像倉庫。基于CI生成的Docker Image,可以通過PaaS的API或界面,進行開發(fā)測試環(huán)境的實例更新,并最終進行生產(chǎn)環(huán)境的實例更新,從而實現(xiàn)持續(xù)集成和持續(xù)交付。
網(wǎng)絡方面,我們沒有采用Docker默認提供的NAT網(wǎng)絡模式,NAT會造成一定的性能損失。通過OpenStack,我們支持Linux bridge和openvswitch,不需要啟動iptables,Docker的性能接近物理機的95%。
準備工作 穩(wěn)定性
迎戰(zhàn)雙11,最重要的當然是確保穩(wěn)定性。通過近一年的產(chǎn)品化和實際使用,我們積累了豐富的提高穩(wěn)定性的經(jīng)驗。
對于那些已遇到過的問題,需要及時采用各種方式進行解決或者規(guī)避。
比如說,CentOS6.5對network namespace支持不好,在Docker容器內(nèi)創(chuàng)建Linux bridge會導致內(nèi)核crash,upstream在2.6.32-504中修復了這個bug,因此線上集群的內(nèi)核版本,必須升級至2.6.32-504或以上。
又比如,CentOS6.5自帶的device mapper存在dm-thin discard導致內(nèi)核可能隨機crash,這個問題我們早在四月份的時候已經(jīng)發(fā)現(xiàn)并解決了,解決的辦法是關閉discard support,在docker配置中添加“--storage-opt dm.mountopt=nodiscard --storage-opt dm.blkdiscard=false”,并且嚴格禁止磁盤超配,因為磁盤超配可能會導致整個device mapper無法分配磁盤空間,而把整個文件系統(tǒng)變成只讀,從而引起嚴重問題。
監(jiān)控
我們在雙11前重點加強的是針對容器的監(jiān)控。
在此之前,我們已經(jīng)自研了一套container tools。主要功能有兩個:一是能夠以容器為粒度計算load值,可以根據(jù)load值進行容器粒度的qps限流。二是替換了原有的top、free、iostat、uptime等命令,確保運維在容器內(nèi)使用常用命令時看到的是容器的值,而不是整個物理機的值。雙十一之后我們還會把lxcfs移植到我們的平臺上來。
在宿主機上,我們增加了多維度的閾值監(jiān)控和報警,包括對關鍵進程的存活性監(jiān)控/語義監(jiān)控,內(nèi)核日志的監(jiān)控,實時pid數(shù)量的監(jiān)控,網(wǎng)絡連接跟蹤數(shù)的監(jiān)控,容器oom的監(jiān)控報警等等。
實時pid數(shù)量監(jiān)控
為什么要監(jiān)控實時的pid數(shù)量呢?因為目前的Linux內(nèi)核對pid的隔離性支持是不完善的。還沒有任何Linux發(fā)行版能做到針對pid按照容器粒度進行pid_max限制。
曾經(jīng)發(fā)生過一個真實的案例是:某個用戶寫的程序有bug,創(chuàng)建的線程沒有及時回收,容器中產(chǎn)生了大量的線程,最后在宿主機上都無法執(zhí)行命令或者ssh登陸,報的錯是"bash: fork: Cannot allocate memory",但是此時通過free命令看到空閑的內(nèi)存卻是足夠的。
為什么會這樣呢?根本原因是內(nèi)核中的pid_max(/proc/sys/kernel/pid_max)是全局共享的。當一個容器中的pid數(shù)目達到上限32768,會導致宿主機和其他容器無法創(chuàng)建新的進程。最新的4.3-rc1才支持對每個容器進行pid_max的限制。
內(nèi)存使用監(jiān)控
值得一提的是,我們發(fā)現(xiàn)cgroup提供的內(nèi)存使用值是不準確的,比真實使用的內(nèi)存值要低。因為內(nèi)核memcg無法回收slab cache,也不對dirty cache量進行限制,所以很難估算容器真實的內(nèi)存使用情況。曾經(jīng)發(fā)生過統(tǒng)計的內(nèi)存使用率一到70-80%,就發(fā)生OOM的情況。為此,我們調整了容器內(nèi)存的計算算法,根據(jù)經(jīng)驗值,將cache的40%算做rss,調整后的內(nèi)存計算比之前精確了不少。
日志亂序
還有一個問題是跑Docker的宿主機內(nèi)核日志中經(jīng)常會產(chǎn)生字符亂序,這樣會導致日志監(jiān)控無法取到正確的關鍵字進行報警。
經(jīng)過分析發(fā)現(xiàn),這個跟我們在宿主機和Docker容器中都跑了rsyslogd有關。由于內(nèi)核中只有一個log_buf緩沖區(qū),所有printk打印的日志先放到這個緩沖區(qū)中,docker host以及container上的rsyslogd都會通過syslog從kernel的log_buf緩沖區(qū)中取日志,導致日志混亂。通過修改container里的rsyslog配置,只讓宿主機去讀kernel日志,就能解決這個問題。
隔離開關
平時我們的容器是嚴格隔離的,我們做的隔離包括CPU、內(nèi)存和磁盤IO,網(wǎng)絡IO等。但雙十一的業(yè)務量可能是平時的十幾倍或幾十倍。我們?yōu)殡p十一做了不少開關,在壓力大的情況下,我們可以為個別容器進行動態(tài)的CPU,內(nèi)存等擴容或縮容,調整甚至放開磁盤iops限速和網(wǎng)絡的TC限速。
健康監(jiān)測
我們還開發(fā)了定期的健康監(jiān)測,定期的掃描線上可能存在的潛在風險,真正做到提前發(fā)現(xiàn)問題,解決問題。
災備和緊急故障處理
除了穩(wěn)定性,災備能力也是必須的,我們做了大量的災備預案和技術準備。比如我們研究了不啟動Docker Daemon的情況下,離線恢復Docker中數(shù)據(jù)的方法。具體來說,是用dmsetup create命令創(chuàng)建一個臨時的dm設備,映射到Docker實例所用的dm設備號,通過mount這個臨時設備,就可以恢復出原來的數(shù)據(jù)。
我們還支持Docker容器的冷遷移。通過管理平臺的界面可以一鍵實現(xiàn)跨物理機的遷移。
與已有運維系統(tǒng)的對接
Docker集群必須能與現(xiàn)有的運維系統(tǒng)無縫對接,才能快速響應,真正做到秒級的彈性擴容/縮容。我們有統(tǒng)一的容器管理平臺,實現(xiàn)對多個Docker集群的管理,從下發(fā)指令到完成容器的創(chuàng)建可以在7秒內(nèi)完成。
性能優(yōu)化
我們從系統(tǒng)層面也對docker做了大量的優(yōu)化,比如針對磁盤IO的性能瓶頸,我們調優(yōu)了像vm.dirty_expire_centisecs,vm.dirty_writeback_centisecs, vm.extra_free_kbytes這樣的內(nèi)核參數(shù)。還引入了Facebook的開源軟件flashcache,將SSD作為cache,顯著的提高docker容器的IO性能。
我們還通過合并鏡像層次來優(yōu)化docker pull鏡像的時間。在docker pull時,每一層校驗的耗時很長,通過減小層數(shù),不僅大小變小,docker pull時間也大幅縮短。
|
鏡像 |
文件層數(shù) |
文件大小 |
docker pull時間 |
| 原鏡像 | 13 | 1.051 GB | 2m13 |
| 新鏡像 | 1 | 674.4 MB | 0m26 |
總結
總的來說,雙11是對蘑菇街私有云的一次年終大考,對此我們已有了充分的準備。隨著Docker集群部署的規(guī)模越來越大,我們還有很多技術難題有待解決,包括容器本身的隔離性問題,集群的彈性調度問題等等。同時我們也很關注Docker相關的開源軟件Kubernetes、Mesos、Hyper、criu、runC的發(fā)展,未來將引入容器的熱遷移,Docker Daemon的熱升級等特性。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關文章
Docker swarm如何通過docker-compose部署應用
這篇文章主要介紹了Docker swarm如何通過docker-compose部署應用問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
docker部署Macvlan實現(xiàn)跨主機網(wǎng)絡通信的實現(xiàn)
這篇文章主要介紹了docker部署Macvlan實現(xiàn)跨主機網(wǎng)絡通信的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10

