Yelp是如何使用Docker的?

jopen 9年前發布 | 21K 次閱讀 Docker

本文主要講述了Docker在Yelp真實生產環境下使用的一些最佳實踐和一些部署經驗。

每天都有成千上萬的人在使用Yelp的SeatMe來完成餐廳預訂服務。這篇博客將會深入地講解Yelp是如何使用Docker來開發并部署 SeatMe系統的。Docker是一個非常強大的生產環境助推器,它已經大大簡化了我們的部署方式。首先,我要簡單介紹一下Yelp的SeatMe系統 的背景,以及它的開發部署方式。

Yelp的SeatMe是什么

餐廳會通過我們的網站或者iPad應用來接受并管理客戶預定信息。我們會保證客戶所有的終端信息實時同步,同時當客戶在沒有聯網的情況下我們也支持離線更改。

Yelp是如何使用Docker的?

我們的技術棧:

  • 客戶端的JavaScript,我們在單頁應用中使用到了Backbone
  • Python是我們后端的語言,Django是我們的Web框架。
  • 我們使用CeleryRabbitMQ來處理我們的異步任務。
  • Postgres數據庫,使用觸發器的數據驗證和更新通知,以支持我們的同步協議和長輪詢引擎。
  • 我們把整個平臺都放到了AWS上,并使用Chef作為我們的主要工具來配置服務器,管理部署和組織我們的測試、灰度、線上環境。
  • </ul>

    在生產環境使用Docker

    一年前,我們使用Docker容器開啟了一種新的方式來讓我們的測試環境、灰度環境、生產環境更加地一致,同時讓我們的部署流程更加簡化。

    在我們使用容器之前,部署一個Web應用的邏輯是被放在Chef的配置文件里。部署流程大概像這樣:

    • 設置目錄權限。
    • 安裝Python的依賴組件和依賴包。
    • 下載指定標簽的Git分支。
    • 保留最近的幾個版本來確保我們可以快速回滾。
    • </ul>
      這些Chef的配置文件對于新工程師來說簡直是噩夢,因為它們使用一種完全不同的語言(Ruby)的一個非常復雜的框架。

      通過使用Docker,我們能夠簡化Chef管理的部署部分,現在的流程如下:

      • 拉取一個指定的Docker鏡像到服務器。
      • 通過健康檢查來停止服務器。
      • 停止存在的容器。
      • 給新的鏡像打一個易讀的標簽。
      • 啟動這個鏡像(以及所有它的文件系統的映射等等),并使用一個新的名字來命名這個容器(www)。
      • </ul>
        使用Docker的好處:

        • 通過Docker來增強開發者對環境的控制。
        • 消除服務器環境的不統一。
        • 減少了Chef的配置工作量。
        • 集中了部署鏡像庫而且永遠可以對應到某個具體的Git提交。
        • 我們持續集成了Docker鏡像,所以每一次Code Review通過后總會生成一個可部署的鏡像。
        • 現在開發者可以修改系統級別的包,而不需要運維團隊來做這件事了。
        • </ul>
          經過兩個月的開發和測試,我們在2014年10月初期終于把Docker用到了生產環境,并且運行穩定。

          向Docker遷移過程中需要注意的事情

          Docker是一個相對比較新的技術,所以你使用過程中難免會遇到一些坑。我在這里總結下我們的經驗。

          • 務必認真測試你的文件系統。

            這里有一些對Docker可用的文件系統,AUFS被認為是上一代的文件系統,Device Mapper被認為是目前這一代的文件系統。我們發現盡管測試是在本地文件系統,但使用Device Mapper文件系統的時候可能會出現崩潰,同時整個系統也會掛。當然這很可能是內核和發行版的不同所造成的,我們發現AUFS在我們的生產環境中非常地 穩定。務必充分地測試你的文件系統尤其是通過在測試環境中不斷地重復部署的方式。
          • 多次構建Docker鏡像以及鏡像的大小。

            由于Docker的分層文件系統,所以當你改變某些層的時候,就需要重新構建系統。而相對于你的寶貴時間來說,這樣的重復等待工作簡直令人郁悶。為了減少構建層以及重構時間,你可以將某些命令整合成單個命令。考慮一下緩存成功構建后的Docker鏡像來減少構建的次數吧。
          • 務必使用明確的命令來構建和啟動容器或者編寫Dockerfile。

            我們使用模板來做這件事情。一旦有一些參數要傳給docker run,你想要這些參數文檔化。當你使用新的Docker版本的時候,你不必去改變這個服務器上的配置文件或者shell的alias,僅僅是代碼的改變。
          • 鏡像文件和容器實例不會自動地回收。

            這已經被談論了很長時間了,我們發現當我們所有的服務器硬盤神秘變滿地時候,我們部署過的每一個鏡像依然保存在服務器上直到我們刪除它。我們已經使用一些簡單的管理腳本來減少磁盤的占用了,直到我們發現了像docker-custodian一樣的工具才真正解決了這個問題。
          • 考慮把你的鏡像分層到多個Dockerfile來加速構建。

            我們前面討論過鏡像緩存,我們已經完成了一個多層Docker鏡像策略,這個策略是讓鏡像之間可以互相繼承。

            一些基礎鏡像,他們包含了一些系統包,構建的過程非常慢,但是這樣的鏡像也很少改變。

            生產環境中的Web鏡像繼承自這些基礎鏡像,同時也包含了一系列的編譯好的Python包和某一時刻的源代碼快照。這樣會快速地構建除非遇到requirements.txt文件的變動,這個變動會觸發virtualenv的重新構建。

            開發者的Web鏡像繼承自生產環境的鏡像,并且增加了一些跑selenium測試(Xvcon、google-chrome)的工具和一些開發者的工具。然后開發者利用文件系統將他們的新的代碼映射到容器當中,并且在生產環境Web鏡像中覆蓋快照。
          • 遇到緊急情況,你依然可以進入容器內debug你的代碼。

            最初當你在容器內跑你的代碼的時候,它就像在你跟你的代碼之間放了一個隔離層,并且這個隔離層阻止了大量的正常debugging技術。當它不被認為是最佳實踐的生產環境系統的時候,當在測試環境(尤其是在開發環境)的時候,你很可能打開一個終端執行docker exec -ti <containerid> bash然后用平常的命令比如strace來檢查你的代碼或系統是否正常。
          • 你需要一個日志管理的策略。

            這聽起來是一個再普通不過的話題,但是日志管理對于Docker來說是非常棘手的問題。你可以用一些簡單的技術去映射宿主機的文件系統到容器中簡單地把日志保存在宿主機上,但是當你在這個宿主機上起更多的容器實例的時候這個方法很快就會失敗。

            最后,經過大量的實驗,我們已經取得巨大的成功,并將應用程序的日志通過UDP直接打到宿主機的syslog上。在Docker 1.7版本之前,做這一件事情需要一個技術來找到syslog宿主機的正確IP地址,后來我們通過傳遞環境變量解決了這個問題。
          • </ul>

            關于未來

            總的來說,容器化已經取得了巨大成功。比如說,當Shellshock漏洞被公布的時候,我們的事故響應僅僅是一次容 器的構建和一次Chef的執行。盡管發展步履維艱,Docker已經是一個巨大的改變,我們非常樂意繼續研究它。有了一個穩定的Web基礎構件后,我們已 經找到更新更有效率的方法來測試、部署和管理我們的基礎構件,同時也找到了更快的開發迭代的方法。我們希望能在今后的文章中分享這些方法,敬請關注吧!

            原文鏈接:Docker in the Real World at Yelp(翻譯:吳飛群 校對:李穎杰)

            =====================================================
            譯者介紹
            吳飛群,錢方科技運維工程師,Docker愛好者。

            來自: http://dockone.io/article/626

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!