我們使用容器的方式部署資料庫元件,特别是企業有大量的項目開發業務的,部署的開發、測試資料庫元件較多時。經常會遇到以下問題:
- 業務需要使用資料庫,但部署完資料庫後,需要在資料庫中執行建立schema的操作或者一些初始化資料的建立。
- 開發測試多套部署環境,需要多次重複1的步驟。
- 項目比較多,時間久了項目需要的資料庫Schema不清楚。
- 項目傳遞時資料庫Schema管理混亂。
現在如果是使用Go等語言研發的業務系統,都具備了ORM層自動初始化和更新Schema的能力,如果是這樣本文對你無用。但目前大多數其他開發語言的業務都不具備這種能力。
如果我們把資料庫也作為一個業務中的一個服務子產品來管理的話,我們希望服務啟動後即可直接完成Schema的初始化,直接提供資料服務能力。
那麼在Rainbond中如何達成這樣的效果呢?
Schema初始化在傳統模式中一般有兩種方案:
- 在資料庫啟動後手動導入;人工通過用戶端操作,沒有自動化程度可言;
- 在業務服務啟動時連接配接資料庫進行初始化,依賴業務服務端的能力。
可以看出,這兩種方式都存在各自的弊端,那麼有沒有方式能夠讓資料庫啟動時自動初始化指定的資料呢?答案是 有!
我們以MySQL為例, 官方對于 Docker 有着良好的支援,首先來看 Dockerhub上 Mysql官方鏡像 的一段描述:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLi0zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwkzX39GZhh2csATMflHLwEzX4xSZz91ZsADMx8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PnVGcq5iN2QDM1EWMwQDZmBTNyQjYygDZ5E2NjVmY4QGMmRGOi9CXzAzLcZDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL4M3Lc9CX6MHc0RHaiojIsJye.jpeg)
在資料庫容器首次啟動時,将建立一個指定名稱的新資料庫,并使用提供的環境變量對其進行初始化。 此外,它将執行在 /docker-entrypoint-initdb.d 中找到的擴充名為 .sh,.sql 和 .sql.gz 的檔案。 檔案将按字母順序執行。 預設情況下,SQL檔案将導入到MYSQL_DATABASE 變量指定的資料庫中。是以我們隻需要在Mysql鏡像工作機制的基礎上維護好資料庫初始化所需要的SQL即可。上文我們說到把資料庫也作為一個獨立的服務子產品,我們也可以通過代碼把Sql等腳步管理起來,劃分版本分支。
Rainbond 支援多種元件建立方式,在這裡我們采用 從源碼建立元件 的方式,編寫 Dockerfile 并上傳至支援 Git/Svn 協定的用戶端,即可在平台直接進行建構;這種方式 透明、可複用、并且能夠進行自動化建構。
目錄結構
./
└── Dockerfile
└── config
├── my.cnf
├── conf.d
├── docker.cnf
└── sql
├── init_database
└── README.md
Dockerfile檔案
#基礎鏡像
FROM mysql:latest
MAINTAINER Aaron#把sql檔案拷貝到/docker-entrypoint-initdb.d/目錄下,以便啟動時自動執行這個sql
COPY ./sql/*.sql /docker-entrypoint-initdb.d
#拷貝mysql配置檔案
COPY ./config/ /etc/mysql/
#Mysql密碼
ENV MYSQL_ROOT_PASSWORD rainbond
#資料持久化目錄
VOLUME [ "/var/lib/mysql" ]
#端口
EXPOSE 3306
項目位址:https://github.com/Aaron-23/Initialize-db
使用該項目在平台進行建構,Rainbond 将會自動檢測 Dockerfile 中定義的環境變量,存儲,端口等資訊,對這些配置項進行自動化配置,在 Dockerfile 建構完畢後自動啟動資料庫。
需要注意的是 MySQL 屬于有狀态服務,是以在建構前需将元件類型修改為有狀态單執行個體,關于元件狀态請參考 元件部署類型。
啟動完成,進入運作中狀态
通過 Web終端 進入資料庫檢視相關資料已經完成初始化