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