我們將以基於技術總監最新演講的出版物開始我們的博客
31月XNUMX日 會議
如果你有機會花一個小時
使用 Docker 持續交付
下 持續交付 我們了解 Git 儲存庫中的應用程式程式碼首先進入生產環境,然後最終進入存檔的事件鏈。 它看起來像這樣: Git → 建置 → 測試 → 發布 → 運行.
報告的大部分內容致力於建立階段(應用程式組裝),並簡要討論了發布和操作主題。 我們將討論問題和允許您解決問題的模式,這些模式的具體實現可能會有所不同。
為什麼這裡需要 Docker? 我們決定在這個開源工具的背景下討論持續交付實踐並不是沒有原因的。 儘管整個報告都致力於其使用,但在考慮應用程式程式碼推出的主要模式時,揭示了許多原因。
主要推出模式
因此,當我們推出應用程式的新版本時,我們肯定會面臨 停機問題,在生產伺服器切換期間產生。 從舊版應用程式到新版本應用程式的流量無法立即切換:首先,我們必須確保新版本不僅已成功下載,而且已「預熱」(即完全準備好服務請求)。
因此,在一段時間內,應用程式的兩個版本(舊版和新版)將同時運行。 這會自動導致 共享資源衝突:網路、檔案系統、IPC等。 使用 Docker,可以透過在單獨的容器中執行不同版本的應用程式來輕鬆解決此問題,從而在同一台主機(伺服器/虛擬機)內保證資源隔離。 當然,你可以在沒有絕緣的情況下使用一些技巧,但是如果有一個現成的方便的工具,那麼就有相反的原因 - 不要忽視它。
容器化在部署時還提供了許多其他好處。 任何應用程式都取決於 具體版本 (或版本範圍) 口譯員、模組/擴充的可用性等,以及它們的版本。 這不僅適用於直接可執行環境,也適用於整個環境,包括 系統軟體 及其版本(取決於所使用的 Linux 發行版)。 由於容器中不僅包含應用程式程式碼,還預先安裝了所需版本的系統和應用軟體,因此您可以忘記依賴關係的問題。
我們來總結一下 主要推出模式 新版本考慮了以下因素:
- 首先,舊版本的應用程式在第一個容器中運行。
- 然後,新版本將在第二個容器中推出並「預熱」。 值得注意的是,這個新版本本身可能不僅包含更新的應用程式程式碼,還包含其任何依賴項以及系統元件(例如,新版本的 OpenSSL 或整個發行版)。
- 當新版本完全準備好服務要求時,流量將從第一個容器切換到第二個容器。
- 舊版現在可以停止了。
這種在單獨的容器中部署不同版本的應用程式的方法提供了另一個便利 - 快速回滾 到舊版本(畢竟,將流量切換到所需的容器就足夠了)。
最後的第一個建議聽起來連隊長都挑不出毛病:「[使用 Docker 組織持續交付時] 使用 Docker [並了解它給了什麼]」 請記住,這並不是解決所有問題的靈丹妙藥,而是提供良好基礎的工具。
再現性
「再現性」是指操作應用程式時遇到的一系列普遍問題。 我們正在談論這樣的案例:
- 品質部門檢查的舞台腳本必須在生產中準確複製。
- 應用程式發佈在可以從不同儲存庫鏡像接收套件的伺服器上(隨著時間的推移,它們會更新,並且已安裝應用程式的版本也隨之更新)。
- “一切都適合我本地!” (......並且不允許開發人員投入生產。)
- 您需要檢查舊(存檔)版本中的某些內容。
- ...
它們的一般本質歸結為這樣一個事實:完全符合所使用的環境(以及缺乏人為因素)是必要的。 如何保證重現性? 製作 Docker 映像 基於 Git 的程式碼,然後將它們用於任何任務:在測試網站、生產中、程式設計師的本機電腦上...同時,盡量減少所執行的操作也很重要 後 組裝影像:越簡單,出現錯誤的可能性就越小。
基礎設施就是程式碼
如果基礎設施要求(伺服器軟體的可用性、版本等)沒有正式化和“編程”,那麼任何應用程式更新的推出都可能導致災難性的後果。 例如,在暫存階段,您已經切換到 PHP 7.0 並相應地重寫了程式碼 - 那麼它在生產中與一些舊 PHP (5.5) 的出現肯定會讓某人感到驚訝。 您可能不會忘記解釋器版本中的重大更改,但“細節決定成敗”:令人驚訝的可能是任何依賴項的微小更新。
解決這個問題的方法稱為 IaC(基礎設施即代碼,「基礎設施即代碼」) 並涉及將基礎設施需求與應用程式程式碼一起儲存。 使用它,開發人員和 DevOps 專家可以在同一個 Git 應用程式儲存庫上工作,但可以在其中的不同部分上工作。 根據此程式碼,在 Git 中建立了一個 Docker 映像,在其中部署應用程式時考慮了基礎架構的所有細節。 簡單來說,組裝鏡像的腳本(規則)應該與原始程式碼在同一個儲存庫中並合併在一起。
在多層應用程式架構的情況下 - 例如,有 nginx,它位於已在 Docker 容器內運行的應用程式前面 - 必須從 Git 中的程式碼為每一層建立 Docker 映像。 然後,第一個映像將包含一個具有解釋器和其他「緊密」依賴項的應用程序,第二個映像將包含上游 nginx。
Docker 映像,與 Git 通信
我們將從 Git 收集的所有 Docker 映像分為兩類:臨時的和發布的。 臨時影像 由 Git 中的分支名稱標記,可以被下一次提交覆蓋,並且僅用於預覽(不適用於生產)。 這是它們與發布版本的主要區別:您永遠不知道其中有哪個具體提交。
收集到臨時映像中是有意義的:主分支(您可以自動將其推出到單獨的網站以不斷查看主版本的當前版本)、具有版本的分支、特定創新的分支。
當臨時影像預覽到需要轉化為生產後,開發人員會打上一定的標籤。 按標籤自動收集 發布圖片 (其標籤對應於 Git 中的標籤)並已推出至暫存階段。 如果品質部門驗證成功,則進入生產。
DAPP
所描述的一切(推出、鏡像組裝、後續維護)都可以使用 Bash 腳本和其他「臨時」工具獨立實現。 但如果這樣做的話,那麼到了某個時候,實施就會導致極大的複雜性和較差的可控性。 理解這一點後,我們開始創建自己的專用工作流程實用程式來建立 CI/CD - DAPP.
它的原始碼是用Ruby寫的,開源並發佈在
13 年 2019 月 XNUMX 日更新: 目前是一個項目 DAPP 重新命名為
Kubernetes
另一個已經在專業環境中獲得廣泛認可的現成開源工具是 Kubernetes,一個Docker管理叢集。 它在運行基於 Docker 的專案中的使用主題超出了報告的範圍,因此演示僅限於概述一些有趣的功能。
對於部署,Kubernetes 提供:
- 就緒探針-檢查新版本應用程式的就緒情況(將流量切換到它);
- 捲動更新 - 容器叢集中的順序映像更新(關閉、更新、準備啟動、流量切換);
- 同步更新 - 使用不同的方法更新叢集中的映像:先更新一半容器,然後更新其餘容器;
- 金絲雀發布 - 在有限(少量)數量的容器上啟動新映像以監視異常情況。
由於持續交付不僅僅是一個新版本的發布,Kubernetes對於後續的基礎設施維護有很多能力:對所有容器的內建監控和日誌記錄、自動伸縮等。這一切都已經在工作,只是等待適當的時機。在您的流程中實施。
最終建議
- 使用 Docker。
- 建立滿足您所有需求的應用程式的 Docker 映像。
- 遵循「基礎設施就是程式碼」的原則。
- 將 Git 連結到 Docker。
- 規範推出順序。
- 使用現成的平台(Kubernetes 或其他)。
影片和幻燈片
演出影片(約一小時)
報告介紹:
聚苯乙烯
我們部落格上有關該主題的其他報告:
- «
werf - 我們在 Kubernetes 中的 CI / CD 工具(概述和視頻報告) » (Dmitry Stolyarov;27 年 2019 月 XNUMX 日,DevOpsConf); - «
資料庫和 Kubernetes » (Dmitry Stolyarov;8 年 2018 月 XNUMX 日,HighLoad++); - «
Kubernetes 和 GitLab 的 CI/CD 最佳實踐 » (Dmitry Stolyarov;7 年 2017 月 XNUMX 日,HighLoad++); - «
我們在小型項目中使用 Kubernetes 的經驗 » (德米特里·斯托利亞羅夫;6 年 2017 月 XNUMX 日,RootConf).
來源: www.habr.com