1. 程式人生 > >Docker 實戰案例解析,實現自己主動化資料庫遷移

Docker 實戰案例解析,實現自己主動化資料庫遷移

640?wx_fmt=jpeg

出品丨Docker公司(ID:docker-cn)

編譯丨小東

每週一、三、五晚6點10分  與您不見不散


說在前面


在 Phorest Salon Software 公司,我們是在 AWS 上執行我們的平臺。該平臺由 VPC 內的很多 AWS 資源(例項,資料庫)組成。

我們的大部分服務都執行在由亞馬遜 ECS 管理的 Docker 容器上。

&


遷移的挑戰


我們有三個專用環境:開發、分段構建和生產。每一個環境都有自己的專用 VPC,因此 VPC 中的資源不能直接從外部訪問,通常來說這是非常好的。

問題是我們有時須要改動某些元件的模式結構,比如:加入一個新的表或列。在 Java-ish 中,我們使用 Liquibase 來管理 DDL / DML 的更改。相同的,通常來說這是非常好的。可是我們要怎樣才幹使這些更改通過持續交付的方式應用到各個不同的環境中呢?


我們針對上述問題,提出了幾種解決方法:


1、在啟動時執行


您能夠讓您的元件執行此操作。

比如,您能夠將應用程式配置為在啟動時應用它。對於 Spring Boot 應用程式來說,這非常easy。您僅僅需將 liquibase jar 加入到環境變數並配置一些配置屬性就可以實現此目的。


這樣的方法對於在本地的開發或開發環境來說可能是非常好的,可是對於分段構建或生產呢?問題在於,您的資料庫遷移指令碼可能非常慢,執行它們可能須要幾分鐘、幾個小時甚至幾天的時間。


對於上述情況。使用 ECS 的效果就不太理想了。由於在那裡部署服務時。您定義了 ECS 將用於驗證元件的執行狀態。在執行資料庫遷移指令碼的情況下啟動它,會導致整個遷移過程被覺得是不健康的。並且 ECS 可能會在遷移過程中殺死您的容器。您能夠為 ECS 服務配置一個寬限期。但這可能非常難預測到它的值,由於每一個遷移都可能不同。


2、手動應用


還有一種選擇是 SSH 連線到與服務在同一個 VPC 中執行的EC2例項。並從那裡手動執行遷移指令碼(你可能知道這樣的做法有多糟糕)。


3、使用 docker 容器


還有一個選擇是建立一個專用的 docker 映象來執行遷移指令碼。我們選擇了這個選項:


定義 docker 映象:


640?wx_fmt=png


我們使用了一個開源的基礎映象,它為我們提供了一種執行 Liquibase 更改日誌的方法。我們所要做的就是定義一些環境變數並將 Liquibase 更改日誌複製過去。空變數是有益放進去的,以便大家在執行容器時記得替換掉它們。

640?</p><p>wx_fmt=png

我們將映象定義檔案與我們的程式碼庫一起儲存,因此在公佈時會對其進行版本號控制和標記。

有了這一點。我們更新了 Jenkins 的工作,作為工作流程的一部分來構建和推動新的 docker 映象。


下一步是更新 Jenkins 的工作來觸發使用我們的新映象遷移資料庫的 ECS 任務。為此,我們使用了自己的框架。但您能夠使用 Terraform 或K8s。或者您甚至能夠使用下面命令手動執行它(請不要在生產中執行!)

 

docker run your-image-tag liquibase update

 

640?wx_fmt=png

使用新步驟構建管道

640?wx_fmt=png


這樣的方法的優點


由於我們不在容器啟動時執行遷移,所以我們不再有與長時間執行的遷移相關的問題,從而導致 ECS 執行狀況檢查失敗。

但優點是,我們的遷移如今已經與我們的部署分離了(這是一篇非常好的文章,解釋了從應用程式部署中分離資料庫遷移的優點)。


使用這樣的新方法,我們必須確保我們的遷移始終與當前在生產中執行的程式碼相容。

它須要一些額外的工作。但如今意味著我們能夠毫不費力地回滾我們的版本號。

 

解決問題可能還有很多其它(或許更好)的方法。可是這樣的方法對我們更有效。假設你對這個話題有不論什麼想法或想法能夠在文尾處留言與我們探討。

640?wx_fmt=png


點選下列標題。閱讀很多其它乾貨



假設本文對你有幫助,歡迎分享到朋友圈!

獲取很多其它Docker有用技巧,掃描下圖二維碼。

    640?</p><p>wx_fmt=png