摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項(xiàng)目來說,理論上來說是沒必要用太復(fù)雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。
Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領(lǐng)域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關(guān)技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到的各種坑以及踩坑過程中的一些思考,希望能對了解過Docker并且躍躍欲試的同學(xué)有點(diǎn)啟發(fā),當(dāng)然更歡迎在這方面有豐富經(jīng)驗(yàn)的同學(xué)給一些建議或者指點(diǎn)。
一、項(xiàng)目環(huán)境這篇文章不會提及Docker的理論知識或者基本概念相關(guān)的內(nèi)容,如果想了解Docker的基本使用,Docker的官方文檔是個不錯的選擇,如果想了解基本的理論,可以參考下coolshell博客上的幾篇文章:Docker基礎(chǔ)技術(shù):Linux Namespace(上)、Docker基礎(chǔ)技術(shù):Linux Namespace(下)、Docker基礎(chǔ)技術(shù):Linux CGroup、Docker基礎(chǔ)技術(shù):AUFS、Docker基礎(chǔ)技術(shù):DeviceMapper。
我們項(xiàng)目用的標(biāo)準(zhǔn)的PHP技術(shù)棧:PHP-FPM + Nginx,運(yùn)行在阿里云的ECS上,數(shù)據(jù)庫也是阿里云的服務(wù)。
二、緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項(xiàng)目來說,理論上來說是沒必要用太復(fù)雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。然而我之所以在項(xiàng)目上做這個嘗試也并非是想嘗試新技術(shù),而是源自于項(xiàng)目上線以來遇到的各種問題,比如前面文章里有提到過的laravel的性能問題,而HHVM或者PHP7這些新技術(shù)都大大提到了性能,一下子全部切換風(fēng)險太大,所以可以用容器來運(yùn)行某幾個服務(wù)測試一下;再比如之前有出現(xiàn)過一個BUG,某個接口出現(xiàn)問題占用內(nèi)存太高導(dǎo)致整個系統(tǒng)響應(yīng)超時;再比如,看了各種技術(shù)大會上別人分享的經(jīng)驗(yàn)確實(shí)想自己試一下,哈哈。
三、牛刀小試根據(jù)Docker的理念,每個容器都是一個獨(dú)立的服務(wù),服務(wù)之間通過接口相互協(xié)作。我們采用的方案是PHP-FPM和Nginx分別跑在不同的容器中,PHP-FPM容器暴露端口給Nginx容器。
容器之間的網(wǎng)絡(luò)通信最初用的是Docker自帶的link,link雖然很簡單,但是不太好用,link是通過在容器啟動時修改/etc/hosts文件來實(shí)現(xiàn)的,當(dāng)時用的時候遇到的一個問題是被link的容器重啟后,這個容器IP變了,但是link的容器里并沒有更新(1.10版本對link機(jī)制做了修改,不知道是否解決了這個問題,還沒具體看),還有一個問題就是當(dāng)同一個服務(wù)需要開多個容器時就搞不定了,當(dāng)然如果是用集群的方式來跑就更搞不定了,所以link只能在本地開發(fā)時玩玩,在生產(chǎn)環(huán)境沒啥用。最后這部分用的方案是用consul來做服務(wù)發(fā)現(xiàn),關(guān)于consul就不在這里展開介紹了,有興趣的同學(xué)可以看下這篇文章:Service Discovery for Docker Containers using Consul and Registrator。
然后代碼是放在host上,在容器啟動時掛載一下代碼的目錄。根據(jù)接口使用的場景將接口分到了幾個不同的容器里面去跑,對資源隔離做了下壓力測試,符合預(yù)期,很滿意!然后選了兩個容器跑HHVM測試了下,確實(shí)性能提高了很多。整個結(jié)構(gòu)如下圖所示:
這樣可以正常使用了,然后就是日志的處理,最開始掛載了一個host上的目錄用來存放日志,但是這樣也不太符合Docker的理念,于是就又弄了個logstash容器,將各種容器的日志寫到logstash容器里面去。
然后就是對容器的監(jiān)控,我們用了oneapm提供的服務(wù),還不錯,也有其他一些開源工具的選擇,但是用oneapm的服務(wù)更方便一些。
一個完整的技術(shù)棧就這樣搞定了,跑了幾天也沒出現(xiàn)什么問題。作為一個有追求的碼農(nóng),當(dāng)然是要有更高的要求的,后來想到這樣一個問題:Docker的理念是容器即是一個完整的服務(wù),但是我們的用法是把在容器內(nèi)把PHP-FPM跑起來了,代碼并不在里面,而是通過目錄掛載的方式來實(shí)現(xiàn)的,這樣就需要在host上面部署好代碼,沒有完美的實(shí)現(xiàn)容器即服務(wù)的理念。好,我們追求下完美!
四、完美之路其實(shí)把代碼放進(jìn)容器并不只是為了去追求理念上的完美,還有另外一個用意,那就是基于Docker的CI。基本思路是每次發(fā)布都會build一個新版本的鏡像,build過程中需要把代碼更新到最新版本,然后安裝依賴的第三方庫以及其他一些業(yè)務(wù)相關(guān)的預(yù)處理,build完成后再push到registry,然后在各個節(jié)點(diǎn)pull下來,重啟容器。整個流程如下圖所示:
怎么樣?這下完美了吧!如果現(xiàn)實(shí)也是那么完美就好了,但是偏偏現(xiàn)實(shí)總是會有各種各樣的坑等著你!
首先,在沒有用這個機(jī)制之前,發(fā)布一次代碼也就幾秒鐘的事情,merge下分支,然后各個節(jié)點(diǎn)pull下代碼就可以了,但是用了Docker后,merge分支后就需要build一下鏡像,build后再push到registry,然后再到各個節(jié)點(diǎn)把鏡像pull下來,少說也是要花分鐘級別的。這時候有的同學(xué)可能會說Docker鏡像的原理不是layer機(jī)制么,對,確實(shí)是layer,每次build只需要更新需要更新的layer就可以,但是還是沒辦法做到像git那樣只更新那幾個文件,至少要更新整個項(xiàng)目的代碼目錄。
其次,之前只需要更新一下代碼就可以了,現(xiàn)在卻需要把容器重啟一下!本來重啟容器是很快的,但是在容器里PHP-FPM跑起來后卻很慢,我猜測是在執(zhí)行docker stop時會發(fā)一個SIGTERM的信號到容器里的進(jìn)程,PHP-FPM在處理SIGTERM信號時會做一些清理工作。一個節(jié)點(diǎn)至少有幾十個容器,每個容器都重啟一下非常耗時!
這樣本來很簡單的一個發(fā)布,用了這個「完美」的機(jī)制后卻需要好幾分鐘。雖然整個流程完全自動化,但是確實(shí)沒必要為了完美的理念做出這樣一個妥協(xié)。
此外還遇到了另外一個非常奇葩的問題:升級到1.10后,容器啟動后經(jīng)常會遇到端口不通的情況,這時候如果進(jìn)入到容器里發(fā)起一次網(wǎng)絡(luò)請求,比如ping以下某個IP,端口就會恢復(fù)正常。用各種工具調(diào)試了很久依然沒找出來問題在哪,屌絲創(chuàng)業(yè)公司也沒精力研究這么高深的問題,只好暫時擱置了。
掙扎了很久,最后又回到了老路子。
五、面對現(xiàn)實(shí)雖然沒能理念上完美的方案,但是也要讓整套架構(gòu)更方便的擴(kuò)展,比如在流量高峰期快速上架節(jié)點(diǎn)。得益于云計(jì)算近幾年的發(fā)展,這個問題也比較容易解決。前面提到代碼是放在host的一個目錄,那么基本上每個host只需要三個條件就能夠上線:
項(xiàng)目代碼目錄
安裝Docker
配置好salt-minion(用來更新配置文件)
只需要在購買一臺ECS后,做完上面的操作,生成一個系統(tǒng)鏡像,需要上線新節(jié)點(diǎn)時用這個系統(tǒng)鏡像來直接配置服務(wù)器即可。節(jié)點(diǎn)上線后,啟動各個容器,通過前面提到的用consul實(shí)現(xiàn)的服務(wù)發(fā)現(xiàn)機(jī)制,自動加入集群。
六、繼續(xù)探索后面打算用Docker Swarm來簡單做下集群管理,未來對調(diào)度需求比較大時可能會嘗試下Mesos或者Kubernetes。不過關(guān)于容器的生態(tài)鏈都發(fā)展的非常快,可能等需要的時候又有更好的方案了吧。
簡單總結(jié)下整個過程的感悟吧,從架構(gòu)上來說,永遠(yuǎn)都沒有完美的架構(gòu),只有最適合自己的架構(gòu)。從碼農(nóng)角度來說,在做技術(shù)選型時最重要的是權(quán)衡當(dāng)前項(xiàng)目需求、團(tuán)隊(duì)對各種技術(shù)了解的程度以及該技術(shù)選型帶來的復(fù)雜度。切勿看了幾個大牛的技術(shù)架構(gòu)分享就在自己項(xiàng)目上躍躍欲試,最后弄的連自己都搞不定還給別人留下一個爛攤子收拾。最后,在項(xiàng)目迭代過程中保持項(xiàng)目的簡單的能力永遠(yuǎn)是衡量一個碼農(nóng)技術(shù)的水平的重要標(biāo)準(zhǔn)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/26528.html
摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項(xiàng)目來說,理論上來說是沒必要用太復(fù)雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。 Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領(lǐng)域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關(guān)技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到...
摘要:二緣起對于一個普通的屌絲創(chuàng)業(yè)公司的屌絲項(xiàng)目來說,理論上來說是沒必要用太復(fù)雜的技術(shù)的,對新技術(shù)的克制也是碼農(nóng)的一個職業(yè)操守。 Docker出現(xiàn)后,容器技術(shù)在互聯(lián)網(wǎng)領(lǐng)域得到了空前的普及,無論是大公司還是屌絲創(chuàng)業(yè)公司的碼農(nóng)基本上都會在各種技術(shù)社區(qū)或者各種演講會議上了解到過相關(guān)技術(shù),我們作為一家屌絲創(chuàng)業(yè)公司也不例外,去年對Docker做了一番了解,并在年前測試了一些方案,今天在這里總結(jié)一下遇到...
摘要:的主要作用是自己根據(jù)基礎(chǔ)鏡像,重新定制鏡像,而不是直接從官方倉庫拿現(xiàn)成的使用。以接下來要構(gòu)建的環(huán)境來說明下,下面我將要搭建一個的開發(fā)環(huán)境,需要進(jìn)行配合。它的主要作用是持久化數(shù)據(jù),避免容器銷毀后內(nèi)部數(shù)據(jù)丟失暴露到宿主機(jī)的端口。 以前一直使用 Vagrant 作為自己的開發(fā)環(huán)境,并且在上家公司也推行大家采用 Vagrant 作為開發(fā)環(huán)境,保障公司使用的是同一套開發(fā)環(huán)境。隨著docker的流...
摘要:的主要作用是自己根據(jù)基礎(chǔ)鏡像,重新定制鏡像,而不是直接從官方倉庫拿現(xiàn)成的使用。以接下來要構(gòu)建的環(huán)境來說明下,下面我將要搭建一個的開發(fā)環(huán)境,需要進(jìn)行配合。它的主要作用是持久化數(shù)據(jù),避免容器銷毀后內(nèi)部數(shù)據(jù)丟失暴露到宿主機(jī)的端口。 以前一直使用 Vagrant 作為自己的開發(fā)環(huán)境,并且在上家公司也推行大家采用 Vagrant 作為開發(fā)環(huán)境,保障公司使用的是同一套開發(fā)環(huán)境。隨著docker的流...
閱讀 3618·2021-11-24 10:25
閱讀 2539·2021-11-24 09:38
閱讀 1230·2021-09-08 10:41
閱讀 2914·2021-09-01 10:42
閱讀 2586·2021-07-25 21:37
閱讀 1991·2019-08-30 15:56
閱讀 922·2019-08-30 15:55
閱讀 2759·2019-08-30 15:54